]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 Mar 2018 17:01:26 +0000 (18:01 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 Mar 2018 17:01:26 +0000 (18:01 +0100)
added patches:
scsi-mpt3sas-fix-oops-in-error-handlers-after-shutdown-unload.patch
scsi-mpt3sas-wait-for-and-flush-running-commands-on-shutdown-unload.patch

queue-4.14/scsi-mpt3sas-fix-oops-in-error-handlers-after-shutdown-unload.patch [new file with mode: 0644]
queue-4.14/scsi-mpt3sas-wait-for-and-flush-running-commands-on-shutdown-unload.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/scsi-mpt3sas-fix-oops-in-error-handlers-after-shutdown-unload.patch b/queue-4.14/scsi-mpt3sas-fix-oops-in-error-handlers-after-shutdown-unload.patch
new file mode 100644 (file)
index 0000000..3ea3c68
--- /dev/null
@@ -0,0 +1,87 @@
+From 9ff549ffb4fb4cc9a4b24d1de9dc3e68287797c4 Mon Sep 17 00:00:00 2001
+From: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+Date: Fri, 16 Feb 2018 20:39:57 -0200
+Subject: scsi: mpt3sas: fix oops in error handlers after shutdown/unload
+
+From: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+
+commit 9ff549ffb4fb4cc9a4b24d1de9dc3e68287797c4 upstream.
+
+This patch adds checks for 'ioc->remove_host' in the SCSI error handlers, so
+not to access pointers/resources potentially freed in the PCI shutdown/module
+unload path.  The error handlers may be invoked after shutdown/unload,
+depending on other components.
+
+This problem was observed with kexec on a system with a mpt3sas based adapter
+and an infiniband adapter which takes long enough to shutdown:
+
+The mpt3sas driver finished shutting down / disabled interrupt handling, thus
+some commands have not finished and timed out.
+
+Since the system was still running (waiting for the infiniband adapter to
+shutdown), the scsi error handler for task abort of mpt3sas was invoked, and
+hit an oops -- either in scsih_abort() because 'ioc->scsi_lookup' was NULL
+without commit dbec4c9040ed ("scsi: mpt3sas: lockless command submission"), or
+later up in scsih_host_reset() (with or without that commit), because it
+eventually called mpt3sas_base_get_iocstate().
+
+After the above commit, the oops in scsih_abort() does not occur anymore
+(_scsih_scsi_lookup_find_by_scmd() is no longer called), but that commit is
+too big and out of the scope of linux-stable, where this patch might help, so
+still go for the changes.
+
+Also, this might help to prevent similar errors in the future, in case code
+changes and possibly tries to access freed stuff.
+
+Note the fix in scsih_host_reset() is still important anyway.
+
+Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+Acked-by: Sreekanth Reddy <Sreekanth.Reddy@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/mpt3sas/mpt3sas_scsih.c |   11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+@@ -2471,7 +2471,8 @@ scsih_abort(struct scsi_cmnd *scmd)
+       _scsih_tm_display_info(ioc, scmd);
+       sas_device_priv_data = scmd->device->hostdata;
+-      if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
++      if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
++          ioc->remove_host) {
+               sdev_printk(KERN_INFO, scmd->device,
+                       "device been deleted! scmd(%p)\n", scmd);
+               scmd->result = DID_NO_CONNECT << 16;
+@@ -2533,7 +2534,8 @@ scsih_dev_reset(struct scsi_cmnd *scmd)
+       _scsih_tm_display_info(ioc, scmd);
+       sas_device_priv_data = scmd->device->hostdata;
+-      if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
++      if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
++          ioc->remove_host) {
+               sdev_printk(KERN_INFO, scmd->device,
+                       "device been deleted! scmd(%p)\n", scmd);
+               scmd->result = DID_NO_CONNECT << 16;
+@@ -2595,7 +2597,8 @@ scsih_target_reset(struct scsi_cmnd *scm
+       _scsih_tm_display_info(ioc, scmd);
+       sas_device_priv_data = scmd->device->hostdata;
+-      if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
++      if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
++          ioc->remove_host) {
+               starget_printk(KERN_INFO, starget, "target been deleted! scmd(%p)\n",
+                       scmd);
+               scmd->result = DID_NO_CONNECT << 16;
+@@ -2652,7 +2655,7 @@ scsih_host_reset(struct scsi_cmnd *scmd)
+           ioc->name, scmd);
+       scsi_print_command(scmd);
+-      if (ioc->is_driver_loading) {
++      if (ioc->is_driver_loading || ioc->remove_host) {
+               pr_info(MPT3SAS_FMT "Blocking the host reset\n",
+                   ioc->name);
+               r = FAILED;
diff --git a/queue-4.14/scsi-mpt3sas-wait-for-and-flush-running-commands-on-shutdown-unload.patch b/queue-4.14/scsi-mpt3sas-wait-for-and-flush-running-commands-on-shutdown-unload.patch
new file mode 100644 (file)
index 0000000..1d252f3
--- /dev/null
@@ -0,0 +1,109 @@
+From c666d3be99c000bb889a33353e9be0fa5808d3de Mon Sep 17 00:00:00 2001
+From: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+Date: Fri, 16 Feb 2018 20:39:58 -0200
+Subject: scsi: mpt3sas: wait for and flush running commands on shutdown/unload
+
+From: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+
+commit c666d3be99c000bb889a33353e9be0fa5808d3de upstream.
+
+This patch finishes all outstanding SCSI IO commands (but not other commands,
+e.g., task management) in the shutdown and unload paths.
+
+It first waits for the commands to complete (this is done after setting
+'ioc->remove_host = 1 ', which prevents new commands to be queued) then it
+flushes commands that might still be running.
+
+This avoids triggering error handling (e.g., abort command) for all commands
+possibly completed by the adapter after interrupts disabled.
+
+[mauricfo: introduced something in commit message.]
+
+Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+Tested-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+[mauricfo: backport to linux-4.14.y (a few updates to context lines)]
+Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/mpt3sas/mpt3sas_base.c  |    8 ++++----
+ drivers/scsi/mpt3sas/mpt3sas_base.h  |    3 +++
+ drivers/scsi/mpt3sas/mpt3sas_scsih.c |   10 +++++++++-
+ 3 files changed, 16 insertions(+), 5 deletions(-)
+
+--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
+@@ -5659,14 +5659,14 @@ _base_reset_handler(struct MPT3SAS_ADAPT
+ }
+ /**
+- * _wait_for_commands_to_complete - reset controller
++ * mpt3sas_wait_for_commands_to_complete - reset controller
+  * @ioc: Pointer to MPT_ADAPTER structure
+  *
+  * This function waiting(3s) for all pending commands to complete
+  * prior to putting controller in reset.
+  */
+-static void
+-_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc)
++void
++mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc)
+ {
+       u32 ioc_state;
+       unsigned long flags;
+@@ -5745,7 +5745,7 @@ mpt3sas_base_hard_reset_handler(struct M
+                       is_fault = 1;
+       }
+       _base_reset_handler(ioc, MPT3_IOC_PRE_RESET);
+-      _wait_for_commands_to_complete(ioc);
++      mpt3sas_wait_for_commands_to_complete(ioc);
+       _base_mask_interrupts(ioc);
+       r = _base_make_ioc_ready(ioc, type);
+       if (r)
+--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
+@@ -1292,6 +1292,9 @@ void mpt3sas_base_update_missing_delay(s
+ int mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc);
++void
++mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc);
++
+ /* scsih shared API */
+ u8 mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
+--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+@@ -3960,7 +3960,7 @@ _scsih_flush_running_cmds(struct MPT3SAS
+               _scsih_set_satl_pending(scmd, false);
+               mpt3sas_base_free_smid(ioc, smid);
+               scsi_dma_unmap(scmd);
+-              if (ioc->pci_error_recovery)
++              if (ioc->pci_error_recovery || ioc->remove_host)
+                       scmd->result = DID_NO_CONNECT << 16;
+               else
+                       scmd->result = DID_RESET << 16;
+@@ -8243,6 +8243,10 @@ static void scsih_remove(struct pci_dev
+       unsigned long flags;
+       ioc->remove_host = 1;
++
++      mpt3sas_wait_for_commands_to_complete(ioc);
++      _scsih_flush_running_cmds(ioc);
++
+       _scsih_fw_event_cleanup_queue(ioc);
+       spin_lock_irqsave(&ioc->fw_event_lock, flags);
+@@ -8313,6 +8317,10 @@ scsih_shutdown(struct pci_dev *pdev)
+       unsigned long flags;
+       ioc->remove_host = 1;
++
++      mpt3sas_wait_for_commands_to_complete(ioc);
++      _scsih_flush_running_cmds(ioc);
++
+       _scsih_fw_event_cleanup_queue(ioc);
+       spin_lock_irqsave(&ioc->fw_event_lock, flags);
index 4157cb0c469ace4eb18669ead38ee59e74aeb46f..454a38a747e3f45e602b63401cacf5c9fb3c5af4 100644 (file)
@@ -64,3 +64,5 @@ clk-axi-clkgen-correctly-handle-nocount-bit-in-recalc_rate.patch
 clk-si5351-rename-internal-plls-to-avoid-name-collisions.patch
 crypto-artpec6-set-correct-iv-size-for-gcm-aes.patch
 dmaengine-ti-dma-crossbar-fix-event-mapping-for-tpcc_evt_mux_60_63.patch
+scsi-mpt3sas-fix-oops-in-error-handlers-after-shutdown-unload.patch
+scsi-mpt3sas-wait-for-and-flush-running-commands-on-shutdown-unload.patch