Home Home > GIT Browse > SLE12-SP3
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2019-01-11 15:12:56 +0100
committerHannes Reinecke <hare@suse.de>2019-01-11 15:13:09 +0100
commit086a2ce1cfb67bb8870bbf97014fa73a08487112 (patch)
tree72a49d3d62b9b1f25b06af96e8189b2a54d12523
parent4595c2b981df354dcc89cc23f668e38b5064e679 (diff)
scsi: Split scsi_internal_device_block() (bsc#1119877).
-rw-r--r--patches.fixes/scsi-Split-scsi_internal_device_block.patch173
-rw-r--r--series.conf1
2 files changed, 174 insertions, 0 deletions
diff --git a/patches.fixes/scsi-Split-scsi_internal_device_block.patch b/patches.fixes/scsi-Split-scsi_internal_device_block.patch
new file mode 100644
index 0000000000..2195dc6d03
--- /dev/null
+++ b/patches.fixes/scsi-Split-scsi_internal_device_block.patch
@@ -0,0 +1,173 @@
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Fri, 2 Jun 2017 14:21:53 -0700
+Subject: [PATCH] scsi: Split scsi_internal_device_block()
+Git-commit: 551eb598e5ea52996eb821f43740496a78a97b68
+Patch-mainline: v4.13-rc1
+References: bsc#1119877
+
+Instead of passing a "wait" argument to scsi_internal_device_block(),
+split this function into a function that waits and a function that
+doesn't wait. This will make it easier to serialize SCSI device state
+changes through a mutex.
+
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Cc: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Hannes Reinecke <hare@suse.com>
+---
+ drivers/scsi/mpt3sas/mpt3sas_scsih.c | 4 +-
+ drivers/scsi/scsi_lib.c | 73 +++++++++++++++++++++++-------------
+ include/scsi/scsi_device.h | 2 +-
+ 3 files changed, 50 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+index a5d872664257..c63bc5ccce37 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+@@ -2859,7 +2859,7 @@ _scsih_internal_device_block(struct scsi_device *sdev,
+ sas_device_priv_data->sas_target->handle);
+ sas_device_priv_data->block = 1;
+
+- r = scsi_internal_device_block(sdev, false);
++ r = scsi_internal_device_block_nowait(sdev);
+ if (r == -EINVAL)
+ sdev_printk(KERN_WARNING, sdev,
+ "device_block failed with return(%d) for handle(0x%04x)\n",
+@@ -2895,7 +2895,7 @@ _scsih_internal_device_unblock(struct scsi_device *sdev,
+ "performing a block followed by an unblock\n",
+ r, sas_device_priv_data->sas_target->handle);
+ sas_device_priv_data->block = 1;
+- r = scsi_internal_device_block(sdev, false);
++ r = scsi_internal_device_block_nowait(sdev);
+ if (r)
+ sdev_printk(KERN_WARNING, sdev, "retried device_block "
+ "failed with return(%d) for handle(0x%04x)\n",
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index a95eb022fb89..fc8f394eb854 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -2944,28 +2944,20 @@ scsi_target_resume(struct scsi_target *starget)
+ EXPORT_SYMBOL(scsi_target_resume);
+
+ /**
+- * scsi_internal_device_block - internal function to put a device temporarily into the SDEV_BLOCK state
+- * @sdev: device to block
+- * @wait: Whether or not to wait until ongoing .queuecommand() /
+- * .queue_rq() calls have finished.
++ * scsi_internal_device_block_nowait - try to transition to the SDEV_BLOCK state
++ * @sdev: device to block
+ *
+- * Block request made by scsi lld's to temporarily stop all
+- * scsi commands on the specified device. May sleep.
++ * Pause SCSI command processing on the specified device. Does not sleep.
+ *
+- * Returns zero if successful or error if not
++ * Returns zero if successful or a negative error code upon failure.
+ *
+- * Notes:
+- * This routine transitions the device to the SDEV_BLOCK state
+- * (which must be a legal transition). When the device is in this
+- * state, all commands are deferred until the scsi lld reenables
+- * the device with scsi_device_unblock or device_block_tmo fires.
+- *
+- * To do: avoid that scsi_send_eh_cmnd() calls queuecommand() after
+- * scsi_internal_device_block() has blocked a SCSI device and also
+- * remove the rport mutex lock and unlock calls from srp_queuecommand().
++ * Notes:
++ * This routine transitions the device to the SDEV_BLOCK state (which must be
++ * a legal transition). When the device is in this state, command processing
++ * is paused until the device leaves the SDEV_BLOCK state. See also
++ * scsi_internal_device_unblock_nowait().
+ */
+-int
+-scsi_internal_device_block(struct scsi_device *sdev, bool wait)
++int scsi_internal_device_block_nowait(struct scsi_device *sdev)
+ {
+ struct request_queue *q = sdev->request_queue;
+ unsigned long flags;
+@@ -2985,21 +2977,50 @@ scsi_internal_device_block(struct scsi_device *sdev, bool wait)
+ * request queue.
+ */
+ if (q->mq_ops) {
+- if (wait)
+- blk_mq_quiesce_queue(q);
+- else
+- blk_mq_stop_hw_queues(q);
++ blk_mq_stop_hw_queues(q);
+ } else {
+ spin_lock_irqsave(q->queue_lock, flags);
+ blk_stop_queue(q);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+- if (wait)
+- scsi_wait_for_queuecommand(sdev);
+ }
+
+ return 0;
+ }
+-EXPORT_SYMBOL_GPL(scsi_internal_device_block);
++EXPORT_SYMBOL_GPL(scsi_internal_device_block_nowait);
++
++/**
++ * scsi_internal_device_block - try to transition to the SDEV_BLOCK state
++ * @sdev: device to block
++ *
++ * Pause SCSI command processing on the specified device and wait until all
++ * ongoing scsi_request_fn() / scsi_queue_rq() calls have finished. May sleep.
++ *
++ * Returns zero if successful or a negative error code upon failure.
++ *
++ * Note:
++ * This routine transitions the device to the SDEV_BLOCK state (which must be
++ * a legal transition). When the device is in this state, command processing
++ * is paused until the device leaves the SDEV_BLOCK state. See also
++ * scsi_internal_device_unblock().
++ *
++ * To do: avoid that scsi_send_eh_cmnd() calls queuecommand() after
++ * scsi_internal_device_block() has blocked a SCSI device and also
++ * remove the rport mutex lock and unlock calls from srp_queuecommand().
++ */
++static int scsi_internal_device_block(struct scsi_device *sdev)
++{
++ struct request_queue *q = sdev->request_queue;
++ int err;
++
++ err = scsi_internal_device_block_nowait(sdev);
++ if (err == 0) {
++ if (q->mq_ops)
++ blk_mq_quiesce_queue(q);
++ else
++ scsi_wait_for_queuecommand(sdev);
++ }
++ return err;
++}
+
+ /**
+ * scsi_internal_device_unblock - resume a device after a block request
+@@ -3056,7 +3077,7 @@ EXPORT_SYMBOL_GPL(scsi_internal_device_unblock);
+ static void
+ device_block(struct scsi_device *sdev, void *data)
+ {
+- scsi_internal_device_block(sdev, true);
++ scsi_internal_device_block(sdev);
+ }
+
+ static int
+diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
+index 05641aebd181..6ce6888f3c69 100644
+--- a/include/scsi/scsi_device.h
++++ b/include/scsi/scsi_device.h
+@@ -472,7 +472,7 @@ static inline int scsi_device_created(struct scsi_device *sdev)
+ sdev->sdev_state == SDEV_CREATED_BLOCK;
+ }
+
+-int scsi_internal_device_block(struct scsi_device *sdev, bool wait);
++int scsi_internal_device_block_nowait(struct scsi_device *sdev);
+ int scsi_internal_device_unblock(struct scsi_device *sdev,
+ enum scsi_device_state new_state);
+
+--
+2.16.4
+
diff --git a/series.conf b/series.conf
index 5114496171..24610bda00 100644
--- a/series.conf
+++ b/series.conf
@@ -21166,6 +21166,7 @@
patches.drivers/scsi-qla2xxx-Remove-extra-register-read.patch
patches.drivers/0018-scsi-qedf-Check-if-sense-buffer-has-been-allocated-d.patch
patches.drivers/scsi-qla2xxx-remove-writeq-readq-function-definition.patch
+ patches.fixes/scsi-Split-scsi_internal_device_block.patch
patches.drivers/scsi-qla2xxx-remove-redundant-null-check-on-tgt.patch
patches.drivers/scsi-qla2xxx-Fix-compile-warning.patch
patches.drivers/0019-scsi-qedf-Fix-a-return-value-in-case-of-error-in-qed.patch