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);
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to