diff options
author | Alexander Motin <mav@FreeBSD.org> | 2014-11-25 17:53:35 +0000 |
---|---|---|
committer | Alexander Motin <mav@FreeBSD.org> | 2014-11-25 17:53:35 +0000 |
commit | f7241cceb02f56add7f4a504021069acb81f4bf6 (patch) | |
tree | a3a596368ccfcff50a172e691d7ebad9c8822de3 /sys/cam/ctl/ctl_backend_block.c | |
parent | 82e843b93b2ce12c8cf5c1fd5fb88c1d37a54134 (diff) | |
download | src-f7241cceb02f56add7f4a504021069acb81f4bf6.tar.gz src-f7241cceb02f56add7f4a504021069acb81f4bf6.zip |
Coalesce last data move and command status for read commands.
Make CTL core and block backend set success status before initiating last
data move for read commands. Make CAM target and iSCSI frontends detect
such condition and send command status together with data. New I/O flag
allows to skip duplicate status sending on later fe_done() call.
For Fibre Channel this change saves one of three interrupts per read command,
increasing performance from 126K to 160K IOPS. For iSCSI this change saves
one of three PDUs per read command, increasing performance from 1M to 1.2M
IOPS.
MFC after: 1 month
Sponsored by: iXsystems, Inc.
Notes
Notes:
svn path=/head/; revision=275058
Diffstat (limited to 'sys/cam/ctl/ctl_backend_block.c')
-rw-r--r-- | sys/cam/ctl/ctl_backend_block.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c index ecaecbdff315..a90245a26e4b 100644 --- a/sys/cam/ctl/ctl_backend_block.c +++ b/sys/cam/ctl/ctl_backend_block.c @@ -381,8 +381,9 @@ ctl_be_block_move_done(union ctl_io *io) * We set status at this point for read commands, and write * commands with errors. */ - if ((io->io_hdr.port_status == 0) && - ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0) && + if (io->io_hdr.flags & CTL_FLAG_ABORT) { + ; + } else if ((io->io_hdr.port_status == 0) && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) { lbalen = ARGS(beio->io); if (lbalen->flags & CTL_LLF_READ) { @@ -405,10 +406,9 @@ ctl_be_block_move_done(union ctl_io *io) else ctl_set_success(&io->scsiio); } - } - else if ((io->io_hdr.port_status != 0) - && ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0) - && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) { + } else if ((io->io_hdr.port_status != 0) && + ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE || + (io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)) { /* * For hardware error sense keys, the sense key * specific value is defined to be a retry count, @@ -532,6 +532,9 @@ ctl_be_block_biodone(struct bio *bio) ctl_set_success(&io->scsiio); ctl_complete_beio(beio); } else { + if ((ARGS(io)->flags & CTL_LLF_READ) && + beio->beio_cont == NULL) + ctl_set_success(&io->scsiio); #ifdef CTL_TIME_IO getbintime(&io->io_hdr.dma_start_bt); #endif @@ -739,6 +742,9 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun, ctl_set_success(&io->scsiio); ctl_complete_beio(beio); } else { + if ((ARGS(io)->flags & CTL_LLF_READ) && + beio->beio_cont == NULL) + ctl_set_success(&io->scsiio); #ifdef CTL_TIME_IO getbintime(&io->io_hdr.dma_start_bt); #endif @@ -828,6 +834,9 @@ ctl_be_block_dispatch_zvol(struct ctl_be_block_lun *be_lun, ctl_set_success(&io->scsiio); ctl_complete_beio(beio); } else { + if ((ARGS(io)->flags & CTL_LLF_READ) && + beio->beio_cont == NULL) + ctl_set_success(&io->scsiio); #ifdef CTL_TIME_IO getbintime(&io->io_hdr.dma_start_bt); #endif |