Home Home > GIT Browse > SLE12-SP3-AZURE
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKernel Build Daemon <kbuild@suse.de>2019-01-15 07:08:27 +0100
committerKernel Build Daemon <kbuild@suse.de>2019-01-15 07:08:27 +0100
commit7336445d0d9324f3d8d1d5e0727e943f7cf7dd61 (patch)
tree7ac95edcfc778d1a99a9b9848fe08a4fc96bf87f
parent87e6e4d1e4780cd94ef0cfd8b6d59a307d9f14fd (diff)
parent045b211c801fd5eebe25bce70ff6eff9878c2c5f (diff)
Merge branch 'SLE12-SP3' into SLE12-SP3-AZURE
-rw-r--r--blacklist.conf1
-rw-r--r--patches.fixes/scsi-Create-two-versions-of-scsi_internal_device_unb.patch132
-rw-r--r--patches.fixes/scsi-Introduce-scsi_start_queue.patch86
-rw-r--r--patches.fixes/scsi-Make-__scsi_remove_device-go-straight-from-BLOC.patch94
-rw-r--r--patches.fixes/scsi-Protect-SCSI-device-state-changes-with-a-mutex.patch289
-rw-r--r--patches.fixes/scsi-Split-scsi_internal_device_block.patch173
-rw-r--r--patches.kabi/scsi-Re-export-scsi_internal_device_-un-_block.patch68
-rw-r--r--patches.kabi/scsi-use-inquiry_mutex-instead-of-state_mutex.patch218
-rw-r--r--patches.suse/dm-multipath-do-not-assign-cmd_flags-in-setup_clone.patch49
-rw-r--r--patches.suse/hpwdt-calculate-reload-each-use.patch2
-rw-r--r--series.conf8
11 files changed, 1119 insertions, 1 deletions
diff --git a/blacklist.conf b/blacklist.conf
index 9085b0791e..d3294c5790 100644
--- a/blacklist.conf
+++ b/blacklist.conf
@@ -574,3 +574,4 @@ fb265c9cb49e2074ddcdd4de99728aefdd3b3592 # Intrusive patch, mostly cleanup, fixe
b767ad726c2aa6219318bf0da83fbe690e653d9a # Duplicate of 713b93f1b849527e8c440753fc92cc6c202f2092
b217113362f9e24e68ce849fc2fef7a1d2e40b82 # Not requied for SLE or openSUSE
dd6251e463d3d8ea55ac2c5944e24bd6ed8f423b # Since gic implementation_rev missing
+548f0e65a38f36976260a63ff4acfa9f3b17307d # Invalidated by follow-up changes
diff --git a/patches.fixes/scsi-Create-two-versions-of-scsi_internal_device_unb.patch b/patches.fixes/scsi-Create-two-versions-of-scsi_internal_device_unb.patch
new file mode 100644
index 0000000000..cd0edb1a77
--- /dev/null
+++ b/patches.fixes/scsi-Create-two-versions-of-scsi_internal_device_unb.patch
@@ -0,0 +1,132 @@
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Fri, 2 Jun 2017 14:21:54 -0700
+Subject: [PATCH] scsi: Create two versions of scsi_internal_device_unblock()
+Git-commit: 43f7571be077ee4673466cbcba115427d68440e1
+Patch-mainline: v4.13-rc1
+References: bsc#1119877
+
+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 | 46 +++++++++++++++++++++++++-----------
+ include/scsi/scsi_device.h | 4 ++--
+ 3 files changed, 36 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+index c63bc5ccce37..22998cbd538f 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+@@ -2883,7 +2883,7 @@ _scsih_internal_device_unblock(struct scsi_device *sdev,
+ sdev_printk(KERN_WARNING, sdev, "device_unblock and setting to running, "
+ "handle(0x%04x)\n", sas_device_priv_data->sas_target->handle);
+ sas_device_priv_data->block = 0;
+- r = scsi_internal_device_unblock(sdev, SDEV_RUNNING);
++ r = scsi_internal_device_unblock_nowait(sdev, SDEV_RUNNING);
+ if (r == -EINVAL) {
+ /* The device has been set to SDEV_RUNNING by SD layer during
+ * device addition but the request queue is still stopped by
+@@ -2902,7 +2902,7 @@ _scsih_internal_device_unblock(struct scsi_device *sdev,
+ r, sas_device_priv_data->sas_target->handle);
+
+ sas_device_priv_data->block = 0;
+- r = scsi_internal_device_unblock(sdev, SDEV_RUNNING);
++ r = scsi_internal_device_unblock_nowait(sdev, SDEV_RUNNING);
+ if (r)
+ sdev_printk(KERN_WARNING, sdev, "retried device_unblock"
+ " failed with return(%d) for handle(0x%04x)\n",
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index fc8f394eb854..f0eb55744513 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -3023,24 +3023,22 @@ static int scsi_internal_device_block(struct scsi_device *sdev)
+ }
+
+ /**
+- * scsi_internal_device_unblock - resume a device after a block request
++ * scsi_internal_device_unblock_nowait - resume a device after a block request
+ * @sdev: device to resume
+- * @new_state: state to set devices to after unblocking
++ * @new_state: state to set the device to after unblocking
+ *
+- * Called by scsi lld's or the midlayer to restart the device queue
+- * for the previously suspended scsi device. Called from interrupt or
+- * normal process context.
++ * Restart the device queue for a previously suspended SCSI 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_RUNNING state
+- * or to one of the offline states (which must be a legal transition)
+- * allowing the midlayer to goose the queue for this device.
++ * Notes:
++ * This routine transitions the device to the SDEV_RUNNING state or to one of
++ * the offline states (which must be a legal transition) allowing the midlayer
++ * to goose the queue for this device.
+ */
+-int
+-scsi_internal_device_unblock(struct scsi_device *sdev,
+- enum scsi_device_state new_state)
++int scsi_internal_device_unblock_nowait(struct scsi_device *sdev,
++ enum scsi_device_state new_state)
+ {
+ struct request_queue *q = sdev->request_queue;
+ unsigned long flags;
+@@ -3072,7 +3070,27 @@ scsi_internal_device_unblock(struct scsi_device *sdev,
+
+ return 0;
+ }
+-EXPORT_SYMBOL_GPL(scsi_internal_device_unblock);
++EXPORT_SYMBOL_GPL(scsi_internal_device_unblock_nowait);
++
++/**
++ * scsi_internal_device_unblock - resume a device after a block request
++ * @sdev: device to resume
++ * @new_state: state to set the device to after unblocking
++ *
++ * Restart the device queue for a previously suspended SCSI device. May sleep.
++ *
++ * Returns zero if successful or a negative error code upon failure.
++ *
++ * Notes:
++ * This routine transitions the device to the SDEV_RUNNING state or to one of
++ * the offline states (which must be a legal transition) allowing the midlayer
++ * to goose the queue for this device.
++ */
++static int scsi_internal_device_unblock(struct scsi_device *sdev,
++ enum scsi_device_state new_state)
++{
++ return scsi_internal_device_unblock_nowait(sdev, new_state);
++}
+
+ static void
+ device_block(struct scsi_device *sdev, void *data)
+diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
+index 6ce6888f3c69..5f24dae2a8e1 100644
+--- a/include/scsi/scsi_device.h
++++ b/include/scsi/scsi_device.h
+@@ -473,8 +473,8 @@ static inline int scsi_device_created(struct scsi_device *sdev)
+ }
+
+ 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);
++int scsi_internal_device_unblock_nowait(struct scsi_device *sdev,
++ enum scsi_device_state new_state);
+
+ /* accessor functions for the SCSI parameters */
+ static inline int scsi_device_sync(struct scsi_device *sdev)
+--
+2.16.4
+
diff --git a/patches.fixes/scsi-Introduce-scsi_start_queue.patch b/patches.fixes/scsi-Introduce-scsi_start_queue.patch
new file mode 100644
index 0000000000..fa185e38d3
--- /dev/null
+++ b/patches.fixes/scsi-Introduce-scsi_start_queue.patch
@@ -0,0 +1,86 @@
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Fri, 2 Jun 2017 14:21:56 -0700
+Subject: [PATCH] scsi: Introduce scsi_start_queue()
+Git-commit: 66483a4a9f34427e3d6ec87d8e583f5d2a7cbb76
+References: bsc#1119877
+Patch-Mainline: v4.13-rc1
+
+This patch does not change any functionality.
+
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Cc: Israel Rukshin <israelr@mellanox.com>
+Cc: Max Gurtovoy <maxg@mellanox.com>
+Cc: Benjamin Block <bblock@linux.vnet.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/scsi_lib.c | 25 +++++++++++++++----------
+ drivers/scsi/scsi_priv.h | 1 +
+ 2 files changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index 4b0bac3ac6ab..ed744668b984 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -3031,6 +3031,20 @@ static int scsi_internal_device_block(struct scsi_device *sdev)
+ return err;
+ }
+
++void scsi_start_queue(struct scsi_device *sdev)
++{
++ struct request_queue *q = sdev->request_queue;
++ unsigned long flags;
++
++ if (q->mq_ops) {
++ blk_mq_start_stopped_hw_queues(q, false);
++ } else {
++ spin_lock_irqsave(q->queue_lock, flags);
++ blk_start_queue(q);
++ spin_unlock_irqrestore(q->queue_lock, flags);
++ }
++}
++
+ /**
+ * scsi_internal_device_unblock_nowait - resume a device after a block request
+ * @sdev: device to resume
+@@ -3049,9 +3063,6 @@ static int scsi_internal_device_block(struct scsi_device *sdev)
+ int scsi_internal_device_unblock_nowait(struct scsi_device *sdev,
+ enum scsi_device_state new_state)
+ {
+- struct request_queue *q = sdev->request_queue;
+- unsigned long flags;
+-
+ /*
+ * Try to transition the scsi device to SDEV_RUNNING or one of the
+ * offlined states and goose the device queue if successful.
+@@ -3069,13 +3080,7 @@ int scsi_internal_device_unblock_nowait(struct scsi_device *sdev,
+ sdev->sdev_state != SDEV_OFFLINE)
+ return -EINVAL;
+
+- if (q->mq_ops) {
+- blk_mq_start_stopped_hw_queues(q, false);
+- } else {
+- spin_lock_irqsave(q->queue_lock, flags);
+- blk_start_queue(q);
+- spin_unlock_irqrestore(q->queue_lock, flags);
+- }
++ scsi_start_queue(sdev);
+
+ return 0;
+ }
+diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
+index 59ebc1795bb3..f86057842f9a 100644
+--- a/drivers/scsi/scsi_priv.h
++++ b/drivers/scsi/scsi_priv.h
+@@ -88,6 +88,7 @@ extern void scsi_run_host_queues(struct Scsi_Host *shost);
+ extern void scsi_requeue_run_queue(struct work_struct *work);
+ extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev);
+ extern struct request_queue *scsi_mq_alloc_queue(struct scsi_device *sdev);
++extern void scsi_start_queue(struct scsi_device *sdev);
+ extern int scsi_mq_setup_tags(struct Scsi_Host *shost);
+ extern void scsi_mq_destroy_tags(struct Scsi_Host *shost);
+ extern int scsi_init_queue(void);
+--
+2.16.4
+
diff --git a/patches.fixes/scsi-Make-__scsi_remove_device-go-straight-from-BLOC.patch b/patches.fixes/scsi-Make-__scsi_remove_device-go-straight-from-BLOC.patch
new file mode 100644
index 0000000000..d5dd8e234d
--- /dev/null
+++ b/patches.fixes/scsi-Make-__scsi_remove_device-go-straight-from-BLOC.patch
@@ -0,0 +1,94 @@
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Fri, 2 Jun 2017 14:21:57 -0700
+Subject: [PATCH] scsi: Make __scsi_remove_device go straight from BLOCKED to
+ DEL
+Git-commit: 255ee9320e5dc46173bb94dbcd68e32f11fc10a9
+References: bsc#1119877
+Patch-Mainline: v4.13-rc1
+
+If a device is blocked, make __scsi_remove_device() cause it to
+transition to the DEL state. This means that all the commands issued in
+.shutdown() will error in the mid-layer, thus making the removal proceed
+without being stopped.
+
+This patch is a slightly modified version of a patch from James
+Bottomley. This patch avoids that the following lockup occurs:
+
+Call Trace:
+ schedule+0x35/0x80
+ schedule_timeout+0x237/0x2d0
+ io_schedule_timeout+0xa6/0x110
+ wait_for_completion_io+0xa3/0x110
+ blk_execute_rq+0xdf/0x120
+ scsi_execute+0xce/0x150 [scsi_mod]
+ scsi_execute_req_flags+0x8f/0xf0 [scsi_mod]
+ sd_sync_cache+0xa9/0x190 [sd_mod]
+ sd_shutdown+0x6a/0x100 [sd_mod]
+ sd_remove+0x64/0xc0 [sd_mod]
+ __device_release_driver+0x8d/0x120
+ device_release_driver+0x1e/0x30
+ bus_remove_device+0xf9/0x170
+ device_del+0x127/0x240
+ __scsi_remove_device+0xc1/0xd0 [scsi_mod]
+ scsi_forget_host+0x57/0x60 [scsi_mod]
+ scsi_remove_host+0x72/0x110 [scsi_mod]
+ srp_remove_work+0x8b/0x200 [ib_srp]
+
+Reported-by: Israel Rukshin <israelr@mellanox.com>
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
+Cc: Israel Rukshin <israelr@mellanox.com>
+Cc: Max Gurtovoy <maxg@mellanox.com>
+Cc: Benjamin Block <bblock@linux.vnet.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/scsi_lib.c | 2 +-
+ drivers/scsi/scsi_sysfs.c | 10 ++++++++++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index ed744668b984..0554a6a7ea55 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -2625,7 +2625,6 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
+ case SDEV_QUIESCE:
+ case SDEV_OFFLINE:
+ case SDEV_TRANSPORT_OFFLINE:
+- case SDEV_BLOCK:
+ break;
+ default:
+ goto illegal;
+@@ -2639,6 +2638,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
+ case SDEV_OFFLINE:
+ case SDEV_TRANSPORT_OFFLINE:
+ case SDEV_CANCEL:
++ case SDEV_BLOCK:
+ case SDEV_CREATED_BLOCK:
+ break;
+ default:
+diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
+index a91537a3abbf..ce470f62a8ae 100644
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -1290,7 +1290,17 @@ void __scsi_remove_device(struct scsi_device *sdev)
+ * wait until it has finished before changing the device state.
+ */
+ mutex_lock(&sdev->state_mutex);
++ /*
++ * If blocked, we go straight to DEL and restart the queue so
++ * any commands issued during driver shutdown (like sync
++ * cache) are errored immediately.
++ */
+ res = scsi_device_set_state(sdev, SDEV_CANCEL);
++ if (res != 0) {
++ res = scsi_device_set_state(sdev, SDEV_DEL);
++ if (res == 0)
++ scsi_start_queue(sdev);
++ }
+ mutex_unlock(&sdev->state_mutex);
+
+ if (res != 0)
+--
+2.16.4
+
diff --git a/patches.fixes/scsi-Protect-SCSI-device-state-changes-with-a-mutex.patch b/patches.fixes/scsi-Protect-SCSI-device-state-changes-with-a-mutex.patch
new file mode 100644
index 0000000000..e114c12289
--- /dev/null
+++ b/patches.fixes/scsi-Protect-SCSI-device-state-changes-with-a-mutex.patch
@@ -0,0 +1,289 @@
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Fri, 2 Jun 2017 14:21:55 -0700
+Subject: [PATCH] scsi: Protect SCSI device state changes with a mutex
+Git-commit: 0db6ca8a5e1ea585795db3643ec7d50fc8cb1aff
+Patch-mainline: v4.13-rc1
+References: bsc#1119877
+
+Serializing SCSI device state changes avoids that two state changes can
+occur concurrently, e.g. the state changes in scsi_target_block() and
+__scsi_remove_device(). This serialization is essential to make patch
+"Make __scsi_remove_device go straight from BLOCKED to DEL" work
+reliably.
+
+Enable this mechanism for all scsi_target_*block() callers but not for
+the scsi_internal_device_unblock() calls from the mpt3sas driver because
+that driver can call scsi_internal_device_unblock() from atomic context.
+
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Hannes Reinecke <hare@suse.com>
+Cc: Johannes Thumshirn <jthumshirn@suse.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Hannes Reinecke <hare@suse.com>
+---
+ drivers/scsi/scsi_error.c | 8 +++++++-
+ drivers/scsi/scsi_lib.c | 27 +++++++++++++++++++++------
+ drivers/scsi/scsi_scan.c | 16 +++++++++-------
+ drivers/scsi/scsi_sysfs.c | 24 +++++++++++++++++++-----
+ drivers/scsi/scsi_transport_srp.c | 7 ++++---
+ drivers/scsi/sd.c | 7 +++++--
+ include/scsi/scsi_device.h | 1 +
+ 7 files changed, 66 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index ecc07dab893d..ac3196420435 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -1628,11 +1628,17 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q,
+ struct list_head *done_q)
+ {
+ struct scsi_cmnd *scmd, *next;
++ struct scsi_device *sdev;
+
+ list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
+ sdev_printk(KERN_INFO, scmd->device, "Device offlined - "
+ "not ready after error recovery\n");
+- scsi_device_set_state(scmd->device, SDEV_OFFLINE);
++ sdev = scmd->device;
++
++ mutex_lock(&sdev->state_mutex);
++ scsi_device_set_state(sdev, SDEV_OFFLINE);
++ mutex_unlock(&sdev->state_mutex);
++
+ if (scmd->eh_eflags & SCSI_EH_CANCEL_CMD) {
+ /*
+ * FIXME: Handle lost cmds.
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index f0eb55744513..4b0bac3ac6ab 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -2882,7 +2882,12 @@ static void scsi_wait_for_queuecommand(struct scsi_device *sdev)
+ int
+ scsi_device_quiesce(struct scsi_device *sdev)
+ {
+- int err = scsi_device_set_state(sdev, SDEV_QUIESCE);
++ int err;
++
++ mutex_lock(&sdev->state_mutex);
++ err = scsi_device_set_state(sdev, SDEV_QUIESCE);
++ mutex_unlock(&sdev->state_mutex);
++
+ if (err)
+ return err;
+
+@@ -2910,10 +2915,11 @@ void scsi_device_resume(struct scsi_device *sdev)
+ * so assume the state is being managed elsewhere (for example
+ * device deleted during suspend)
+ */
+- if (sdev->sdev_state != SDEV_QUIESCE ||
+- scsi_device_set_state(sdev, SDEV_RUNNING))
+- return;
+- scsi_run_queue(sdev->request_queue);
++ mutex_lock(&sdev->state_mutex);
++ if (sdev->sdev_state == SDEV_QUIESCE &&
++ scsi_device_set_state(sdev, SDEV_RUNNING) == 0)
++ scsi_run_queue(sdev->request_queue);
++ mutex_unlock(&sdev->state_mutex);
+ }
+ EXPORT_SYMBOL(scsi_device_resume);
+
+@@ -3012,6 +3018,7 @@ static int scsi_internal_device_block(struct scsi_device *sdev)
+ struct request_queue *q = sdev->request_queue;
+ int err;
+
++ mutex_lock(&sdev->state_mutex);
+ err = scsi_internal_device_block_nowait(sdev);
+ if (err == 0) {
+ if (q->mq_ops)
+@@ -3019,6 +3026,8 @@ static int scsi_internal_device_block(struct scsi_device *sdev)
+ else
+ scsi_wait_for_queuecommand(sdev);
+ }
++ mutex_unlock(&sdev->state_mutex);
++
+ return err;
+ }
+
+@@ -3089,7 +3098,13 @@ EXPORT_SYMBOL_GPL(scsi_internal_device_unblock_nowait);
+ static int scsi_internal_device_unblock(struct scsi_device *sdev,
+ enum scsi_device_state new_state)
+ {
+- return scsi_internal_device_unblock_nowait(sdev, new_state);
++ int ret;
++
++ mutex_lock(&sdev->state_mutex);
++ ret = scsi_internal_device_unblock_nowait(sdev, new_state);
++ mutex_unlock(&sdev->state_mutex);
++
++ return ret;
+ }
+
+ static void
+diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
+index 6f7128f49c30..e6de4eee97a3 100644
+--- a/drivers/scsi/scsi_scan.c
++++ b/drivers/scsi/scsi_scan.c
+@@ -231,6 +231,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
+ sdev->id = starget->id;
+ sdev->lun = lun;
+ sdev->channel = starget->channel;
++ mutex_init(&sdev->state_mutex);
+ sdev->sdev_state = SDEV_CREATED;
+ INIT_LIST_HEAD(&sdev->siblings);
+ INIT_LIST_HEAD(&sdev->same_target_siblings);
+@@ -943,16 +944,17 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
+
+ /* set the device running here so that slave configure
+ * may do I/O */
++ mutex_lock(&sdev->state_mutex);
+ ret = scsi_device_set_state(sdev, SDEV_RUNNING);
+- if (ret) {
++ if (ret)
+ ret = scsi_device_set_state(sdev, SDEV_BLOCK);
++ mutex_unlock(&sdev->state_mutex);
+
+- if (ret) {
+- sdev_printk(KERN_ERR, sdev,
+- "in wrong state %s to complete scan\n",
+- scsi_device_state_name(sdev->sdev_state));
+- return SCSI_SCAN_NO_RESPONSE;
+- }
++ if (ret) {
++ sdev_printk(KERN_ERR, sdev,
++ "in wrong state %s to complete scan\n",
++ scsi_device_state_name(sdev->sdev_state));
++ return SCSI_SCAN_NO_RESPONSE;
+ }
+
+ if (*bflags & BLIST_MS_192_BYTES_FOR_3F)
+diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
+index 82dfe07b1d47..a91537a3abbf 100644
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -719,7 +719,7 @@ static ssize_t
+ store_state_field(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+- int i;
++ int i, ret;
+ struct scsi_device *sdev = to_scsi_device(dev);
+ enum scsi_device_state state = 0;
+
+@@ -734,9 +734,11 @@ store_state_field(struct device *dev, struct device_attribute *attr,
+ if (!state)
+ return -EINVAL;
+
+- if (scsi_device_set_state(sdev, state))
+- return -EINVAL;
+- return count;
++ mutex_lock(&sdev->state_mutex);
++ ret = scsi_device_set_state(sdev, state);
++ mutex_unlock(&sdev->state_mutex);
++
++ return ret == 0 ? count : -EINVAL;
+ }
+
+ static ssize_t
+@@ -1272,6 +1274,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
+ void __scsi_remove_device(struct scsi_device *sdev)
+ {
+ struct device *dev = &sdev->sdev_gendev;
++ int res;
+
+ /*
+ * This cleanup path is not reentrant and while it is impossible
+@@ -1282,7 +1285,15 @@ void __scsi_remove_device(struct scsi_device *sdev)
+ return;
+
+ if (sdev->is_visible) {
+- if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
++ /*
++ * If scsi_internal_target_block() is running concurrently,
++ * wait until it has finished before changing the device state.
++ */
++ mutex_lock(&sdev->state_mutex);
++ res = scsi_device_set_state(sdev, SDEV_CANCEL);
++ mutex_unlock(&sdev->state_mutex);
++
++ if (res != 0)
+ return;
+
+ bsg_unregister_queue(sdev->request_queue);
+@@ -1298,7 +1309,10 @@ void __scsi_remove_device(struct scsi_device *sdev)
+ * scsi_run_queue() invocations have finished before tearing down the
+ * device.
+ */
++ mutex_lock(&sdev->state_mutex);
+ scsi_device_set_state(sdev, SDEV_DEL);
++ mutex_unlock(&sdev->state_mutex);
++
+ blk_cleanup_queue(sdev->request_queue);
+ cancel_work_sync(&sdev->requeue_work);
+
+diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c
+index 3c5d89852e9f..f617021c94f7 100644
+--- a/drivers/scsi/scsi_transport_srp.c
++++ b/drivers/scsi/scsi_transport_srp.c
+@@ -554,11 +554,12 @@ int srp_reconnect_rport(struct srp_rport *rport)
+ * invoking scsi_target_unblock() won't change the state of
+ * these devices into running so do that explicitly.
+ */
+- spin_lock_irq(shost->host_lock);
+- __shost_for_each_device(sdev, shost)
++ shost_for_each_device(sdev, shost) {
++ mutex_lock(&sdev->state_mutex);
+ if (sdev->sdev_state == SDEV_OFFLINE)
+ sdev->sdev_state = SDEV_RUNNING;
+- spin_unlock_irq(shost->host_lock);
++ mutex_unlock(&sdev->state_mutex);
++ }
+ } else if (rport->state == SRP_RPORT_RUNNING) {
+ /*
+ * srp_reconnect_rport() has been invoked with fast_io_fail
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
+index b6bb4e0ce0e3..53b6d72c214d 100644
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -1818,13 +1818,14 @@ static void sd_eh_reset(struct scsi_cmnd *scmd)
+ static int sd_eh_action(struct scsi_cmnd *scmd, int eh_disp)
+ {
+ struct scsi_disk *sdkp = scsi_disk(scmd->request->rq_disk);
++ struct scsi_device *sdev = scmd->device;
+
+ if (eh_disp == SCSI_RETURN_NOT_HANDLED) {
+ /* New SCSI EH run, reset gate variable */
+ sdkp->ignore_medium_access_errors = false;
+ return eh_disp;
+ }
+- if (!scsi_device_online(scmd->device) ||
++ if (!scsi_device_online(sdev) ||
+ !scsi_medium_access_command(scmd) ||
+ host_byte(scmd->result) != DID_TIME_OUT ||
+ eh_disp != SUCCESS)
+@@ -1845,7 +1846,9 @@ static int sd_eh_action(struct scsi_cmnd *scmd, int eh_disp)
+ if (sdkp->medium_access_timed_out >= sdkp->max_medium_access_timeouts) {
+ scmd_printk(KERN_ERR, scmd,
+ "Medium access timeout failure. Offlining disk!\n");
+- scsi_device_set_state(scmd->device, SDEV_OFFLINE);
++ mutex_lock(&sdev->state_mutex);
++ scsi_device_set_state(sdev, SDEV_OFFLINE);
++ mutex_unlock(&sdev->state_mutex);
+
+ return FAILED;
+ }
+diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
+index 5f24dae2a8e1..d13bc80825b1 100644
+--- a/include/scsi/scsi_device.h
++++ b/include/scsi/scsi_device.h
+@@ -207,6 +207,7 @@ struct scsi_device {
+ void *handler_data;
+
+ unsigned char access_state;
++ struct mutex state_mutex;
+ enum scsi_device_state sdev_state;
+ unsigned long sdev_data[0];
+ } __attribute__((aligned(sizeof(unsigned long))));
+--
+2.16.4
+
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/patches.kabi/scsi-Re-export-scsi_internal_device_-un-_block.patch b/patches.kabi/scsi-Re-export-scsi_internal_device_-un-_block.patch
new file mode 100644
index 0000000000..3012f78a6e
--- /dev/null
+++ b/patches.kabi/scsi-Re-export-scsi_internal_device_-un-_block.patch
@@ -0,0 +1,68 @@
+From: Hannes Reinecke <hare@suse.de>
+Date: Mon, 14 Jan 2019 08:10:58 +0100
+Subject: [PATCH] scsi: Re-export scsi_internal_device_{,un}_block()
+Patch-Mainline: never, SLE12 SP3 kABI fix
+References: bsc#1119877
+
+Re-export symbols which got dropped to preserve the kABI.
+
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+---
+ drivers/scsi/scsi_lib.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index e5e52fbbea9d..99b1a2a0a826 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -2996,7 +2996,9 @@ EXPORT_SYMBOL_GPL(scsi_internal_device_block_nowait);
+
+ /**
+ * scsi_internal_device_block - try to transition to the SDEV_BLOCK state
+- * @sdev: device to block
++ * @sdev: device to block
++ * @wait: Whether or not to wait until ongoing .queuecommand() /
++ * .queue_rq() calls have finished.
+ *
+ * Pause SCSI command processing on the specified device and wait until all
+ * ongoing scsi_request_fn() / scsi_queue_rq() calls have finished. May sleep.
+@@ -3013,11 +3015,13 @@ EXPORT_SYMBOL_GPL(scsi_internal_device_block_nowait);
+ * 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)
++static int scsi_internal_device_block(struct scsi_device *sdev, bool wait)
+ {
+ struct request_queue *q = sdev->request_queue;
+ int err;
+
++ if (!wait)
++ return scsi_internal_device_block_nowait(sdev);
+ mutex_lock(&sdev->inquiry_mutex);
+ err = scsi_internal_device_block_nowait(sdev);
+ if (err == 0) {
+@@ -3030,6 +3034,7 @@ static int scsi_internal_device_block(struct scsi_device *sdev)
+
+ return err;
+ }
++EXPORT_SYMBOL_GPL(scsi_internal_device_block);
+
+ void scsi_start_queue(struct scsi_device *sdev)
+ {
+@@ -3111,11 +3116,12 @@ static int scsi_internal_device_unblock(struct scsi_device *sdev,
+
+ return ret;
+ }
++EXPORT_SYMBOL_GPL(scsi_internal_device_unblock);
+
+ static void
+ device_block(struct scsi_device *sdev, void *data)
+ {
+- scsi_internal_device_block(sdev);
++ scsi_internal_device_block(sdev, true);
+ }
+
+ static int
+--
+2.16.4
+
diff --git a/patches.kabi/scsi-use-inquiry_mutex-instead-of-state_mutex.patch b/patches.kabi/scsi-use-inquiry_mutex-instead-of-state_mutex.patch
new file mode 100644
index 0000000000..935d9aa45e
--- /dev/null
+++ b/patches.kabi/scsi-use-inquiry_mutex-instead-of-state_mutex.patch
@@ -0,0 +1,218 @@
+From: Hannes Reinecke <hare@suse.de>
+Date: Fri, 11 Jan 2019 14:53:47 +0100
+Subject: [PATCH] scsi: use 'inquiry_mutex' instead of 'state_mutex'
+Patch-Mainline: never, SLE12 SP3 kABI fix
+References: bsc#1119877
+
+'state_mutex' and 'inquiry_mutex' are used for two distinct use-cases,
+and will never collide. So we can use 'inquiry_mutex' instead of
+'state_mutex' and can drop 'state_mutex' completely, preserving
+the kABI.
+
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+---
+ drivers/scsi/scsi_error.c | 4 ++--
+ drivers/scsi/scsi_lib.c | 16 ++++++++--------
+ drivers/scsi/scsi_scan.c | 5 ++---
+ drivers/scsi/scsi_sysfs.c | 12 ++++++------
+ drivers/scsi/scsi_transport_srp.c | 4 ++--
+ drivers/scsi/sd.c | 4 ++--
+ include/scsi/scsi_device.h | 1 -
+ 7 files changed, 22 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index ac3196420435..457eb54e4466 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -1635,9 +1635,9 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q,
+ "not ready after error recovery\n");
+ sdev = scmd->device;
+
+- mutex_lock(&sdev->state_mutex);
++ mutex_lock(&sdev->inquiry_mutex);
+ scsi_device_set_state(sdev, SDEV_OFFLINE);
+- mutex_unlock(&sdev->state_mutex);
++ mutex_unlock(&sdev->inquiry_mutex);
+
+ if (scmd->eh_eflags & SCSI_EH_CANCEL_CMD) {
+ /*
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index 0554a6a7ea55..e5e52fbbea9d 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -2884,9 +2884,9 @@ scsi_device_quiesce(struct scsi_device *sdev)
+ {
+ int err;
+
+- mutex_lock(&sdev->state_mutex);
++ mutex_lock(&sdev->inquiry_mutex);
+ err = scsi_device_set_state(sdev, SDEV_QUIESCE);
+- mutex_unlock(&sdev->state_mutex);
++ mutex_unlock(&sdev->inquiry_mutex);
+
+ if (err)
+ return err;
+@@ -2915,11 +2915,11 @@ void scsi_device_resume(struct scsi_device *sdev)
+ * so assume the state is being managed elsewhere (for example
+ * device deleted during suspend)
+ */
+- mutex_lock(&sdev->state_mutex);
++ mutex_lock(&sdev->inquiry_mutex);
+ if (sdev->sdev_state == SDEV_QUIESCE &&
+ scsi_device_set_state(sdev, SDEV_RUNNING) == 0)
+ scsi_run_queue(sdev->request_queue);
+- mutex_unlock(&sdev->state_mutex);
++ mutex_unlock(&sdev->inquiry_mutex);
+ }
+ EXPORT_SYMBOL(scsi_device_resume);
+
+@@ -3018,7 +3018,7 @@ static int scsi_internal_device_block(struct scsi_device *sdev)
+ struct request_queue *q = sdev->request_queue;
+ int err;
+
+- mutex_lock(&sdev->state_mutex);
++ mutex_lock(&sdev->inquiry_mutex);
+ err = scsi_internal_device_block_nowait(sdev);
+ if (err == 0) {
+ if (q->mq_ops)
+@@ -3026,7 +3026,7 @@ static int scsi_internal_device_block(struct scsi_device *sdev)
+ else
+ scsi_wait_for_queuecommand(sdev);
+ }
+- mutex_unlock(&sdev->state_mutex);
++ mutex_unlock(&sdev->inquiry_mutex);
+
+ return err;
+ }
+@@ -3105,9 +3105,9 @@ static int scsi_internal_device_unblock(struct scsi_device *sdev,
+ {
+ int ret;
+
+- mutex_lock(&sdev->state_mutex);
++ mutex_lock(&sdev->inquiry_mutex);
+ ret = scsi_internal_device_unblock_nowait(sdev, new_state);
+- mutex_unlock(&sdev->state_mutex);
++ mutex_unlock(&sdev->inquiry_mutex);
+
+ return ret;
+ }
+diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
+index e6de4eee97a3..a6cfa289ccd6 100644
+--- a/drivers/scsi/scsi_scan.c
++++ b/drivers/scsi/scsi_scan.c
+@@ -231,7 +231,6 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
+ sdev->id = starget->id;
+ sdev->lun = lun;
+ sdev->channel = starget->channel;
+- mutex_init(&sdev->state_mutex);
+ sdev->sdev_state = SDEV_CREATED;
+ INIT_LIST_HEAD(&sdev->siblings);
+ INIT_LIST_HEAD(&sdev->same_target_siblings);
+@@ -944,11 +943,11 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
+
+ /* set the device running here so that slave configure
+ * may do I/O */
+- mutex_lock(&sdev->state_mutex);
++ mutex_lock(&sdev->inquiry_mutex);
+ ret = scsi_device_set_state(sdev, SDEV_RUNNING);
+ if (ret)
+ ret = scsi_device_set_state(sdev, SDEV_BLOCK);
+- mutex_unlock(&sdev->state_mutex);
++ mutex_unlock(&sdev->inquiry_mutex);
+
+ if (ret) {
+ sdev_printk(KERN_ERR, sdev,
+diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
+index ce470f62a8ae..21c91d48d062 100644
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -734,9 +734,9 @@ store_state_field(struct device *dev, struct device_attribute *attr,
+ if (!state)
+ return -EINVAL;
+
+- mutex_lock(&sdev->state_mutex);
++ mutex_lock(&sdev->inquiry_mutex);
+ ret = scsi_device_set_state(sdev, state);
+- mutex_unlock(&sdev->state_mutex);
++ mutex_unlock(&sdev->inquiry_mutex);
+
+ return ret == 0 ? count : -EINVAL;
+ }
+@@ -1289,7 +1289,7 @@ void __scsi_remove_device(struct scsi_device *sdev)
+ * If scsi_internal_target_block() is running concurrently,
+ * wait until it has finished before changing the device state.
+ */
+- mutex_lock(&sdev->state_mutex);
++ mutex_lock(&sdev->inquiry_mutex);
+ /*
+ * If blocked, we go straight to DEL and restart the queue so
+ * any commands issued during driver shutdown (like sync
+@@ -1301,7 +1301,7 @@ void __scsi_remove_device(struct scsi_device *sdev)
+ if (res == 0)
+ scsi_start_queue(sdev);
+ }
+- mutex_unlock(&sdev->state_mutex);
++ mutex_unlock(&sdev->inquiry_mutex);
+
+ if (res != 0)
+ return;
+@@ -1319,9 +1319,9 @@ void __scsi_remove_device(struct scsi_device *sdev)
+ * scsi_run_queue() invocations have finished before tearing down the
+ * device.
+ */
+- mutex_lock(&sdev->state_mutex);
++ mutex_lock(&sdev->inquiry_mutex);
+ scsi_device_set_state(sdev, SDEV_DEL);
+- mutex_unlock(&sdev->state_mutex);
++ mutex_unlock(&sdev->inquiry_mutex);
+
+ blk_cleanup_queue(sdev->request_queue);
+ cancel_work_sync(&sdev->requeue_work);
+diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c
+index f617021c94f7..91dc733ab46c 100644
+--- a/drivers/scsi/scsi_transport_srp.c
++++ b/drivers/scsi/scsi_transport_srp.c
+@@ -555,10 +555,10 @@ int srp_reconnect_rport(struct srp_rport *rport)
+ * these devices into running so do that explicitly.
+ */
+ shost_for_each_device(sdev, shost) {
+- mutex_lock(&sdev->state_mutex);
++ mutex_lock(&sdev->inquiry_mutex);
+ if (sdev->sdev_state == SDEV_OFFLINE)
+ sdev->sdev_state = SDEV_RUNNING;
+- mutex_unlock(&sdev->state_mutex);
++ mutex_unlock(&sdev->inquiry_mutex);
+ }
+ } else if (rport->state == SRP_RPORT_RUNNING) {
+ /*
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
+index 53b6d72c214d..0f15c0a84256 100644
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -1846,9 +1846,9 @@ static int sd_eh_action(struct scsi_cmnd *scmd, int eh_disp)
+ if (sdkp->medium_access_timed_out >= sdkp->max_medium_access_timeouts) {
+ scmd_printk(KERN_ERR, scmd,
+ "Medium access timeout failure. Offlining disk!\n");
+- mutex_lock(&sdev->state_mutex);
++ mutex_lock(&sdev->inquiry_mutex);
+ scsi_device_set_state(sdev, SDEV_OFFLINE);
+- mutex_unlock(&sdev->state_mutex);
++ mutex_unlock(&sdev->inquiry_mutex);
+
+ return FAILED;
+ }
+diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
+index d13bc80825b1..5f24dae2a8e1 100644
+--- a/include/scsi/scsi_device.h
++++ b/include/scsi/scsi_device.h
+@@ -207,7 +207,6 @@ struct scsi_device {
+ void *handler_data;
+
+ unsigned char access_state;
+- struct mutex state_mutex;
+ enum scsi_device_state sdev_state;
+ unsigned long sdev_data[0];
+ } __attribute__((aligned(sizeof(unsigned long))));
+--
+2.16.4
+
diff --git a/patches.suse/dm-multipath-do-not-assign-cmd_flags-in-setup_clone.patch b/patches.suse/dm-multipath-do-not-assign-cmd_flags-in-setup_clone.patch
new file mode 100644
index 0000000000..1249b76c02
--- /dev/null
+++ b/patches.suse/dm-multipath-do-not-assign-cmd_flags-in-setup_clone.patch
@@ -0,0 +1,49 @@
+From: Hannes Reinecke <hare@suse.de>
+Date: Fri, 11 Jan 2019 10:54:01 +0100
+Subject: [PATCH] dm-multipath: do not assign cmd_flags in setup_clone()
+References: bsc#1103156
+Patch-Mainline: never, SLE12 SP3 specific
+
+setup_clone() is called from two locations in different order;
+the 'old' (request-based) implementation is calling setup_clone()
+before __multipath_map(), and the 'new' (blk-mq based) implementation
+is calling setup_clone() _after_ __multipath_map().
+The problem is not that in __multipath_map() itself we only have
+access to the original request for the 'new' implementation, not the
+'old' one.
+Hence we can't copy over the original cmd_flags() in here.
+At the same time we can't use setup_clone() as then the modifications
+would be overwritten by __multipath_map().
+
+So stop modifying cmd_flags() in setup_clone() and use the calling
+location; with that the flags will be set correctly in all cases.
+
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+---
+ drivers/md/dm-rq.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
+index d1a93c0e4b9f..bf16e52d3bca 100644
+--- a/drivers/md/dm-rq.c
++++ b/drivers/md/dm-rq.c
+@@ -498,7 +498,6 @@ static int setup_clone(struct request *clone, struct request *rq,
+ if (r)
+ return r;
+
+- clone->cmd_flags = rq->cmd_flags | REQ_NOMERGE;
+ clone->end_io = end_clone_request;
+ clone->end_io_data = tio;
+
+@@ -525,7 +524,7 @@ static struct request *clone_old_rq(struct request *rq, struct mapped_device *md
+ free_old_clone_request(md, clone);
+ return NULL;
+ }
+-
++ clone->cmd_flags = rq->cmd_flags | REQ_NOMERGE;
+ return clone;
+ }
+
+--
+2.16.4
+
diff --git a/patches.suse/hpwdt-calculate-reload-each-use.patch b/patches.suse/hpwdt-calculate-reload-each-use.patch
index 036df126d6..7a923497f7 100644
--- a/patches.suse/hpwdt-calculate-reload-each-use.patch
+++ b/patches.suse/hpwdt-calculate-reload-each-use.patch
@@ -1,7 +1,7 @@
Subject: hpwdt calculate reload value on each use
From: David Bond <dbond@suse.com>
Patch-mainline: never, SUSE specific
-References: bsc#1114417
+References: bsc#1114417 bsc#1116962
Partial port of mainline commit 0458f403fee34 to fix bug where
calling hpwdt_settimeout() doesn't work due to missing logic
diff --git a/series.conf b/series.conf
index d5ec69b392..22738277dc 100644
--- a/series.conf
+++ b/series.conf
@@ -21171,6 +21171,11 @@
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.fixes/scsi-Create-two-versions-of-scsi_internal_device_unb.patch
+ patches.fixes/scsi-Protect-SCSI-device-state-changes-with-a-mutex.patch
+ patches.fixes/scsi-Introduce-scsi_start_queue.patch
+ patches.fixes/scsi-Make-__scsi_remove_device-go-straight-from-BLOC.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
@@ -24292,6 +24297,8 @@
patches.fixes/libfc-Correctly-set-E_D_TOV-and-R_A_TOV-values-in-RT.patch
patches.drivers/scsi_transport_fc-return-EBUSY-for-deleted-vport.patch
patches.kabi/scsi-kABI-fix-for-new-state-STARGET_CREATED_REMOVE.patch
+ patches.kabi/scsi-use-inquiry_mutex-instead-of-state_mutex.patch
+ patches.kabi/scsi-Re-export-scsi_internal_device_-un-_block.patch
# qla2xxx backport for SP3 (FATE#321701)
patches.suse/qla2xxx-asynchronous-pci-probing.patch
@@ -24741,6 +24748,7 @@
patches.suse/dm-Always-copy-cmd_flags-when-cloning-a-request.patch
patches.fixes/dm-mpath-do-not-try-to-access-NULL-rq.patch
patches.suse/dm-mpath-finally-fixup-cmd_flags.patch
+ patches.suse/dm-multipath-do-not-assign-cmd_flags-in-setup_clone.patch
patches.kabi/nvme-reimplement-nvmf_check_if_ready-to-avoid-kabi-b.patch
patches.kabi/nvme-kABI-compliant-version-of-nvmf_fail_nonready_co.patch