Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Feb 2015 10:28:45 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r278619 - head/sys/cam/ctl
Message-ID:  <201502121028.t1CASjCv098432@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Thu Feb 12 10:28:45 2015
New Revision: 278619
URL: https://svnweb.freebsd.org/changeset/base/278619

Log:
  Make WRITE SAME commands respect physical block size.
  
  This change by 2-3 times improves performance of misaligned WRITE SAME
  commands by avoiding unneeded read-modify-write cycles inside ZFS.
  
  MFC after:	1 week

Modified:
  head/sys/cam/ctl/ctl_backend_block.c

Modified: head/sys/cam/ctl/ctl_backend_block.c
==============================================================================
--- head/sys/cam/ctl/ctl_backend_block.c	Thu Feb 12 07:22:46 2015	(r278618)
+++ head/sys/cam/ctl/ctl_backend_block.c	Thu Feb 12 10:28:45 2015	(r278619)
@@ -1187,7 +1187,7 @@ ctl_be_block_cw_dispatch_ws(struct ctl_b
 	struct ctl_be_block_io *beio;
 	struct ctl_be_block_softc *softc;
 	struct ctl_lba_len_flags *lbalen;
-	uint64_t len_left, lba;
+	uint64_t len_left, lba, pb, pbo, adj;
 	int i, seglen;
 	uint8_t *buf, *end;
 
@@ -1241,6 +1241,8 @@ ctl_be_block_cw_dispatch_ws(struct ctl_b
 	DPRINTF("WRITE SAME at LBA %jx len %u\n",
 	       (uintmax_t)lbalen->lba, lbalen->len);
 
+	pb = (uint64_t)be_lun->blocksize << be_lun->pblockexp;
+	pbo = pb - (uint64_t)be_lun->blocksize * be_lun->pblockoff;
 	len_left = (uint64_t)lbalen->len * be_lun->blocksize;
 	for (i = 0, lba = 0; i < CTLBLK_MAX_SEGS && len_left > 0; i++) {
 
@@ -1248,7 +1250,15 @@ ctl_be_block_cw_dispatch_ws(struct ctl_b
 		 * Setup the S/G entry for this chunk.
 		 */
 		seglen = MIN(CTLBLK_MAX_SEG, len_left);
-		seglen -= seglen % be_lun->blocksize;
+		if (pb > be_lun->blocksize) {
+			adj = ((lbalen->lba + lba) * be_lun->blocksize +
+			    seglen - pbo) % pb;
+			if (seglen > adj)
+				seglen -= adj;
+			else
+				seglen -= seglen % be_lun->blocksize;
+		} else
+			seglen -= seglen % be_lun->blocksize;
 		beio->sg_segs[i].len = seglen;
 		beio->sg_segs[i].addr = uma_zalloc(be_lun->lun_zone, M_WAITOK);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201502121028.t1CASjCv098432>