summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-10-05 10:41:08 +0000
committermav <mav@FreeBSD.org>2015-10-05 10:41:08 +0000
commite6730078eb600c022e751c91cc886aa4a5b09e4f (patch)
treec80b3d940c419abcf84ccebef20900dd0969f1ff
parentcfbb7640a74a9b74f45fb2fcd3bc27b11f1476e4 (diff)
downloadFreeBSD-src-e6730078eb600c022e751c91cc886aa4a5b09e4f.zip
FreeBSD-src-e6730078eb600c022e751c91cc886aa4a5b09e4f.tar.gz
MFC r287967: Relax serseq option operation for reads.
Previously, with serseq enabled, next command was unblocked only after previous completed. With this change, for read operations, next command is unblocked as soon as last media read completed. This is important for frontends that actually wait for data move completion (like camtgt), or when data are moved through the HA link, or especially when both.
-rw-r--r--sys/cam/ctl/ctl.c19
-rw-r--r--sys/cam/ctl/ctl.h1
-rw-r--r--sys/cam/ctl/ctl_backend_block.c12
-rw-r--r--sys/cam/ctl/ctl_io.h3
4 files changed, 31 insertions, 4 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index b2036e4..567cfba 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -10594,6 +10594,8 @@ ctl_extent_check(union ctl_io *io1, union ctl_io *io2, bool seq)
if (ctl_get_lba_len(io1, &lba1, &len1) != 0)
return (CTL_ACTION_ERROR);
+ if (io1->io_hdr.flags & CTL_FLAG_SERSEQ_DONE)
+ seq = FALSE;
return (ctl_extent_check_lba(lba1, len1, lba2, len2, seq));
}
@@ -10603,6 +10605,8 @@ ctl_extent_check_seq(union ctl_io *io1, union ctl_io *io2)
uint64_t lba1, lba2;
uint64_t len1, len2;
+ if (io1->io_hdr.flags & CTL_FLAG_SERSEQ_DONE)
+ return (CTL_ACTION_PASS);
if (ctl_get_lba_len(io1, &lba1, &len1) != 0)
return (CTL_ACTION_ERROR);
if (ctl_get_lba_len(io2, &lba2, &len2) != 0)
@@ -13220,6 +13224,21 @@ ctl_done_timer_wakeup(void *arg)
#endif /* CTL_IO_DELAY */
void
+ctl_serseq_done(union ctl_io *io)
+{
+ struct ctl_lun *lun;
+
+ lun = (struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+ if (lun->be_lun == NULL ||
+ lun->be_lun->serseq == CTL_LUN_SERSEQ_OFF)
+ return;
+ mtx_lock(&lun->lun_lock);
+ io->io_hdr.flags |= CTL_FLAG_SERSEQ_DONE;
+ ctl_check_blocked(lun);
+ mtx_unlock(&lun->lun_lock);
+}
+
+void
ctl_done(union ctl_io *io)
{
diff --git a/sys/cam/ctl/ctl.h b/sys/cam/ctl/ctl.h
index 5d8a182..c024336 100644
--- a/sys/cam/ctl/ctl.h
+++ b/sys/cam/ctl/ctl.h
@@ -172,6 +172,7 @@ int ctl_sap_log_sense_handler(struct ctl_scsiio *ctsio,
int pc);
int ctl_config_move_done(union ctl_io *io);
void ctl_datamove(union ctl_io *io);
+void ctl_serseq_done(union ctl_io *io);
void ctl_done(union ctl_io *io);
void ctl_data_submit_done(union ctl_io *io);
void ctl_config_read_done(union ctl_io *io);
diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c
index 140bdc8..4edf039 100644
--- a/sys/cam/ctl/ctl_backend_block.c
+++ b/sys/cam/ctl/ctl_backend_block.c
@@ -565,8 +565,10 @@ ctl_be_block_biodone(struct bio *bio)
ctl_complete_beio(beio);
} else {
if ((ARGS(io)->flags & CTL_LLF_READ) &&
- beio->beio_cont == NULL)
+ beio->beio_cont == NULL) {
ctl_set_success(&io->scsiio);
+ ctl_serseq_done(io);
+ }
#ifdef CTL_TIME_IO
getbintime(&io->io_hdr.dma_start_bt);
#endif
@@ -785,8 +787,10 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
ctl_complete_beio(beio);
} else {
if ((ARGS(io)->flags & CTL_LLF_READ) &&
- beio->beio_cont == NULL)
+ beio->beio_cont == NULL) {
ctl_set_success(&io->scsiio);
+ ctl_serseq_done(io);
+ }
#ifdef CTL_TIME_IO
getbintime(&io->io_hdr.dma_start_bt);
#endif
@@ -954,8 +958,10 @@ ctl_be_block_dispatch_zvol(struct ctl_be_block_lun *be_lun,
ctl_complete_beio(beio);
} else {
if ((ARGS(io)->flags & CTL_LLF_READ) &&
- beio->beio_cont == NULL)
+ beio->beio_cont == NULL) {
ctl_set_success(&io->scsiio);
+ ctl_serseq_done(io);
+ }
#ifdef CTL_TIME_IO
getbintime(&io->io_hdr.dma_start_bt);
#endif
diff --git a/sys/cam/ctl/ctl_io.h b/sys/cam/ctl/ctl_io.h
index 2fb8900..d8823fb 100644
--- a/sys/cam/ctl/ctl_io.h
+++ b/sys/cam/ctl/ctl_io.h
@@ -115,7 +115,8 @@ typedef enum {
CTL_FLAG_FAILOVER = 0x04000000, /* Killed by a failover */
CTL_FLAG_IO_ACTIVE = 0x08000000, /* I/O active on this SC */
- CTL_FLAG_STATUS_SENT = 0x10000000 /* Status sent by datamove */
+ CTL_FLAG_STATUS_SENT = 0x10000000, /* Status sent by datamove */
+ CTL_FLAG_SERSEQ_DONE = 0x20000000 /* All storage I/O started */
} ctl_io_flags;
OpenPOWER on IntegriCloud