[PATCH] ufs: core: Disable queue depth tracking support
Bart Van Assche <[email protected]>
| Newsgroups | gmane.linux.scsi |
|---|---|
| Message-ID | <[email protected]> |
Disable queue depth tracking support because:
- UFS devices shouldn't need queue tracking support. If the host sends
less than or equal to bQueueDepth commands to the UFS device, no TASK
SET FULL condition should be reported. If a TASK SET FULL condition
is reported anyway, the host->host_blocked variable will be set and
the SCSI command will be requeued. Submission of the SCSI command
will be retried after another SCSI command has completed.
- The queue depth tracking code is not thread-safe. With MCQ enabled,
scsi_track_queue_full() may be called from multiple CPU cores
concurrently. This is not safe because individual
scsi_track_queue_full() calls are not serialized.
- scsi_track_queue_full() is called from interrupt context but not all
code called by scsi_track_queue_full() is IRQ-safe. Here is an
example of a call chain that may cause interrupts to be enabled,
something that is not allowed from interrupt context:
ufshcd_mcq_poll_cqe_lock()
ufshcd_compl_one_cqe()
scsi_done()
blk_mq_complete_request()
scsi_complete()
scsi_decide_disposition()
scsi_handle_queue_full()
scsi_track_queue_full()
scsi_change_queue_depth()
blk_set_queue_depth()
rq_qos_queue_depth_changed()
ioc_rqos_queue_depth_changed()
spin_lock_irq()
spin_unlock_irq() <- enables interrupts
Signed-off-by: Bart Van Assche <[email protected]>
---
drivers/infiniband/ulp/srp/ib_srp.c | 4 ++++
drivers/ufs/core/ufshcd.c | 16 ----------------
2 files changed, 4 insertions(+), 16 deletions(-)
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index acbd787de265..19a6400d1ec4 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1044,6 +1044,10 @@ static void srp_remove_target(struct srp_target_port *target)
WARN_ON_ONCE(target->state != SRP_TARGET_REMOVED);
srp_del_scsi_host_attr(target->scsi_host);
+ /*
+ * The srp_remove_host() call decrements the rport reference count.
+ * Keep the rport as long as its needed.
+ */
srp_rport_get(target->rport);
srp_remove_host(target->scsi_host);
scsi_remove_host(target->scsi_host);
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 67745d2796d0..59212a3a46de 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -5602,20 +5602,6 @@ static int ufshcd_sdev_init(struct scsi_device *sdev)
return 0;
}
-/**
- * ufshcd_change_queue_depth - change queue depth
- * @sdev: pointer to SCSI device
- * @depth: required depth to set
- *
- * Change queue depth and make sure the max. limits are not crossed.
- *
- * Return: new queue depth.
- */
-static int ufshcd_change_queue_depth(struct scsi_device *sdev, int depth)
-{
- return scsi_change_queue_depth(sdev, min(depth, sdev->host->can_queue));
-}
-
/**
* ufshcd_sdev_configure - adjust SCSI device configurations
* @sdev: pointer to SCSI device
@@ -9662,7 +9648,6 @@ static const struct scsi_host_template ufshcd_driver_template = {
.sdev_init = ufshcd_sdev_init,
.sdev_configure = ufshcd_sdev_configure,
.sdev_destroy = ufshcd_sdev_destroy,
- .change_queue_depth = ufshcd_change_queue_depth,
.eh_abort_handler = ufshcd_abort,
.eh_device_reset_handler = ufshcd_eh_device_reset_handler,
.eh_host_reset_handler = ufshcd_eh_host_reset_handler,
@@ -9673,7 +9658,6 @@ static const struct scsi_host_template ufshcd_driver_template = {
.max_sectors = SZ_1M / SECTOR_SIZE,
.max_host_blocked = 1,
.host_tagset = true,
- .track_queue_depth = 1,
.skip_settle_delay = 1,
.sdev_groups = ufshcd_driver_groups,
};