These do the same as nvme_mpath_{start,end}_request() Signed-off-by: John Garry --- drivers/scsi/sd.c | 55 +++++++++++++++++++++++++++++++++++ include/scsi/scsi_cmnd.h | 5 ++++ include/scsi/scsi_multipath.h | 1 + 3 files changed, 61 insertions(+) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 222e28ed44e9b..845d392456549 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1546,6 +1546,57 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt) mempool_free(rq->special_vec.bv_page, sd_page_pool); } +#ifdef CONFIG_SCSI_MULTIPATH +static void sd_mpath_start_command(struct scsi_cmnd *scmd) +{ + struct request *req = scsi_cmd_to_rq(scmd); + struct scsi_disk *sdkp = scsi_disk(req->q->disk); + struct sd_mpath_disk *sd_mpath_disk = sdkp->sd_mpath_disk; + struct mpath_disk *mpath_disk = sd_mpath_disk->mpath_disk; + struct scsi_device *sdev = scmd->device; + struct mpath_head *mpath_head = mpath_disk->mpath_head; + struct scsi_mpath_head *scsi_mpath_head = mpath_head->drvdata; + struct gendisk *disk = mpath_disk->disk; + + if (mpath_qd_iopolicy(&scsi_mpath_head->iopolicy) && + !(scmd->flags & SCMD_MPATH_CNT_ACTIVE)) { + struct scsi_mpath_device *scsi_mpath_dev = sdev->scsi_mpath_dev; + + atomic_inc(&scsi_mpath_dev->nr_active); + scmd->flags |= SCMD_MPATH_CNT_ACTIVE; + } + + if (!blk_queue_io_stat(disk->queue) || blk_rq_is_passthrough(req) || + (scmd->flags & SCMD_MPATH_IO_STATS)) + return; + + scmd->flags |= SCMD_MPATH_IO_STATS; + scmd->start_time = bdev_start_io_acct(disk->part0, req_op(req), + jiffies); +} + +static void sd_mpath_end_command(struct scsi_cmnd *scmd) +{ + struct request *req = scsi_cmd_to_rq(scmd); + struct scsi_disk *sdkp = scsi_disk(req->q->disk); + struct sd_mpath_disk *sd_mpath_disk = sdkp->sd_mpath_disk; + struct mpath_disk *mpath_disk = sd_mpath_disk->mpath_disk; + struct scsi_device *sdev = scmd->device; + + if (scmd->flags & SCMD_MPATH_CNT_ACTIVE) { + struct scsi_mpath_device *scsi_mpath_dev = sdev->scsi_mpath_dev; + + atomic_dec_if_positive(&scsi_mpath_dev->nr_active); + } + + if (!(scmd->flags & SCMD_MPATH_IO_STATS)) + return; + bdev_end_io_acct(mpath_disk->disk->part0, req_op(req), + blk_rq_bytes(req) >> SECTOR_SHIFT, + scmd->start_time); +} +#endif + static bool sd_need_revalidate(struct gendisk *disk, struct scsi_disk *sdkp) { if (sdkp->device->removable || sdkp->write_prot) { @@ -4468,6 +4519,10 @@ static struct scsi_driver sd_template = { .resume = sd_resume, .init_command = sd_init_command, .uninit_command = sd_uninit_command, + #ifdef CONFIG_SCSI_MULTIPATH + .mpath_start_cmd = sd_mpath_start_command, + .mpath_end_cmd = sd_mpath_end_command, + #endif .done = sd_done, .eh_action = sd_eh_action, .eh_reset = sd_eh_reset, diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 8ecfb94049db5..c6571a36e577b 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -60,6 +60,8 @@ struct scsi_pointer { #define SCMD_FAIL_IF_RECOVERING (1 << 4) /* flags preserved across unprep / reprep */ #define SCMD_PRESERVED_FLAGS (SCMD_INITIALIZED | SCMD_FAIL_IF_RECOVERING) +#define SCMD_MPATH_IO_STATS (1 << 5) +#define SCMD_MPATH_CNT_ACTIVE (1 << 6) /* for scmd->state */ #define SCMD_STATE_COMPLETE 0 @@ -139,6 +141,9 @@ struct scsi_cmnd { * to release this memory. (The memory * obtained by scsi_malloc is guaranteed * to be at an address < 16Mb). */ + #ifdef CONFIG_SCSI_MULTIPATH + unsigned long start_time; + #endif int result; /* Status code from lower level driver */ }; diff --git a/include/scsi/scsi_multipath.h b/include/scsi/scsi_multipath.h index cb63c6536b854..2011447f482d6 100644 --- a/include/scsi/scsi_multipath.h +++ b/include/scsi/scsi_multipath.h @@ -36,6 +36,7 @@ struct scsi_mpath_device { struct mpath_device mpath_device; struct scsi_device *sdev; int index; + atomic_t nr_active; struct scsi_mpath_head *scsi_mpath_head; char device_id_str[SCSI_MPATH_DEVICE_ID_LEN]; -- 2.43.5