--- /dev/null
+From 318aaf34f1179b39fa9c30fa0f3288b645beee39 Mon Sep 17 00:00:00 2001
+From: Jason Yan <yanaijie@huawei.com>
+Date: Thu, 8 Mar 2018 10:34:53 +0800
+Subject: scsi: libsas: defer ata device eh commands to libata
+
+From: Jason Yan <yanaijie@huawei.com>
+
+commit 318aaf34f1179b39fa9c30fa0f3288b645beee39 upstream.
+
+When ata device doing EH, some commands still attached with tasks are
+not passed to libata when abort failed or recover failed, so libata did
+not handle these commands. After these commands done, sas task is freed,
+but ata qc is not freed. This will cause ata qc leak and trigger a
+warning like below:
+
+WARNING: CPU: 0 PID: 28512 at drivers/ata/libata-eh.c:4037
+ata_eh_finish+0xb4/0xcc
+CPU: 0 PID: 28512 Comm: kworker/u32:2 Tainted: G W OE 4.14.0#1
+......
+Call trace:
+[<ffff0000088b7bd0>] ata_eh_finish+0xb4/0xcc
+[<ffff0000088b8420>] ata_do_eh+0xc4/0xd8
+[<ffff0000088b8478>] ata_std_error_handler+0x44/0x8c
+[<ffff0000088b8068>] ata_scsi_port_error_handler+0x480/0x694
+[<ffff000008875fc4>] async_sas_ata_eh+0x4c/0x80
+[<ffff0000080f6be8>] async_run_entry_fn+0x4c/0x170
+[<ffff0000080ebd70>] process_one_work+0x144/0x390
+[<ffff0000080ec100>] worker_thread+0x144/0x418
+[<ffff0000080f2c98>] kthread+0x10c/0x138
+[<ffff0000080855dc>] ret_from_fork+0x10/0x18
+
+If ata qc leaked too many, ata tag allocation will fail and io blocked
+for ever.
+
+As suggested by Dan Williams, defer ata device commands to libata and
+merge sas_eh_finish_cmd() with sas_eh_defer_cmd(). libata will handle
+ata qcs correctly after this.
+
+Signed-off-by: Jason Yan <yanaijie@huawei.com>
+CC: Xiaofei Tan <tanxiaofei@huawei.com>
+CC: John Garry <john.garry@huawei.com>
+CC: Dan Williams <dan.j.williams@intel.com>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Cc: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/libsas/sas_scsi_host.c | 33 +++++++++++++--------------------
+ 1 file changed, 13 insertions(+), 20 deletions(-)
+
+--- a/drivers/scsi/libsas/sas_scsi_host.c
++++ b/drivers/scsi/libsas/sas_scsi_host.c
+@@ -222,6 +222,7 @@ out_done:
+ static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
+ {
+ struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host);
++ struct domain_device *dev = cmd_to_domain_dev(cmd);
+ struct sas_task *task = TO_SAS_TASK(cmd);
+
+ /* At this point, we only get called following an actual abort
+@@ -230,6 +231,14 @@ static void sas_eh_finish_cmd(struct scs
+ */
+ sas_end_task(cmd, task);
+
++ if (dev_is_sata(dev)) {
++ /* defer commands to libata so that libata EH can
++ * handle ata qcs correctly
++ */
++ list_move_tail(&cmd->eh_entry, &sas_ha->eh_ata_q);
++ return;
++ }
++
+ /* now finish the command and move it on to the error
+ * handler done list, this also takes it off the
+ * error handler pending list.
+@@ -237,22 +246,6 @@ static void sas_eh_finish_cmd(struct scs
+ scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q);
+ }
+
+-static void sas_eh_defer_cmd(struct scsi_cmnd *cmd)
+-{
+- struct domain_device *dev = cmd_to_domain_dev(cmd);
+- struct sas_ha_struct *ha = dev->port->ha;
+- struct sas_task *task = TO_SAS_TASK(cmd);
+-
+- if (!dev_is_sata(dev)) {
+- sas_eh_finish_cmd(cmd);
+- return;
+- }
+-
+- /* report the timeout to libata */
+- sas_end_task(cmd, task);
+- list_move_tail(&cmd->eh_entry, &ha->eh_ata_q);
+-}
+-
+ static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd)
+ {
+ struct scsi_cmnd *cmd, *n;
+@@ -260,7 +253,7 @@ static void sas_scsi_clear_queue_lu(stru
+ list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
+ if (cmd->device->sdev_target == my_cmd->device->sdev_target &&
+ cmd->device->lun == my_cmd->device->lun)
+- sas_eh_defer_cmd(cmd);
++ sas_eh_finish_cmd(cmd);
+ }
+ }
+
+@@ -630,12 +623,12 @@ static void sas_eh_handle_sas_errors(str
+ case TASK_IS_DONE:
+ SAS_DPRINTK("%s: task 0x%p is done\n", __func__,
+ task);
+- sas_eh_defer_cmd(cmd);
++ sas_eh_finish_cmd(cmd);
+ continue;
+ case TASK_IS_ABORTED:
+ SAS_DPRINTK("%s: task 0x%p is aborted\n",
+ __func__, task);
+- sas_eh_defer_cmd(cmd);
++ sas_eh_finish_cmd(cmd);
+ continue;
+ case TASK_IS_AT_LU:
+ SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task);
+@@ -646,7 +639,7 @@ static void sas_eh_handle_sas_errors(str
+ "recovered\n",
+ SAS_ADDR(task->dev),
+ cmd->device->lun);
+- sas_eh_defer_cmd(cmd);
++ sas_eh_finish_cmd(cmd);
+ sas_scsi_clear_queue_lu(work_q, cmd);
+ goto Again;
+ }
--- /dev/null
+From fa89adba1941e4f3b213399b81732a5c12fd9131 Mon Sep 17 00:00:00 2001
+From: Jens Remus <jremus@linux.ibm.com>
+Date: Thu, 3 May 2018 13:52:47 +0200
+Subject: scsi: zfcp: fix infinite iteration on ERP ready list
+
+From: Jens Remus <jremus@linux.ibm.com>
+
+commit fa89adba1941e4f3b213399b81732a5c12fd9131 upstream.
+
+zfcp_erp_adapter_reopen() schedules blocking of all of the adapter's
+rports via zfcp_scsi_schedule_rports_block() and enqueues a reopen
+adapter ERP action via zfcp_erp_action_enqueue(). Both are separately
+processed asynchronously and concurrently.
+
+Blocking of rports is done in a kworker by zfcp_scsi_rport_work(). It
+calls zfcp_scsi_rport_block(), which then traces a DBF REC "scpdely" via
+zfcp_dbf_rec_trig(). zfcp_dbf_rec_trig() acquires the DBF REC spin lock
+and then iterates with list_for_each() over the adapter's ERP ready list
+without holding the ERP lock. This opens a race window in which the
+current list entry can be moved to another list, causing list_for_each()
+to iterate forever on the wrong list, as the erp_ready_head is never
+encountered as terminal condition.
+
+Meanwhile the ERP action can be processed in the ERP thread by
+zfcp_erp_thread(). It calls zfcp_erp_strategy(), which acquires the ERP
+lock and then calls zfcp_erp_action_to_running() to move the ERP action
+from the ready to the running list. zfcp_erp_action_to_running() can
+move the ERP action using list_move() just during the aforementioned
+race window. It then traces a REC RUN "erator1" via zfcp_dbf_rec_run().
+zfcp_dbf_rec_run() tries to acquire the DBF REC spin lock. If this is
+held by the infinitely looping kworker, it effectively spins forever.
+
+Example Sequence Diagram:
+
+Process ERP Thread rport_work
+------------------- ------------------- -------------------
+zfcp_erp_adapter_reopen()
+zfcp_erp_adapter_block()
+zfcp_scsi_schedule_rports_block()
+lock ERP zfcp_scsi_rport_work()
+zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER)
+list_add_tail() on ready !(rport_task==RPORT_ADD)
+wake_up() ERP thread zfcp_scsi_rport_block()
+zfcp_dbf_rec_trig() zfcp_erp_strategy() zfcp_dbf_rec_trig()
+unlock ERP lock DBF REC
+zfcp_erp_wait() lock ERP
+| zfcp_erp_action_to_running()
+| list_for_each() ready
+| list_move() current entry
+| ready to running
+| zfcp_dbf_rec_run() endless loop over running
+| zfcp_dbf_rec_run_lvl()
+| lock DBF REC spins forever
+
+Any adapter recovery can trigger this, such as setting the device offline
+or reboot.
+
+V4.9 commit 4eeaa4f3f1d6 ("zfcp: close window with unblocked rport
+during rport gone") introduced additional tracing of (un)blocking of
+rports. It missed that the adapter->erp_lock must be held when calling
+zfcp_dbf_rec_trig().
+
+This fix uses the approach formerly introduced by commit aa0fec62391c
+("[SCSI] zfcp: Fix sparse warning by providing new entry in dbf") that got
+later removed by commit ae0904f60fab ("[SCSI] zfcp: Redesign of the debug
+tracing for recovery actions.").
+
+Introduce zfcp_dbf_rec_trig_lock(), a wrapper for zfcp_dbf_rec_trig() that
+acquires and releases the adapter->erp_lock for read.
+
+Reported-by: Sebastian Ott <sebott@linux.ibm.com>
+Signed-off-by: Jens Remus <jremus@linux.ibm.com>
+Fixes: 4eeaa4f3f1d6 ("zfcp: close window with unblocked rport during rport gone")
+Cc: <stable@vger.kernel.org> # 2.6.32+
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Signed-off-by: Steffen Maier <maier@linux.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_dbf.c | 23 ++++++++++++++++++++++-
+ drivers/s390/scsi/zfcp_ext.h | 5 ++++-
+ drivers/s390/scsi/zfcp_scsi.c | 14 +++++++-------
+ 3 files changed, 33 insertions(+), 9 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.c
++++ b/drivers/s390/scsi/zfcp_dbf.c
+@@ -4,7 +4,7 @@
+ *
+ * Debug traces for zfcp.
+ *
+- * Copyright IBM Corp. 2002, 2017
++ * Copyright IBM Corp. 2002, 2018
+ */
+
+ #define KMSG_COMPONENT "zfcp"
+@@ -308,6 +308,27 @@ void zfcp_dbf_rec_trig(char *tag, struct
+ spin_unlock_irqrestore(&dbf->rec_lock, flags);
+ }
+
++/**
++ * zfcp_dbf_rec_trig_lock - trace event related to triggered recovery with lock
++ * @tag: identifier for event
++ * @adapter: adapter on which the erp_action should run
++ * @port: remote port involved in the erp_action
++ * @sdev: scsi device involved in the erp_action
++ * @want: wanted erp_action
++ * @need: required erp_action
++ *
++ * The adapter->erp_lock must not be held.
++ */
++void zfcp_dbf_rec_trig_lock(char *tag, struct zfcp_adapter *adapter,
++ struct zfcp_port *port, struct scsi_device *sdev,
++ u8 want, u8 need)
++{
++ unsigned long flags;
++
++ read_lock_irqsave(&adapter->erp_lock, flags);
++ zfcp_dbf_rec_trig(tag, adapter, port, sdev, want, need);
++ read_unlock_irqrestore(&adapter->erp_lock, flags);
++}
+
+ /**
+ * zfcp_dbf_rec_run_lvl - trace event related to running recovery
+--- a/drivers/s390/scsi/zfcp_ext.h
++++ b/drivers/s390/scsi/zfcp_ext.h
+@@ -4,7 +4,7 @@
+ *
+ * External function declarations.
+ *
+- * Copyright IBM Corp. 2002, 2016
++ * Copyright IBM Corp. 2002, 2018
+ */
+
+ #ifndef ZFCP_EXT_H
+@@ -35,6 +35,9 @@ extern int zfcp_dbf_adapter_register(str
+ extern void zfcp_dbf_adapter_unregister(struct zfcp_adapter *);
+ extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *,
+ struct zfcp_port *, struct scsi_device *, u8, u8);
++extern void zfcp_dbf_rec_trig_lock(char *tag, struct zfcp_adapter *adapter,
++ struct zfcp_port *port,
++ struct scsi_device *sdev, u8 want, u8 need);
+ extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *);
+ extern void zfcp_dbf_rec_run_lvl(int level, char *tag,
+ struct zfcp_erp_action *erp);
+--- a/drivers/s390/scsi/zfcp_scsi.c
++++ b/drivers/s390/scsi/zfcp_scsi.c
+@@ -4,7 +4,7 @@
+ *
+ * Interface to Linux SCSI midlayer.
+ *
+- * Copyright IBM Corp. 2002, 2017
++ * Copyright IBM Corp. 2002, 2018
+ */
+
+ #define KMSG_COMPONENT "zfcp"
+@@ -618,9 +618,9 @@ static void zfcp_scsi_rport_register(str
+ ids.port_id = port->d_id;
+ ids.roles = FC_RPORT_ROLE_FCP_TARGET;
+
+- zfcp_dbf_rec_trig("scpaddy", port->adapter, port, NULL,
+- ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD,
+- ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD);
++ zfcp_dbf_rec_trig_lock("scpaddy", port->adapter, port, NULL,
++ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD,
++ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD);
+ rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids);
+ if (!rport) {
+ dev_err(&port->adapter->ccw_device->dev,
+@@ -642,9 +642,9 @@ static void zfcp_scsi_rport_block(struct
+ struct fc_rport *rport = port->rport;
+
+ if (rport) {
+- zfcp_dbf_rec_trig("scpdely", port->adapter, port, NULL,
+- ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL,
+- ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL);
++ zfcp_dbf_rec_trig_lock("scpdely", port->adapter, port, NULL,
++ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL,
++ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL);
+ fc_remote_port_delete(rport);
+ port->rport = NULL;
+ }