diff options
author | mav <mav@FreeBSD.org> | 2015-02-12 10:28:45 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2015-02-12 10:28:45 +0000 |
commit | 2ffc27bf265328f744335d81c687c48bccdb3265 (patch) | |
tree | 10d208d48e67bd753356e18bd89289f5dbaaa3b7 | |
parent | 05431ee9d34a7cb642760e4c287d006fdf65e8ab (diff) | |
download | FreeBSD-src-2ffc27bf265328f744335d81c687c48bccdb3265.zip FreeBSD-src-2ffc27bf265328f744335d81c687c48bccdb3265.tar.gz |
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
-rw-r--r-- | sys/cam/ctl/ctl_backend_block.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c index a5e45024..6b5f703 100644 --- a/sys/cam/ctl/ctl_backend_block.c +++ b/sys/cam/ctl/ctl_backend_block.c @@ -1187,7 +1187,7 @@ ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun, 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_be_block_lun *be_lun, 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_be_block_lun *be_lun, * 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); |