]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 22 Sep 2017 10:15:32 +0000 (12:15 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 22 Sep 2017 10:15:32 +0000 (12:15 +0200)
added patches:
scsi-megaraid_sas-check-valid-aen-class-range-to-avoid-kernel-panic.patch
scsi-megaraid_sas-return-pended-ioctls-with-cmd_status-mfi_stat_wrong_state-in-case-adapter-is-dead.patch
scsi-megaraid_sas-set-minimum-value-of-resetwaittime-to-be-1-secs.patch
scsi-sg-factor-out-sg_fill_request_table.patch
scsi-sg-off-by-one-in-sg_ioctl.patch
scsi-sg-remove-save_scat_len.patch
scsi-sg-use-standard-lists-for-sg_requests.patch
scsi-storvsc-fix-memory-leak-on-ring-buffer-busy.patch
scsi-zfcp-add-handling-for-fcp_resid_over-to-the-fcp-ingress-path.patch
scsi-zfcp-fix-capping-of-unsuccessful-gpn_ft-san-response-trace-records.patch
scsi-zfcp-fix-missing-trace-records-for-early-returns-in-tmf-eh-handlers.patch
scsi-zfcp-fix-passing-fsf_req-to-scsi-trace-on-tmf-to-correlate-with-hba.patch
scsi-zfcp-fix-payload-with-full-fcp_rsp-iu-in-scsi-trace-records.patch
scsi-zfcp-fix-queuecommand-for-scsi_eh-commands-when-dix-enabled.patch
scsi-zfcp-trace-hba-fsf-response-by-default-on-dismiss-or-timedout-late-response.patch
scsi-zfcp-trace-high-part-of-new-64-bit-scsi-lun.patch
skd-avoid-that-module-unloading-triggers-a-use-after-free.patch
skd-submit-requests-to-firmware-before-triggering-the-doorbell.patch

19 files changed:
queue-4.9/scsi-megaraid_sas-check-valid-aen-class-range-to-avoid-kernel-panic.patch [new file with mode: 0644]
queue-4.9/scsi-megaraid_sas-return-pended-ioctls-with-cmd_status-mfi_stat_wrong_state-in-case-adapter-is-dead.patch [new file with mode: 0644]
queue-4.9/scsi-megaraid_sas-set-minimum-value-of-resetwaittime-to-be-1-secs.patch [new file with mode: 0644]
queue-4.9/scsi-sg-factor-out-sg_fill_request_table.patch [new file with mode: 0644]
queue-4.9/scsi-sg-off-by-one-in-sg_ioctl.patch [new file with mode: 0644]
queue-4.9/scsi-sg-remove-save_scat_len.patch [new file with mode: 0644]
queue-4.9/scsi-sg-use-standard-lists-for-sg_requests.patch [new file with mode: 0644]
queue-4.9/scsi-storvsc-fix-memory-leak-on-ring-buffer-busy.patch [new file with mode: 0644]
queue-4.9/scsi-zfcp-add-handling-for-fcp_resid_over-to-the-fcp-ingress-path.patch [new file with mode: 0644]
queue-4.9/scsi-zfcp-fix-capping-of-unsuccessful-gpn_ft-san-response-trace-records.patch [new file with mode: 0644]
queue-4.9/scsi-zfcp-fix-missing-trace-records-for-early-returns-in-tmf-eh-handlers.patch [new file with mode: 0644]
queue-4.9/scsi-zfcp-fix-passing-fsf_req-to-scsi-trace-on-tmf-to-correlate-with-hba.patch [new file with mode: 0644]
queue-4.9/scsi-zfcp-fix-payload-with-full-fcp_rsp-iu-in-scsi-trace-records.patch [new file with mode: 0644]
queue-4.9/scsi-zfcp-fix-queuecommand-for-scsi_eh-commands-when-dix-enabled.patch [new file with mode: 0644]
queue-4.9/scsi-zfcp-trace-hba-fsf-response-by-default-on-dismiss-or-timedout-late-response.patch [new file with mode: 0644]
queue-4.9/scsi-zfcp-trace-high-part-of-new-64-bit-scsi-lun.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/skd-avoid-that-module-unloading-triggers-a-use-after-free.patch [new file with mode: 0644]
queue-4.9/skd-submit-requests-to-firmware-before-triggering-the-doorbell.patch [new file with mode: 0644]

diff --git a/queue-4.9/scsi-megaraid_sas-check-valid-aen-class-range-to-avoid-kernel-panic.patch b/queue-4.9/scsi-megaraid_sas-check-valid-aen-class-range-to-avoid-kernel-panic.patch
new file mode 100644 (file)
index 0000000..954d0b4
--- /dev/null
@@ -0,0 +1,37 @@
+From 91b3d9f0069c8307d0b3a4c6843b65a439183318 Mon Sep 17 00:00:00 2001
+From: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
+Date: Wed, 23 Aug 2017 04:47:01 -0700
+Subject: scsi: megaraid_sas: Check valid aen class range to avoid kernel panic
+
+From: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
+
+commit 91b3d9f0069c8307d0b3a4c6843b65a439183318 upstream.
+
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Tomas Henzl <thenzl@redhat.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/megaraid/megaraid_sas_base.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/scsi/megaraid/megaraid_sas_base.c
++++ b/drivers/scsi/megaraid/megaraid_sas_base.c
+@@ -5460,6 +5460,14 @@ megasas_register_aen(struct megasas_inst
+               prev_aen.word =
+                       le32_to_cpu(instance->aen_cmd->frame->dcmd.mbox.w[1]);
++              if ((curr_aen.members.class < MFI_EVT_CLASS_DEBUG) ||
++                  (curr_aen.members.class > MFI_EVT_CLASS_DEAD)) {
++                      dev_info(&instance->pdev->dev,
++                               "%s %d out of range class %d send by application\n",
++                               __func__, __LINE__, curr_aen.members.class);
++                      return 0;
++              }
++
+               /*
+                * A class whose enum value is smaller is inclusive of all
+                * higher values. If a PROGRESS (= -1) was previously
diff --git a/queue-4.9/scsi-megaraid_sas-return-pended-ioctls-with-cmd_status-mfi_stat_wrong_state-in-case-adapter-is-dead.patch b/queue-4.9/scsi-megaraid_sas-return-pended-ioctls-with-cmd_status-mfi_stat_wrong_state-in-case-adapter-is-dead.patch
new file mode 100644 (file)
index 0000000..70f7a01
--- /dev/null
@@ -0,0 +1,40 @@
+From eb3fe263a48b0d27b229c213929c4cb3b1b39a0f Mon Sep 17 00:00:00 2001
+From: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
+Date: Wed, 23 Aug 2017 04:47:04 -0700
+Subject: scsi: megaraid_sas: Return pended IOCTLs with cmd_status MFI_STAT_WRONG_STATE in case adapter is dead
+
+From: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
+
+commit eb3fe263a48b0d27b229c213929c4cb3b1b39a0f upstream.
+
+After a kill adapter, since the cmd_status is not set, the IOCTLs will
+be hung in driver resulting in application hang.  Set cmd_status
+MFI_STAT_WRONG_STATE when completing pended IOCTLs.
+
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Tomas Henzl <thenzl@redhat.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/megaraid/megaraid_sas_base.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/scsi/megaraid/megaraid_sas_base.c
++++ b/drivers/scsi/megaraid/megaraid_sas_base.c
+@@ -1901,9 +1901,12 @@ static void megasas_complete_outstanding
+                       if (cmd_fusion->sync_cmd_idx != (u32)ULONG_MAX) {
+                               cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
+                               if (cmd_mfi->sync_cmd &&
+-                                      cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT)
++                                  (cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT)) {
++                                      cmd_mfi->frame->hdr.cmd_status =
++                                                      MFI_STAT_WRONG_STATE;
+                                       megasas_complete_cmd(instance,
+                                                            cmd_mfi, DID_OK);
++                              }
+                       }
+               }
+       } else {
diff --git a/queue-4.9/scsi-megaraid_sas-set-minimum-value-of-resetwaittime-to-be-1-secs.patch b/queue-4.9/scsi-megaraid_sas-set-minimum-value-of-resetwaittime-to-be-1-secs.patch
new file mode 100644 (file)
index 0000000..fe3ef61
--- /dev/null
@@ -0,0 +1,35 @@
+From e636a7a430f41efb0ff2727960ce61ef9f8f6769 Mon Sep 17 00:00:00 2001
+From: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
+Date: Wed, 23 Aug 2017 04:46:56 -0700
+Subject: scsi: megaraid_sas: set minimum value of resetwaittime to be 1 secs
+
+From: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
+
+commit e636a7a430f41efb0ff2727960ce61ef9f8f6769 upstream.
+
+Setting resetwaittime to 0 during a FW fault will result in driver not
+calling the OCR.
+
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Tomas Henzl <thenzl@redhat.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/megaraid/megaraid_sas_base.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/scsi/megaraid/megaraid_sas_base.c
++++ b/drivers/scsi/megaraid/megaraid_sas_base.c
+@@ -5290,7 +5290,8 @@ static int megasas_init_fw(struct megasa
+               instance->throttlequeuedepth =
+                               MEGASAS_THROTTLE_QUEUE_DEPTH;
+-      if (resetwaittime > MEGASAS_RESET_WAIT_TIME)
++      if ((resetwaittime < 1) ||
++          (resetwaittime > MEGASAS_RESET_WAIT_TIME))
+               resetwaittime = MEGASAS_RESET_WAIT_TIME;
+       if ((scmd_timeout < 10) || (scmd_timeout > MEGASAS_DEFAULT_CMD_TIMEOUT))
diff --git a/queue-4.9/scsi-sg-factor-out-sg_fill_request_table.patch b/queue-4.9/scsi-sg-factor-out-sg_fill_request_table.patch
new file mode 100644 (file)
index 0000000..8aa6a67
--- /dev/null
@@ -0,0 +1,106 @@
+From 4759df905a474d245752c9dc94288e779b8734dd Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Fri, 15 Sep 2017 14:05:15 +0200
+Subject: scsi: sg: factor out sg_fill_request_table()
+
+From: Hannes Reinecke <hare@suse.de>
+
+commit 4759df905a474d245752c9dc94288e779b8734dd upstream.
+
+Factor out sg_fill_request_table() for better readability.
+
+[mkp: typos, applied by hand]
+
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sg.c |   61 ++++++++++++++++++++++++++++++------------------------
+ 1 file changed, 35 insertions(+), 26 deletions(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -828,6 +828,40 @@ static int max_sectors_bytes(struct requ
+       return max_sectors << 9;
+ }
++static void
++sg_fill_request_table(Sg_fd *sfp, sg_req_info_t *rinfo)
++{
++      Sg_request *srp;
++      int val;
++      unsigned int ms;
++
++      val = 0;
++      list_for_each_entry(srp, &sfp->rq_list, entry) {
++              if (val > SG_MAX_QUEUE)
++                      break;
++              memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
++              rinfo[val].req_state = srp->done + 1;
++              rinfo[val].problem =
++                      srp->header.masked_status &
++                      srp->header.host_status &
++                      srp->header.driver_status;
++              if (srp->done)
++                      rinfo[val].duration =
++                              srp->header.duration;
++              else {
++                      ms = jiffies_to_msecs(jiffies);
++                      rinfo[val].duration =
++                              (ms > srp->header.duration) ?
++                              (ms - srp->header.duration) : 0;
++              }
++              rinfo[val].orphan = srp->orphan;
++              rinfo[val].sg_io_owned = srp->sg_io_owned;
++              rinfo[val].pack_id = srp->header.pack_id;
++              rinfo[val].usr_ptr = srp->header.usr_ptr;
++              val++;
++      }
++}
++
+ static long
+ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
+ {
+@@ -1022,38 +1056,13 @@ sg_ioctl(struct file *filp, unsigned int
+                       return -EFAULT;
+               else {
+                       sg_req_info_t *rinfo;
+-                      unsigned int ms;
+                       rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE,
+                                                               GFP_KERNEL);
+                       if (!rinfo)
+                               return -ENOMEM;
+                       read_lock_irqsave(&sfp->rq_list_lock, iflags);
+-                      val = 0;
+-                      list_for_each_entry(srp, &sfp->rq_list, entry) {
+-                              if (val >= SG_MAX_QUEUE)
+-                                      break;
+-                              memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
+-                              rinfo[val].req_state = srp->done + 1;
+-                              rinfo[val].problem =
+-                                      srp->header.masked_status &
+-                                      srp->header.host_status &
+-                                      srp->header.driver_status;
+-                              if (srp->done)
+-                                      rinfo[val].duration =
+-                                              srp->header.duration;
+-                              else {
+-                                      ms = jiffies_to_msecs(jiffies);
+-                                      rinfo[val].duration =
+-                                              (ms > srp->header.duration) ?
+-                                              (ms - srp->header.duration) : 0;
+-                              }
+-                              rinfo[val].orphan = srp->orphan;
+-                              rinfo[val].sg_io_owned = srp->sg_io_owned;
+-                              rinfo[val].pack_id = srp->header.pack_id;
+-                              rinfo[val].usr_ptr = srp->header.usr_ptr;
+-                              val++;
+-                      }
++                      sg_fill_request_table(sfp, rinfo);
+                       read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+                       result = __copy_to_user(p, rinfo,
+                                               SZ_SG_REQ_INFO * SG_MAX_QUEUE);
diff --git a/queue-4.9/scsi-sg-off-by-one-in-sg_ioctl.patch b/queue-4.9/scsi-sg-off-by-one-in-sg_ioctl.patch
new file mode 100644 (file)
index 0000000..e3b6760
--- /dev/null
@@ -0,0 +1,33 @@
+From bd46fc406b30d1db1aff8dabaff8d18bb423fdcf Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Thu, 17 Aug 2017 10:09:54 +0300
+Subject: scsi: sg: off by one in sg_ioctl()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit bd46fc406b30d1db1aff8dabaff8d18bb423fdcf upstream.
+
+If "val" is SG_MAX_QUEUE then we are one element beyond the end of the
+"rinfo" array so the > should be >=.
+
+Fixes: 109bade9c625 ("scsi: sg: use standard lists for sg_requests")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sg.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -1031,7 +1031,7 @@ sg_ioctl(struct file *filp, unsigned int
+                       read_lock_irqsave(&sfp->rq_list_lock, iflags);
+                       val = 0;
+                       list_for_each_entry(srp, &sfp->rq_list, entry) {
+-                              if (val > SG_MAX_QUEUE)
++                              if (val >= SG_MAX_QUEUE)
+                                       break;
+                               memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
+                               rinfo[val].req_state = srp->done + 1;
diff --git a/queue-4.9/scsi-sg-remove-save_scat_len.patch b/queue-4.9/scsi-sg-remove-save_scat_len.patch
new file mode 100644 (file)
index 0000000..9b232d7
--- /dev/null
@@ -0,0 +1,40 @@
+From 136e57bf43dc4babbfb8783abbf707d483cacbe3 Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Fri, 7 Apr 2017 09:34:13 +0200
+Subject: scsi: sg: remove 'save_scat_len'
+
+From: Hannes Reinecke <hare@suse.de>
+
+commit 136e57bf43dc4babbfb8783abbf707d483cacbe3 upstream.
+
+Unused.
+
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
+Tested-by: Johannes Thumshirn <jthumshirn@suse.de>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sg.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -146,7 +146,6 @@ typedef struct sg_fd {             /* holds the sta
+       int timeout;            /* defaults to SG_DEFAULT_TIMEOUT      */
+       int timeout_user;       /* defaults to SG_DEFAULT_TIMEOUT_USER */
+       Sg_scatter_hold reserve;        /* buffer held for this file descriptor */
+-      unsigned save_scat_len; /* original length of trunc. scat. element */
+       Sg_request *headrp;     /* head of request slist, NULL->empty */
+       struct fasync_struct *async_qp; /* used by asynchronous notification */
+       Sg_request req_arr[SG_MAX_QUEUE];       /* used as singly-linked list */
+@@ -2049,7 +2048,6 @@ sg_unlink_reserve(Sg_fd * sfp, Sg_reques
+       req_schp->pages = NULL;
+       req_schp->page_order = 0;
+       req_schp->sglist_len = 0;
+-      sfp->save_scat_len = 0;
+       srp->res_used = 0;
+       /* Called without mutex lock to avoid deadlock */
+       sfp->res_in_use = 0;
diff --git a/queue-4.9/scsi-sg-use-standard-lists-for-sg_requests.patch b/queue-4.9/scsi-sg-use-standard-lists-for-sg_requests.patch
new file mode 100644 (file)
index 0000000..f209c6f
--- /dev/null
@@ -0,0 +1,290 @@
+From 109bade9c625c89bb5ea753aaa1a0a97e6fbb548 Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Fri, 7 Apr 2017 09:34:16 +0200
+Subject: scsi: sg: use standard lists for sg_requests
+
+From: Hannes Reinecke <hare@suse.de>
+
+commit 109bade9c625c89bb5ea753aaa1a0a97e6fbb548 upstream.
+
+'Sg_request' is using a private list implementation; convert it to
+standard lists.
+
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
+Tested-by: Johannes Thumshirn <jthumshirn@suse.de>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sg.c |  147 ++++++++++++++++++++++--------------------------------
+ 1 file changed, 61 insertions(+), 86 deletions(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -122,7 +122,7 @@ struct sg_device;          /* forward declaratio
+ struct sg_fd;
+ typedef struct sg_request {   /* SG_MAX_QUEUE requests outstanding per file */
+-      struct sg_request *nextrp;      /* NULL -> tail request (slist) */
++      struct list_head entry; /* list entry */
+       struct sg_fd *parentfp; /* NULL -> not in use */
+       Sg_scatter_hold data;   /* hold buffer, perhaps scatter list */
+       sg_io_hdr_t header;     /* scsi command+info, see <scsi/sg.h> */
+@@ -146,7 +146,7 @@ typedef struct sg_fd {             /* holds the sta
+       int timeout;            /* defaults to SG_DEFAULT_TIMEOUT      */
+       int timeout_user;       /* defaults to SG_DEFAULT_TIMEOUT_USER */
+       Sg_scatter_hold reserve;        /* buffer held for this file descriptor */
+-      Sg_request *headrp;     /* head of request slist, NULL->empty */
++      struct list_head rq_list; /* head of request list */
+       struct fasync_struct *async_qp; /* used by asynchronous notification */
+       Sg_request req_arr[SG_MAX_QUEUE];       /* used as singly-linked list */
+       char low_dma;           /* as in parent but possibly overridden to 1 */
+@@ -940,7 +940,7 @@ sg_ioctl(struct file *filp, unsigned int
+               if (!access_ok(VERIFY_WRITE, ip, sizeof (int)))
+                       return -EFAULT;
+               read_lock_irqsave(&sfp->rq_list_lock, iflags);
+-              for (srp = sfp->headrp; srp; srp = srp->nextrp) {
++              list_for_each_entry(srp, &sfp->rq_list, entry) {
+                       if ((1 == srp->done) && (!srp->sg_io_owned)) {
+                               read_unlock_irqrestore(&sfp->rq_list_lock,
+                                                      iflags);
+@@ -953,7 +953,8 @@ sg_ioctl(struct file *filp, unsigned int
+               return 0;
+       case SG_GET_NUM_WAITING:
+               read_lock_irqsave(&sfp->rq_list_lock, iflags);
+-              for (val = 0, srp = sfp->headrp; srp; srp = srp->nextrp) {
++              val = 0;
++              list_for_each_entry(srp, &sfp->rq_list, entry) {
+                       if ((1 == srp->done) && (!srp->sg_io_owned))
+                               ++val;
+               }
+@@ -1028,35 +1029,33 @@ sg_ioctl(struct file *filp, unsigned int
+                       if (!rinfo)
+                               return -ENOMEM;
+                       read_lock_irqsave(&sfp->rq_list_lock, iflags);
+-                      for (srp = sfp->headrp, val = 0; val < SG_MAX_QUEUE;
+-                           ++val, srp = srp ? srp->nextrp : srp) {
++                      val = 0;
++                      list_for_each_entry(srp, &sfp->rq_list, entry) {
++                              if (val > SG_MAX_QUEUE)
++                                      break;
+                               memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
+-                              if (srp) {
+-                                      rinfo[val].req_state = srp->done + 1;
+-                                      rinfo[val].problem =
+-                                          srp->header.masked_status & 
+-                                          srp->header.host_status & 
+-                                          srp->header.driver_status;
+-                                      if (srp->done)
+-                                              rinfo[val].duration =
+-                                                      srp->header.duration;
+-                                      else {
+-                                              ms = jiffies_to_msecs(jiffies);
+-                                              rinfo[val].duration =
+-                                                  (ms > srp->header.duration) ?
+-                                                  (ms - srp->header.duration) : 0;
+-                                      }
+-                                      rinfo[val].orphan = srp->orphan;
+-                                      rinfo[val].sg_io_owned =
+-                                                      srp->sg_io_owned;
+-                                      rinfo[val].pack_id =
+-                                                      srp->header.pack_id;
+-                                      rinfo[val].usr_ptr =
+-                                                      srp->header.usr_ptr;
++                              rinfo[val].req_state = srp->done + 1;
++                              rinfo[val].problem =
++                                      srp->header.masked_status &
++                                      srp->header.host_status &
++                                      srp->header.driver_status;
++                              if (srp->done)
++                                      rinfo[val].duration =
++                                              srp->header.duration;
++                              else {
++                                      ms = jiffies_to_msecs(jiffies);
++                                      rinfo[val].duration =
++                                              (ms > srp->header.duration) ?
++                                              (ms - srp->header.duration) : 0;
+                               }
++                              rinfo[val].orphan = srp->orphan;
++                              rinfo[val].sg_io_owned = srp->sg_io_owned;
++                              rinfo[val].pack_id = srp->header.pack_id;
++                              rinfo[val].usr_ptr = srp->header.usr_ptr;
++                              val++;
+                       }
+                       read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+-                      result = __copy_to_user(p, rinfo, 
++                      result = __copy_to_user(p, rinfo,
+                                               SZ_SG_REQ_INFO * SG_MAX_QUEUE);
+                       result = result ? -EFAULT : 0;
+                       kfree(rinfo);
+@@ -1162,7 +1161,7 @@ sg_poll(struct file *filp, poll_table *
+               return POLLERR;
+       poll_wait(filp, &sfp->read_wait, wait);
+       read_lock_irqsave(&sfp->rq_list_lock, iflags);
+-      for (srp = sfp->headrp; srp; srp = srp->nextrp) {
++      list_for_each_entry(srp, &sfp->rq_list, entry) {
+               /* if any read waiting, flag it */
+               if ((0 == res) && (1 == srp->done) && (!srp->sg_io_owned))
+                       res = POLLIN | POLLRDNORM;
+@@ -2060,7 +2059,7 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
+       unsigned long iflags;
+       write_lock_irqsave(&sfp->rq_list_lock, iflags);
+-      for (resp = sfp->headrp; resp; resp = resp->nextrp) {
++      list_for_each_entry(resp, &sfp->rq_list, entry) {
+               /* look for requests that are ready + not SG_IO owned */
+               if ((1 == resp->done) && (!resp->sg_io_owned) &&
+                   ((-1 == pack_id) || (resp->header.pack_id == pack_id))) {
+@@ -2078,70 +2077,45 @@ sg_add_request(Sg_fd * sfp)
+ {
+       int k;
+       unsigned long iflags;
+-      Sg_request *resp;
+       Sg_request *rp = sfp->req_arr;
+       write_lock_irqsave(&sfp->rq_list_lock, iflags);
+-      resp = sfp->headrp;
+-      if (!resp) {
+-              memset(rp, 0, sizeof (Sg_request));
+-              rp->parentfp = sfp;
+-              resp = rp;
+-              sfp->headrp = resp;
+-      } else {
+-              if (0 == sfp->cmd_q)
+-                      resp = NULL;    /* command queuing disallowed */
+-              else {
+-                      for (k = 0; k < SG_MAX_QUEUE; ++k, ++rp) {
+-                              if (!rp->parentfp)
+-                                      break;
+-                      }
+-                      if (k < SG_MAX_QUEUE) {
+-                              memset(rp, 0, sizeof (Sg_request));
+-                              rp->parentfp = sfp;
+-                              while (resp->nextrp)
+-                                      resp = resp->nextrp;
+-                              resp->nextrp = rp;
+-                              resp = rp;
+-                      } else
+-                              resp = NULL;
++      if (!list_empty(&sfp->rq_list)) {
++              if (!sfp->cmd_q)
++                      goto out_unlock;
++
++              for (k = 0; k < SG_MAX_QUEUE; ++k, ++rp) {
++                      if (!rp->parentfp)
++                              break;
+               }
++              if (k >= SG_MAX_QUEUE)
++                      goto out_unlock;
+       }
+-      if (resp) {
+-              resp->nextrp = NULL;
+-              resp->header.duration = jiffies_to_msecs(jiffies);
+-      }
++      memset(rp, 0, sizeof (Sg_request));
++      rp->parentfp = sfp;
++      rp->header.duration = jiffies_to_msecs(jiffies);
++      list_add_tail(&rp->entry, &sfp->rq_list);
+       write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+-      return resp;
++      return rp;
++out_unlock:
++      write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
++      return NULL;
+ }
+ /* Return of 1 for found; 0 for not found */
+ static int
+ sg_remove_request(Sg_fd * sfp, Sg_request * srp)
+ {
+-      Sg_request *prev_rp;
+-      Sg_request *rp;
+       unsigned long iflags;
+       int res = 0;
+-      if ((!sfp) || (!srp) || (!sfp->headrp))
++      if (!sfp || !srp || list_empty(&sfp->rq_list))
+               return res;
+       write_lock_irqsave(&sfp->rq_list_lock, iflags);
+-      prev_rp = sfp->headrp;
+-      if (srp == prev_rp) {
+-              sfp->headrp = prev_rp->nextrp;
+-              prev_rp->parentfp = NULL;
++      if (!list_empty(&srp->entry)) {
++              list_del(&srp->entry);
++              srp->parentfp = NULL;
+               res = 1;
+-      } else {
+-              while ((rp = prev_rp->nextrp)) {
+-                      if (srp == rp) {
+-                              prev_rp->nextrp = rp->nextrp;
+-                              rp->parentfp = NULL;
+-                              res = 1;
+-                              break;
+-                      }
+-                      prev_rp = rp;
+-              }
+       }
+       write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+       return res;
+@@ -2160,7 +2134,7 @@ sg_add_sfp(Sg_device * sdp)
+       init_waitqueue_head(&sfp->read_wait);
+       rwlock_init(&sfp->rq_list_lock);
+-
++      INIT_LIST_HEAD(&sfp->rq_list);
+       kref_init(&sfp->f_ref);
+       mutex_init(&sfp->f_mutex);
+       sfp->timeout = SG_DEFAULT_TIMEOUT;
+@@ -2201,10 +2175,13 @@ sg_remove_sfp_usercontext(struct work_st
+ {
+       struct sg_fd *sfp = container_of(work, struct sg_fd, ew.work);
+       struct sg_device *sdp = sfp->parentdp;
++      Sg_request *srp;
+       /* Cleanup any responses which were never read(). */
+-      while (sfp->headrp)
+-              sg_finish_rem_req(sfp->headrp);
++      while (!list_empty(&sfp->rq_list)) {
++              srp = list_first_entry(&sfp->rq_list, Sg_request, entry);
++              sg_finish_rem_req(srp);
++      }
+       if (sfp->reserve.bufflen > 0) {
+               SCSI_LOG_TIMEOUT(6, sg_printk(KERN_INFO, sdp,
+@@ -2607,7 +2584,7 @@ static int sg_proc_seq_show_devstrs(stru
+ /* must be called while holding sg_index_lock */
+ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
+ {
+-      int k, m, new_interface, blen, usg;
++      int k, new_interface, blen, usg;
+       Sg_request *srp;
+       Sg_fd *fp;
+       const sg_io_hdr_t *hp;
+@@ -2627,13 +2604,11 @@ static void sg_proc_debug_helper(struct
+               seq_printf(s, "   cmd_q=%d f_packid=%d k_orphan=%d closed=0\n",
+                          (int) fp->cmd_q, (int) fp->force_packid,
+                          (int) fp->keep_orphan);
+-              for (m = 0, srp = fp->headrp;
+-                              srp != NULL;
+-                              ++m, srp = srp->nextrp) {
++              list_for_each_entry(srp, &fp->rq_list, entry) {
+                       hp = &srp->header;
+                       new_interface = (hp->interface_id == '\0') ? 0 : 1;
+                       if (srp->res_used) {
+-                              if (new_interface && 
++                              if (new_interface &&
+                                   (SG_FLAG_MMAP_IO & hp->flags))
+                                       cp = "     mmap>> ";
+                               else
+@@ -2664,7 +2639,7 @@ static void sg_proc_debug_helper(struct
+                       seq_printf(s, "ms sgat=%d op=0x%02x\n", usg,
+                                  (int) srp->data.cmd_opcode);
+               }
+-              if (0 == m)
++              if (list_empty(&fp->rq_list))
+                       seq_puts(s, "     No requests active\n");
+               read_unlock(&fp->rq_list_lock);
+       }
diff --git a/queue-4.9/scsi-storvsc-fix-memory-leak-on-ring-buffer-busy.patch b/queue-4.9/scsi-storvsc-fix-memory-leak-on-ring-buffer-busy.patch
new file mode 100644 (file)
index 0000000..93f8228
--- /dev/null
@@ -0,0 +1,38 @@
+From 0208eeaa650c5c866a3242201678a19e6dc4a14e Mon Sep 17 00:00:00 2001
+From: Long Li <longli@microsoft.com>
+Date: Mon, 28 Aug 2017 17:43:59 -0700
+Subject: scsi: storvsc: fix memory leak on ring buffer busy
+
+From: Long Li <longli@microsoft.com>
+
+commit 0208eeaa650c5c866a3242201678a19e6dc4a14e upstream.
+
+When storvsc is sending I/O to Hyper-v, it may allocate a bigger buffer
+descriptor for large data payload that can't fit into a pre-allocated
+buffer descriptor. This bigger buffer is freed on return path.
+
+If I/O request to Hyper-v fails due to ring buffer busy, the storvsc
+allocated buffer descriptor should also be freed.
+
+[mkp: applied by hand]
+
+Fixes: be0cf6ca301c ("scsi: storvsc: Set the tablesize based on the information given by the host")
+Signed-off-by: Long Li <longli@microsoft.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/storvsc_drv.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -1559,6 +1559,8 @@ static int storvsc_queuecommand(struct S
+       ret = storvsc_do_io(dev, cmd_request);
+       if (ret == -EAGAIN) {
++              if (payload_sz > sizeof(cmd_request->mpb))
++                      kfree(payload);
+               /* no more space */
+               return SCSI_MLQUEUE_DEVICE_BUSY;
+       }
diff --git a/queue-4.9/scsi-zfcp-add-handling-for-fcp_resid_over-to-the-fcp-ingress-path.patch b/queue-4.9/scsi-zfcp-add-handling-for-fcp_resid_over-to-the-fcp-ingress-path.patch
new file mode 100644 (file)
index 0000000..db1ab46
--- /dev/null
@@ -0,0 +1,90 @@
+From a099b7b1fc1f0418ab8d79ecf98153e1e134656e Mon Sep 17 00:00:00 2001
+From: Benjamin Block <bblock@linux.vnet.ibm.com>
+Date: Fri, 28 Jul 2017 12:30:52 +0200
+Subject: scsi: zfcp: add handling for FCP_RESID_OVER to the fcp ingress path
+
+From: Benjamin Block <bblock@linux.vnet.ibm.com>
+
+commit a099b7b1fc1f0418ab8d79ecf98153e1e134656e upstream.
+
+Up until now zfcp would just ignore the FCP_RESID_OVER flag in the FCP
+response IU. When this flag is set, it is possible, in regards to the
+FCP standard, that the storage-server processes the command normally, up
+to the point where data is missing and simply ignores those.
+
+In this case no CHECK CONDITION would be set, and because we ignored the
+FCP_RESID_OVER flag we resulted in at least a data loss or even
+-corruption as a follow-up error, depending on how the
+applications/layers on top behave. To prevent this, we now set the
+host-byte of the corresponding scsi_cmnd to DID_ERROR.
+
+Other storage-behaviors, where the same condition results in a CHECK
+CONDITION set in the answer, don't need to be changed as they are
+handled in the mid-layer already.
+
+Following is an example trace record decoded with zfcpdbf from the
+s390-tools package. We forcefully injected a fc_dl which is one byte too
+small:
+
+Timestamp      : ...
+Area           : SCSI
+Subarea        : 00
+Level          : 3
+Exception      : -
+CPU ID         : ..
+Caller         : 0x...
+Record ID      : 1
+Tag            : rsl_err
+Request ID     : 0x...
+SCSI ID        : 0x...
+SCSI LUN       : 0x...
+SCSI result    : 0x00070000
+                     ^^DID_ERROR
+SCSI retries   : 0x..
+SCSI allowed   : 0x..
+SCSI scribble  : 0x...
+SCSI opcode    : 2a000000 00000000 08000000 00000000
+FCP rsp inf cod: 0x00
+FCP rsp IU     : 00000000 00000000 00000400 00000001
+                                       ^^fr_flags==FCP_RESID_OVER
+                                         ^^fr_status==SAM_STAT_GOOD
+                                            ^^^^^^^^fr_resid
+                 00000000 00000000
+
+As of now, we don't actively handle to possibility that a response IU
+has both flags - FCP_RESID_OVER and FCP_RESID_UNDER - set at once.
+
+Reported-by: Luke M. Hopkins <lmhopkin@us.ibm.com>
+Reviewed-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: 553448f6c483 ("[SCSI] zfcp: Message cleanup")
+Fixes: ea127f975424 ("[PATCH] s390 (7/7): zfcp host adapter.") (tglx/history.git)
+Signed-off-by: Benjamin Block <bblock@linux.vnet.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_fc.h |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/s390/scsi/zfcp_fc.h
++++ b/drivers/s390/scsi/zfcp_fc.h
+@@ -4,7 +4,7 @@
+  * Fibre Channel related definitions and inline functions for the zfcp
+  * device driver
+  *
+- * Copyright IBM Corp. 2009
++ * Copyright IBM Corp. 2009, 2017
+  */
+ #ifndef ZFCP_FC_H
+@@ -279,6 +279,10 @@ void zfcp_fc_eval_fcp_rsp(struct fcp_res
+                    !(rsp_flags & FCP_SNS_LEN_VAL) &&
+                    fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
+                       set_host_byte(scsi, DID_ERROR);
++      } else if (unlikely(rsp_flags & FCP_RESID_OVER)) {
++              /* FCP_DL was not sufficient for SCSI data length */
++              if (fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
++                      set_host_byte(scsi, DID_ERROR);
+       }
+ }
diff --git a/queue-4.9/scsi-zfcp-fix-capping-of-unsuccessful-gpn_ft-san-response-trace-records.patch b/queue-4.9/scsi-zfcp-fix-capping-of-unsuccessful-gpn_ft-san-response-trace-records.patch
new file mode 100644 (file)
index 0000000..41c2ddc
--- /dev/null
@@ -0,0 +1,149 @@
+From 975171b4461be296a35e83ebd748946b81cf0635 Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Fri, 28 Jul 2017 12:30:53 +0200
+Subject: scsi: zfcp: fix capping of unsuccessful GPN_FT SAN response trace records
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit 975171b4461be296a35e83ebd748946b81cf0635 upstream.
+
+v4.9 commit aceeffbb59bb ("zfcp: trace full payload of all SAN records
+(req,resp,iels)") fixed trace data loss of 2.6.38 commit 2c55b750a884
+("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
+necessary for problem determination, e.g. to see the
+currently active zone set during automatic port scan.
+
+While it already saves space by not dumping any empty residual entries
+of the large successful GPN_FT response (4 pages), there are seldom cases
+where the GPN_FT response is unsuccessful and likely does not have
+FC_NS_FID_LAST set in fp_flags so we did not cap the trace record.
+We typically see such case for an initiator WWPN, which is not in any zone.
+
+Cap unsuccessful responses to at least the actual basic CT_IU response
+plus whatever fits the SAN trace record built-in "payload" buffer
+just in case there's trailing information
+of which we would at least see the existence and its beginning.
+
+In order not to erroneously cap successful responses, we need to swap
+calling the trace function and setting the CT / ELS status to success (0).
+
+Example trace record pair formatted with zfcpdbf:
+
+Timestamp      : ...
+Area           : SAN
+Subarea        : 00
+Level          : 1
+Exception      : -
+CPU ID         : ..
+Caller         : 0x...
+Record ID      : 1
+Tag            : fssct_1
+Request ID     : 0x<request_id>
+Destination ID : 0x00fffffc
+SAN req short  : 01000000 fc020000 01720ffc 00000000
+                 00000008
+SAN req length : 20
+|
+Timestamp      : ...
+Area           : SAN
+Subarea        : 00
+Level          : 1
+Exception      : -
+CPU ID         : ..
+Caller         : 0x...
+Record ID      : 2
+Tag            : fsscth2
+Request ID     : 0x<request_id>
+Destination ID : 0x00fffffc
+SAN resp short : 01000000 fc020000 80010000 00090700
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+SAN resp length: 16384
+San resp info  : 01000000 fc020000 80010000 00090700
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+                 00000000 00000000 00000000 00000000 [trailing info]
+
+The fix saves all but one of the previously associated 64 PAYload trace
+record chunks of size 256 bytes each.
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: aceeffbb59bb ("zfcp: trace full payload of all SAN records (req,resp,iels)")
+Fixes: 2c55b750a884 ("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Block <bblock@linux.vnet.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 |   10 +++++++++-
+ drivers/s390/scsi/zfcp_fsf.c |    4 ++--
+ 2 files changed, 11 insertions(+), 3 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.c
++++ b/drivers/s390/scsi/zfcp_dbf.c
+@@ -3,7 +3,7 @@
+  *
+  * Debug traces for zfcp.
+  *
+- * Copyright IBM Corp. 2002, 2016
++ * Copyright IBM Corp. 2002, 2017
+  */
+ #define KMSG_COMPONENT "zfcp"
+@@ -447,6 +447,7 @@ static u16 zfcp_dbf_san_res_cap_len_if_g
+       struct fc_ct_hdr *reqh = sg_virt(ct_els->req);
+       struct fc_ns_gid_ft *reqn = (struct fc_ns_gid_ft *)(reqh + 1);
+       struct scatterlist *resp_entry = ct_els->resp;
++      struct fc_ct_hdr *resph;
+       struct fc_gpn_ft_resp *acc;
+       int max_entries, x, last = 0;
+@@ -473,6 +474,13 @@ static u16 zfcp_dbf_san_res_cap_len_if_g
+               return len; /* not GPN_FT response so do not cap */
+       acc = sg_virt(resp_entry);
++
++      /* cap all but accept CT responses to at least the CT header */
++      resph = (struct fc_ct_hdr *)acc;
++      if ((ct_els->status) ||
++          (resph->ct_cmd != cpu_to_be16(FC_FS_ACC)))
++              return max(FC_CT_HDR_LEN, ZFCP_DBF_SAN_MAX_PAYLOAD);
++
+       max_entries = (reqh->ct_mr_size * 4 / sizeof(struct fc_gpn_ft_resp))
+               + 1 /* zfcp_fc_scan_ports: bytes correct, entries off-by-one
+                    * to account for header as 1st pseudo "entry" */;
+--- a/drivers/s390/scsi/zfcp_fsf.c
++++ b/drivers/s390/scsi/zfcp_fsf.c
+@@ -928,8 +928,8 @@ static void zfcp_fsf_send_ct_handler(str
+       switch (header->fsf_status) {
+         case FSF_GOOD:
+-              zfcp_dbf_san_res("fsscth2", req);
+               ct->status = 0;
++              zfcp_dbf_san_res("fsscth2", req);
+               break;
+         case FSF_SERVICE_CLASS_NOT_SUPPORTED:
+               zfcp_fsf_class_not_supp(req);
+@@ -1109,8 +1109,8 @@ static void zfcp_fsf_send_els_handler(st
+       switch (header->fsf_status) {
+       case FSF_GOOD:
+-              zfcp_dbf_san_res("fsselh1", req);
+               send_els->status = 0;
++              zfcp_dbf_san_res("fsselh1", req);
+               break;
+       case FSF_SERVICE_CLASS_NOT_SUPPORTED:
+               zfcp_fsf_class_not_supp(req);
diff --git a/queue-4.9/scsi-zfcp-fix-missing-trace-records-for-early-returns-in-tmf-eh-handlers.patch b/queue-4.9/scsi-zfcp-fix-missing-trace-records-for-early-returns-in-tmf-eh-handlers.patch
new file mode 100644 (file)
index 0000000..357b96b
--- /dev/null
@@ -0,0 +1,62 @@
+From 1a5d999ebfc7bfe28deb48931bb57faa8e4102b6 Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Fri, 28 Jul 2017 12:30:55 +0200
+Subject: scsi: zfcp: fix missing trace records for early returns in TMF eh handlers
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit 1a5d999ebfc7bfe28deb48931bb57faa8e4102b6 upstream.
+
+For problem determination we need to see that we were in scsi_eh
+as well as whether and why we were successful or not.
+
+The following commits introduced new early returns without adding
+a trace record:
+
+v2.6.35 commit a1dbfddd02d2
+("[SCSI] zfcp: Pass return code from fc_block_scsi_eh to scsi eh")
+on fc_block_scsi_eh() returning != 0 which is FAST_IO_FAIL,
+
+v2.6.30 commit 63caf367e1c9
+("[SCSI] zfcp: Improve reliability of SCSI eh handlers in zfcp")
+on not having gotten an FSF request after the maximum number of retry
+attempts and thus could not issue a TMF and has to return FAILED.
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: a1dbfddd02d2 ("[SCSI] zfcp: Pass return code from fc_block_scsi_eh to scsi eh")
+Fixes: 63caf367e1c9 ("[SCSI] zfcp: Improve reliability of SCSI eh handlers in zfcp")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Block <bblock@linux.vnet.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_scsi.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_scsi.c
++++ b/drivers/s390/scsi/zfcp_scsi.c
+@@ -273,8 +273,10 @@ static int zfcp_task_mgmt_function(struc
+               zfcp_erp_wait(adapter);
+               ret = fc_block_scsi_eh(scpnt);
+-              if (ret)
++              if (ret) {
++                      zfcp_dbf_scsi_devreset("fiof", scpnt, tm_flags, NULL);
+                       return ret;
++              }
+               if (!(atomic_read(&adapter->status) &
+                     ZFCP_STATUS_COMMON_RUNNING)) {
+@@ -282,8 +284,10 @@ static int zfcp_task_mgmt_function(struc
+                       return SUCCESS;
+               }
+       }
+-      if (!fsf_req)
++      if (!fsf_req) {
++              zfcp_dbf_scsi_devreset("reqf", scpnt, tm_flags, NULL);
+               return FAILED;
++      }
+       wait_for_completion(&fsf_req->completion);
diff --git a/queue-4.9/scsi-zfcp-fix-passing-fsf_req-to-scsi-trace-on-tmf-to-correlate-with-hba.patch b/queue-4.9/scsi-zfcp-fix-passing-fsf_req-to-scsi-trace-on-tmf-to-correlate-with-hba.patch
new file mode 100644 (file)
index 0000000..ba88a76
--- /dev/null
@@ -0,0 +1,136 @@
+From 9fe5d2b2fd30aa8c7827ec62cbbe6d30df4fe3e3 Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Fri, 28 Jul 2017 12:30:54 +0200
+Subject: scsi: zfcp: fix passing fsf_req to SCSI trace on TMF to correlate with HBA
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit 9fe5d2b2fd30aa8c7827ec62cbbe6d30df4fe3e3 upstream.
+
+Without this fix we get SCSI trace records on task management functions
+which cannot be correlated to HBA trace records because all fields
+related to the FSF request are empty (zero).
+Also, the FCP_RSP_IU is missing as well as any sense data if available.
+
+This was caused by v2.6.14 commit 8a36e4532ea1 ("[SCSI] zfcp: enhancement
+of zfcp debug features") introducing trace records for TMFs but
+hard coding NULL for a possibly existing TMF FSF request.
+The scsi_cmnd scribble is also zero or unrelated for the TMF request
+so it also could not lookup a suitable FSF request from there.
+
+A broken example trace record formatted with zfcpdbf from the s390-tools
+package:
+
+Timestamp      : ...
+Area           : SCSI
+Subarea        : 00
+Level          : 1
+Exception      : -
+CPU ID         : ..
+Caller         : 0x...
+Record ID      : 1
+Tag            : lr_fail
+Request ID     : 0x0000000000000000
+                   ^^^^^^^^^^^^^^^^ no correlation to HBA record
+SCSI ID        : 0x<scsitarget>
+SCSI LUN       : 0x<scsilun>
+SCSI result    : 0x000e0000
+SCSI retries   : 0x00
+SCSI allowed   : 0x05
+SCSI scribble  : 0x0000000000000000
+SCSI opcode    : 2a000017 3bb80000 08000000 00000000
+FCP rsp inf cod: 0x00
+                   ^^ no TMF response
+FCP rsp IU     : 00000000 00000000 00000000 00000000
+                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+                 00000000 00000000
+                 ^^^^^^^^^^^^^^^^^ no interesting FCP_RSP_IU
+Sense len      : ...
+^^^^^^^^^^^^^^^^^^^^ no sense data length
+Sense info     : ...
+^^^^^^^^^^^^^^^^^^^^ no sense data content, even if present
+
+There are some true cases where we really do not have an FSF request:
+"rsl_fai" from zfcp_dbf_scsi_fail_send() called for early
+returns / completions in zfcp_scsi_queuecommand(),
+"abrt_or", "abrt_bl", "abrt_ru", "abrt_ar" from
+zfcp_scsi_eh_abort_handler() where we did not get as far,
+"lr_nres", "tr_nres" from zfcp_task_mgmt_function() where we're
+successful and do not need to do anything because adapter stopped.
+For these cases it's correct to pass NULL for fsf_req to _zfcp_dbf_scsi().
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: 8a36e4532ea1 ("[SCSI] zfcp: enhancement of zfcp debug features")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Block <bblock@linux.vnet.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.h  |    7 ++++---
+ drivers/s390/scsi/zfcp_scsi.c |    8 ++++----
+ 2 files changed, 8 insertions(+), 7 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.h
++++ b/drivers/s390/scsi/zfcp_dbf.h
+@@ -2,7 +2,7 @@
+  * zfcp device driver
+  * debug feature declarations
+  *
+- * Copyright IBM Corp. 2008, 2016
++ * Copyright IBM Corp. 2008, 2017
+  */
+ #ifndef ZFCP_DBF_H
+@@ -401,7 +401,8 @@ void zfcp_dbf_scsi_abort(char *tag, stru
+  * @flag: indicates type of reset (Target Reset, Logical Unit Reset)
+  */
+ static inline
+-void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag)
++void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag,
++                          struct zfcp_fsf_req *fsf_req)
+ {
+       char tmp_tag[ZFCP_DBF_TAG_LEN];
+@@ -411,7 +412,7 @@ void zfcp_dbf_scsi_devreset(char *tag, s
+               memcpy(tmp_tag, "lr_", 3);
+       memcpy(&tmp_tag[3], tag, 4);
+-      _zfcp_dbf_scsi(tmp_tag, 1, scmnd, NULL);
++      _zfcp_dbf_scsi(tmp_tag, 1, scmnd, fsf_req);
+ }
+ /**
+--- a/drivers/s390/scsi/zfcp_scsi.c
++++ b/drivers/s390/scsi/zfcp_scsi.c
+@@ -3,7 +3,7 @@
+  *
+  * Interface to Linux SCSI midlayer.
+  *
+- * Copyright IBM Corp. 2002, 2016
++ * Copyright IBM Corp. 2002, 2017
+  */
+ #define KMSG_COMPONENT "zfcp"
+@@ -278,7 +278,7 @@ static int zfcp_task_mgmt_function(struc
+               if (!(atomic_read(&adapter->status) &
+                     ZFCP_STATUS_COMMON_RUNNING)) {
+-                      zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags);
++                      zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags, NULL);
+                       return SUCCESS;
+               }
+       }
+@@ -288,10 +288,10 @@ static int zfcp_task_mgmt_function(struc
+       wait_for_completion(&fsf_req->completion);
+       if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
+-              zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags);
++              zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags, fsf_req);
+               retval = FAILED;
+       } else {
+-              zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags);
++              zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags, fsf_req);
+               zfcp_scsi_forget_cmnds(zfcp_sdev, tm_flags);
+       }
diff --git a/queue-4.9/scsi-zfcp-fix-payload-with-full-fcp_rsp-iu-in-scsi-trace-records.patch b/queue-4.9/scsi-zfcp-fix-payload-with-full-fcp_rsp-iu-in-scsi-trace-records.patch
new file mode 100644 (file)
index 0000000..7d4ef72
--- /dev/null
@@ -0,0 +1,189 @@
+From 12c3e5754c8022a4f2fd1e9f00d19e99ee0d3cc1 Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Fri, 28 Jul 2017 12:30:56 +0200
+Subject: scsi: zfcp: fix payload with full FCP_RSP IU in SCSI trace records
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit 12c3e5754c8022a4f2fd1e9f00d19e99ee0d3cc1 upstream.
+
+If the FCP_RSP UI has optional parts (FCP_SNS_INFO or FCP_RSP_INFO) and
+thus does not fit into the fsp_rsp field built into a SCSI trace record,
+trace the full FCP_RSP UI with all optional parts as payload record
+instead of just FCP_SNS_INFO as payload and
+a 1 byte RSP_INFO_CODE part of FCP_RSP_INFO built into the SCSI record.
+
+That way we would also get the full FCP_SNS_INFO in case a
+target would ever send more than
+min(SCSI_SENSE_BUFFERSIZE==96, ZFCP_DBF_PAY_MAX_REC==256)==96.
+
+The mandatory part of FCP_RSP IU is only 24 bytes.
+PAYload costs at least one full PAY record of 256 bytes anyway.
+We cap to the hardware response size which is only FSF_FCP_RSP_SIZE==128.
+So we can just put the whole FCP_RSP IU with any optional parts into
+PAYload similarly as we do for SAN PAY since v4.9 commit aceeffbb59bb
+("zfcp: trace full payload of all SAN records (req,resp,iels)").
+This does not cause any additional trace records wasting memory.
+
+Decoded trace records were confusing because they showed a hard-coded
+sense data length of 96 even if the FCP_RSP_IU field FCP_SNS_LEN showed
+actually less.
+
+Since the same commit, we set pl_len for SAN traces to the full length of a
+request/response even if we cap the corresponding trace.
+In contrast, here for SCSI traces we set pl_len to the pre-computed
+length of FCP_RSP IU considering SNS_LEN or RSP_LEN if valid.
+Nonetheless we trace a hardcoded payload of length FSF_FCP_RSP_SIZE==128
+if there were optional parts.
+This makes it easier for the zfcpdbf tool to format only the relevant
+part of the long FCP_RSP UI buffer. And any trailing information is still
+available in the payload trace record just in case.
+
+Rename the payload record tag from "fcp_sns" to "fcp_riu" to make the new
+content explicit to zfcpdbf which can then pick a suitable field name such
+as "FCP rsp IU all:" instead of "Sense info :"
+Also, the same zfcpdbf can still be backwards compatible with "fcp_sns".
+
+Old example trace record before this fix, formatted with the tool zfcpdbf
+from s390-tools:
+
+Timestamp      : ...
+Area           : SCSI
+Subarea        : 00
+Level          : 3
+Exception      : -
+CPU id         : ..
+Caller         : 0x...
+Record id      : 1
+Tag            : rsl_err
+Request id     : 0x<request_id>
+SCSI ID        : 0x...
+SCSI LUN       : 0x...
+SCSI result    : 0x00000002
+SCSI retries   : 0x00
+SCSI allowed   : 0x05
+SCSI scribble  : 0x<request_id>
+SCSI opcode    : 00000000 00000000 00000000 00000000
+FCP rsp inf cod: 0x00
+FCP rsp IU     : 00000000 00000000 00000202 00000000
+                                       ^^==FCP_SNS_LEN_VALID
+                 00000020 00000000
+                 ^^^^^^^^==FCP_SNS_LEN==32
+Sense len      : 96 <==min(SCSI_SENSE_BUFFERSIZE,ZFCP_DBF_PAY_MAX_REC)
+Sense info     : 70000600 00000018 00000000 29000000
+                 00000400 00000000 00000000 00000000
+                 00000000 00000000 00000000 00000000<==superfluous
+                 00000000 00000000 00000000 00000000<==superfluous
+                 00000000 00000000 00000000 00000000<==superfluous
+                 00000000 00000000 00000000 00000000<==superfluous
+
+New example trace records with this fix:
+
+Timestamp      : ...
+Area           : SCSI
+Subarea        : 00
+Level          : 3
+Exception      : -
+CPU ID         : ..
+Caller         : 0x...
+Record ID      : 1
+Tag            : rsl_err
+Request ID     : 0x<request_id>
+SCSI ID        : 0x...
+SCSI LUN       : 0x...
+SCSI result    : 0x00000002
+SCSI retries   : 0x00
+SCSI allowed   : 0x03
+SCSI scribble  : 0x<request_id>
+SCSI opcode    : a30c0112 00000000 02000000 00000000
+FCP rsp inf cod: 0x00
+FCP rsp IU     : 00000000 00000000 00000a02 00000200
+                 00000020 00000000
+FCP rsp IU len : 56
+FCP rsp IU all : 00000000 00000000 00000a02 00000200
+                                       ^^=FCP_RESID_UNDER|FCP_SNS_LEN_VALID
+                 00000020 00000000 70000500 00000018
+                 ^^^^^^^^==FCP_SNS_LEN
+                                   ^^^^^^^^^^^^^^^^^
+                 00000000 240000cb 00011100 00000000
+                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+                 00000000 00000000
+                 ^^^^^^^^^^^^^^^^^==FCP_SNS_INFO
+
+Timestamp      : ...
+Area           : SCSI
+Subarea        : 00
+Level          : 1
+Exception      : -
+CPU ID         : ..
+Caller         : 0x...
+Record ID      : 1
+Tag            : lr_okay
+Request ID     : 0x<request_id>
+SCSI ID        : 0x...
+SCSI LUN       : 0x...
+SCSI result    : 0x00000000
+SCSI retries   : 0x00
+SCSI allowed   : 0x05
+SCSI scribble  : 0x<request_id>
+SCSI opcode    : <CDB of unrelated SCSI command passed to eh handler>
+FCP rsp inf cod: 0x00
+FCP rsp IU     : 00000000 00000000 00000100 00000000
+                 00000000 00000008
+FCP rsp IU len : 32
+FCP rsp IU all : 00000000 00000000 00000100 00000000
+                                       ^^==FCP_RSP_LEN_VALID
+                 00000000 00000008 00000000 00000000
+                          ^^^^^^^^==FCP_RSP_LEN
+                                   ^^^^^^^^^^^^^^^^^==FCP_RSP_INFO
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: 250a1352b95e ("[SCSI] zfcp: Redesign of the debug tracing for SCSI records.")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Block <bblock@linux.vnet.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 |   21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.c
++++ b/drivers/s390/scsi/zfcp_dbf.c
+@@ -572,19 +572,32 @@ void zfcp_dbf_scsi(char *tag, int level,
+       if (fsf) {
+               rec->fsf_req_id = fsf->req_id;
++              rec->pl_len = FCP_RESP_WITH_EXT;
+               fcp_rsp = (struct fcp_resp_with_ext *)
+                               &(fsf->qtcb->bottom.io.fcp_rsp);
++              /* mandatory parts of FCP_RSP IU in this SCSI record */
+               memcpy(&rec->fcp_rsp, fcp_rsp, FCP_RESP_WITH_EXT);
+               if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) {
+                       fcp_rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
+                       rec->fcp_rsp_info = fcp_rsp_info->rsp_code;
++                      rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_rsp_len);
+               }
+               if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) {
+-                      rec->pl_len = min((u16)SCSI_SENSE_BUFFERSIZE,
+-                                        (u16)ZFCP_DBF_PAY_MAX_REC);
+-                      zfcp_dbf_pl_write(dbf, sc->sense_buffer, rec->pl_len,
+-                                        "fcp_sns", fsf->req_id);
++                      rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_sns_len);
+               }
++              /* complete FCP_RSP IU in associated PAYload record
++               * but only if there are optional parts
++               */
++              if (fcp_rsp->resp.fr_flags != 0)
++                      zfcp_dbf_pl_write(
++                              dbf, fcp_rsp,
++                              /* at least one full PAY record
++                               * but not beyond hardware response field
++                               */
++                              min_t(u16, max_t(u16, rec->pl_len,
++                                               ZFCP_DBF_PAY_MAX_REC),
++                                    FSF_FCP_RSP_SIZE),
++                              "fcp_riu", fsf->req_id);
+       }
+       debug_event(dbf->scsi, level, rec, sizeof(*rec));
diff --git a/queue-4.9/scsi-zfcp-fix-queuecommand-for-scsi_eh-commands-when-dix-enabled.patch b/queue-4.9/scsi-zfcp-fix-queuecommand-for-scsi_eh-commands-when-dix-enabled.patch
new file mode 100644 (file)
index 0000000..69b19f1
--- /dev/null
@@ -0,0 +1,59 @@
+From 71b8e45da51a7b64a23378221c0a5868bd79da4f Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Fri, 28 Jul 2017 12:30:51 +0200
+Subject: scsi: zfcp: fix queuecommand for scsi_eh commands when DIX enabled
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit 71b8e45da51a7b64a23378221c0a5868bd79da4f upstream.
+
+Since commit db007fc5e20c ("[SCSI] Command protection operation"),
+scsi_eh_prep_cmnd() saves scmd->prot_op and temporarily resets it to
+SCSI_PROT_NORMAL.
+Other FCP LLDDs such as qla2xxx and lpfc shield their queuecommand()
+to only access any of scsi_prot_sg...() if
+(scsi_get_prot_op(cmd) != SCSI_PROT_NORMAL).
+
+Do the same thing for zfcp, which introduced DIX support with
+commit ef3eb71d8ba4 ("[SCSI] zfcp: Introduce experimental support for
+DIF/DIX").
+
+Otherwise, TUR SCSI commands as part of scsi_eh likely fail in zfcp,
+because the regular SCSI command with DIX protection data, that scsi_eh
+re-uses in scsi_send_eh_cmnd(), of course still has
+(scsi_prot_sg_count() != 0) and so zfcp sends down bogus requests to the
+FCP channel hardware.
+
+This causes scsi_eh_test_devices() to have (finish_cmds == 0)
+[not SCSI device is online or not scsi_eh_tur() failed]
+so regular SCSI commands, that caused / were affected by scsi_eh,
+are moved to work_q and scsi_eh_test_devices() itself returns false.
+In turn, it unnecessarily escalates in our case in scsi_eh_ready_devs()
+beyond host reset to finally scsi_eh_offline_sdevs()
+which sets affected SCSI devices offline with the following kernel message:
+
+"kernel: sd H:0:T:L: Device offlined - not ready after error recovery"
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: ef3eb71d8ba4 ("[SCSI] zfcp: Introduce experimental support for DIF/DIX")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Block <bblock@linux.vnet.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_fsf.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/s390/scsi/zfcp_fsf.c
++++ b/drivers/s390/scsi/zfcp_fsf.c
+@@ -2258,7 +2258,8 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *
+       fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
+       zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd, 0);
+-      if (scsi_prot_sg_count(scsi_cmnd)) {
++      if ((scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) &&
++          scsi_prot_sg_count(scsi_cmnd)) {
+               zfcp_qdio_set_data_div(qdio, &req->qdio_req,
+                                      scsi_prot_sg_count(scsi_cmnd));
+               retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req,
diff --git a/queue-4.9/scsi-zfcp-trace-hba-fsf-response-by-default-on-dismiss-or-timedout-late-response.patch b/queue-4.9/scsi-zfcp-trace-hba-fsf-response-by-default-on-dismiss-or-timedout-late-response.patch
new file mode 100644 (file)
index 0000000..a2a0e91
--- /dev/null
@@ -0,0 +1,217 @@
+From fdb7cee3b9e3c561502e58137a837341f10cbf8b Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Fri, 28 Jul 2017 12:30:57 +0200
+Subject: scsi: zfcp: trace HBA FSF response by default on dismiss or timedout late response
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit fdb7cee3b9e3c561502e58137a837341f10cbf8b upstream.
+
+At the default trace level, we only trace unsuccessful events including
+FSF responses.
+
+zfcp_dbf_hba_fsf_response() only used protocol status and FSF status to
+decide on an unsuccessful response. However, this is only one of multiple
+possible sources determining a failed struct zfcp_fsf_req.
+
+An FSF request can also "fail" if its response runs into an ERP timeout
+or if it gets dismissed because a higher level recovery was triggered
+[trace tags "erscf_1" or "erscf_2" in zfcp_erp_strategy_check_fsfreq()].
+FSF requests with ERP timeout are:
+FSF_QTCB_EXCHANGE_CONFIG_DATA, FSF_QTCB_EXCHANGE_PORT_DATA,
+FSF_QTCB_OPEN_PORT_WITH_DID or FSF_QTCB_CLOSE_PORT or
+FSF_QTCB_CLOSE_PHYSICAL_PORT for target ports,
+FSF_QTCB_OPEN_LUN, FSF_QTCB_CLOSE_LUN.
+One example is slow queue processing which can cause follow-on errors,
+e.g. FSF_PORT_ALREADY_OPEN after FSF_QTCB_OPEN_PORT_WITH_DID timed out.
+In order to see the root cause, we need to see late responses even if the
+channel presented them successfully with FSF_PROT_GOOD and FSF_GOOD.
+Example trace records formatted with zfcpdbf from the s390-tools package:
+
+Timestamp      : ...
+Area           : REC
+Subarea        : 00
+Level          : 1
+Exception      : -
+CPU ID         : ..
+Caller         : ...
+Record ID      : 1
+Tag            : fcegpf1
+LUN            : 0xffffffffffffffff
+WWPN           : 0x<WWPN>
+D_ID           : 0x00<D_ID>
+Adapter status : 0x5400050b
+Port status    : 0x41200000
+LUN status     : 0x00000000
+Ready count    : 0x00000001
+Running count  : 0x...
+ERP want       : 0x02                          ZFCP_ERP_ACTION_REOPEN_PORT
+ERP need       : 0x02                          ZFCP_ERP_ACTION_REOPEN_PORT
+|
+Timestamp      : ...                           30 seconds later
+Area           : REC
+Subarea        : 00
+Level          : 1
+Exception      : -
+CPU ID         : ..
+Caller         : ...
+Record ID      : 2
+Tag            : erscf_2
+LUN            : 0xffffffffffffffff
+WWPN           : 0x<WWPN>
+D_ID           : 0x00<D_ID>
+Adapter status : 0x5400050b
+Port status    : 0x41200000
+LUN status     : 0x00000000
+Request ID     : 0x<request_ID>
+ERP status     : 0x10000000                    ZFCP_STATUS_ERP_TIMEDOUT
+ERP step       : 0x0800                                ZFCP_ERP_STEP_PORT_OPENING
+ERP action     : 0x02                          ZFCP_ERP_ACTION_REOPEN_PORT
+ERP count      : 0x00
+|
+Timestamp      : ...                           later than previous record
+Area           : HBA
+Subarea        : 00
+Level          : 5     > default level         => 3    <= default level
+Exception      : -
+CPU ID         : 00
+Caller         : ...
+Record ID      : 1
+Tag            : fs_qtcb                       => fs_rerr
+Request ID     : 0x<request_ID>
+Request status : 0x00001010                    ZFCP_STATUS_FSFREQ_DISMISSED
+                                               | ZFCP_STATUS_FSFREQ_CLEANUP
+FSF cmnd       : 0x00000005
+FSF sequence no: 0x...
+FSF issued     : ...                           > 30 seconds ago
+FSF stat       : 0x00000000                    FSF_GOOD
+FSF stat qual  : 00000000 00000000 00000000 00000000
+Prot stat      : 0x00000001                    FSF_PROT_GOOD
+Prot stat qual : 00000000 00000000 00000000 00000000
+Port handle    : 0x...
+LUN handle     : 0x00000000
+QTCB log length: ...
+QTCB log info  : ...
+
+In case of problems detecting that new responses are waiting on the input
+queue, we sooner or later trigger adapter recovery due to an FSF request
+timeout (trace tag "fsrth_1").
+FSF requests with FSF request timeout are:
+typically FSF_QTCB_ABORT_FCP_CMND; but theoretically also
+FSF_QTCB_EXCHANGE_CONFIG_DATA or FSF_QTCB_EXCHANGE_PORT_DATA via sysfs,
+FSF_QTCB_OPEN_PORT_WITH_DID or FSF_QTCB_CLOSE_PORT for WKA ports,
+FSF_QTCB_FCP_CMND for task management function (LUN / target reset).
+One or more pending requests can meanwhile have FSF_PROT_GOOD and FSF_GOOD
+because the channel filled in the response via DMA into the request's QTCB.
+
+In a theroretical case, inject code can create an erroneous FSF request
+on purpose. If data router is enabled, it uses deferred error reporting.
+A READ SCSI command can succeed with FSF_PROT_GOOD, FSF_GOOD, and
+SAM_STAT_GOOD. But on writing the read data to host memory via DMA,
+it can still fail, e.g. if an intentionally wrong scatter list does not
+provide enough space. Rather than getting an unsuccessful response,
+we get a QDIO activate check which in turn triggers adapter recovery.
+One or more pending requests can meanwhile have FSF_PROT_GOOD and FSF_GOOD
+because the channel filled in the response via DMA into the request's QTCB.
+Example trace records formatted with zfcpdbf from the s390-tools package:
+
+Timestamp      : ...
+Area           : HBA
+Subarea        : 00
+Level          : 6     > default level         => 3    <= default level
+Exception      : -
+CPU ID         : ..
+Caller         : ...
+Record ID      : 1
+Tag            : fs_norm                       => fs_rerr
+Request ID     : 0x<request_ID2>
+Request status : 0x00001010                    ZFCP_STATUS_FSFREQ_DISMISSED
+                                               | ZFCP_STATUS_FSFREQ_CLEANUP
+FSF cmnd       : 0x00000001
+FSF sequence no: 0x...
+FSF issued     : ...
+FSF stat       : 0x00000000                    FSF_GOOD
+FSF stat qual  : 00000000 00000000 00000000 00000000
+Prot stat      : 0x00000001                    FSF_PROT_GOOD
+Prot stat qual : ........ ........ 00000000 00000000
+Port handle    : 0x...
+LUN handle     : 0x...
+|
+Timestamp      : ...
+Area           : SCSI
+Subarea        : 00
+Level          : 3
+Exception      : -
+CPU ID         : ..
+Caller         : ...
+Record ID      : 1
+Tag            : rsl_err
+Request ID     : 0x<request_ID2>
+SCSI ID        : 0x...
+SCSI LUN       : 0x...
+SCSI result    : 0x000e0000                    DID_TRANSPORT_DISRUPTED
+SCSI retries   : 0x00
+SCSI allowed   : 0x05
+SCSI scribble  : 0x<request_ID2>
+SCSI opcode    : 28...                         Read(10)
+FCP rsp inf cod: 0x00
+FCP rsp IU     : 00000000 00000000 00000000 00000000
+                                         ^^    SAM_STAT_GOOD
+                 00000000 00000000
+
+Only with luck in both above cases, we could see a follow-on trace record
+of an unsuccesful event following a successful but late FSF response with
+FSF_PROT_GOOD and FSF_GOOD. Typically this was the case for I/O requests
+resulting in a SCSI trace record "rsl_err" with DID_TRANSPORT_DISRUPTED
+[On ZFCP_STATUS_FSFREQ_DISMISSED, zfcp_fsf_protstatus_eval() sets
+ZFCP_STATUS_FSFREQ_ERROR seen by the request handler functions as failure].
+However, the reason for this follow-on trace was invisible because the
+corresponding HBA trace record was missing at the default trace level
+(by default hidden records with tags "fs_norm", "fs_qtcb", or "fs_open").
+
+On adapter recovery, after we had shut down the QDIO queues, we perform
+unsuccessful pseudo completions with flag ZFCP_STATUS_FSFREQ_DISMISSED
+for each pending FSF request in zfcp_fsf_req_dismiss_all().
+In order to find the root cause, we need to see all pseudo responses even
+if the channel presented them successfully with FSF_PROT_GOOD and FSF_GOOD.
+
+Therefore, check zfcp_fsf_req.status for ZFCP_STATUS_FSFREQ_DISMISSED
+or ZFCP_STATUS_FSFREQ_ERROR and trace with a new tag "fs_rerr".
+
+It does not matter that there are numerous places which set
+ZFCP_STATUS_FSFREQ_ERROR after the location where we trace an FSF response
+early. These cases are based on protocol status != FSF_PROT_GOOD or
+== FSF_PROT_FSF_STATUS_PRESENTED and are thus already traced by default
+as trace tag "fs_perr" or "fs_ferr" respectively.
+
+NB: The trace record with tag "fssrh_1" for status read buffers on dismiss
+all remains. zfcp_fsf_req_complete() handles this and returns early.
+All other FSF request types are handled separately and as described above.
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: 8a36e4532ea1 ("[SCSI] zfcp: enhancement of zfcp debug features")
+Fixes: 2e261af84cdb ("[SCSI] zfcp: Only collect FSF/HBA debug data for matching trace levels")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Block <bblock@linux.vnet.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.h |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.h
++++ b/drivers/s390/scsi/zfcp_dbf.h
+@@ -323,7 +323,11 @@ void zfcp_dbf_hba_fsf_response(struct zf
+ {
+       struct fsf_qtcb *qtcb = req->qtcb;
+-      if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
++      if (unlikely(req->status & (ZFCP_STATUS_FSFREQ_DISMISSED |
++                                  ZFCP_STATUS_FSFREQ_ERROR))) {
++              zfcp_dbf_hba_fsf_resp("fs_rerr", 3, req);
++
++      } else if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
+           (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
+               zfcp_dbf_hba_fsf_resp("fs_perr", 1, req);
diff --git a/queue-4.9/scsi-zfcp-trace-high-part-of-new-64-bit-scsi-lun.patch b/queue-4.9/scsi-zfcp-trace-high-part-of-new-64-bit-scsi-lun.patch
new file mode 100644 (file)
index 0000000..7bcfb07
--- /dev/null
@@ -0,0 +1,150 @@
+From 5d4a3d0a2ff23799b956e5962b886287614e7fad Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Fri, 28 Jul 2017 12:30:58 +0200
+Subject: scsi: zfcp: trace high part of "new" 64 bit SCSI LUN
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit 5d4a3d0a2ff23799b956e5962b886287614e7fad upstream.
+
+Complements debugging aspects of the otherwise functionally complete
+v3.17 commit 9cb78c16f5da ("scsi: use 64-bit LUNs").
+
+While I don't have access to a target exporting 3 or 4 level LUNs,
+I did test it by explicitly attaching a non-existent fake 4 level LUN
+by means of zfcp sysfs attribute "unit_add".
+In order to see corresponding trace records of otherwise successful
+events, we had to increase the trace level of area SCSI and HBA to 6.
+
+$ echo 6 > /sys/kernel/debug/s390dbf/zfcp_0.0.1880_scsi/level
+$ echo 6 > /sys/kernel/debug/s390dbf/zfcp_0.0.1880_hba/level
+
+$ echo 0x4011402240334044 > \
+  /sys/bus/ccw/drivers/zfcp/0.0.1880/0x50050763031bd327/unit_add
+
+Example output formatted by an updated zfcpdbf from the s390-tools
+package interspersed with kernel messages at scsi_logging_level=4605:
+
+Timestamp      : ...
+Area           : REC
+Subarea        : 00
+Level          : 1
+Exception      : -
+CPU ID         : ..
+Caller         : 0x...
+Record ID      : 1
+Tag            : scsla_1
+LUN            : 0x4011402240334044
+WWPN           : 0x50050763031bd327
+D_ID           : 0x00......
+Adapter status : 0x5400050b
+Port status    : 0x54000001
+LUN status     : 0x41000000
+Ready count    : 0x00000001
+Running count  : 0x00000000
+ERP want       : 0x01
+ERP need       : 0x01
+
+scsi 2:0:0:4630896905707208721: scsi scan: INQUIRY pass 1 length 36
+scsi 2:0:0:4630896905707208721: scsi scan: INQUIRY successful with code 0x0
+
+Timestamp      : ...
+Area           : HBA
+Subarea        : 00
+Level          : 6
+Exception      : -
+CPU ID         : ..
+Caller         : 0x...
+Record ID      : 1
+Tag            : fs_norm
+Request ID     : 0x<inquiry2-req-id>
+Request status : 0x00000010
+FSF cmnd       : 0x00000001
+FSF sequence no: 0x...
+FSF issued     : ...
+FSF stat       : 0x00000000
+FSF stat qual  : 00000000 00000000 00000000 00000000
+Prot stat      : 0x00000001
+Prot stat qual : ........ ........ 00000000 00000000
+Port handle    : 0x...
+LUN handle     : 0x...
+|
+Timestamp      : ...
+Area           : SCSI
+Subarea        : 00
+Level          : 6
+Exception      : -
+CPU ID         : ..
+Caller         : 0x...
+Record ID      : 1
+Tag            : rsl_nor
+Request ID     : 0x<inquiry2-req-id>
+SCSI ID        : 0x00000000
+SCSI LUN       : 0x40224011
+SCSI LUN high  : 0x40444033 <=======================
+SCSI result    : 0x00000000
+SCSI retries   : 0x00
+SCSI allowed   : 0x03
+SCSI scribble  : 0x<inquiry2-req-id>
+SCSI opcode    : 12000000 a4000000 00000000 00000000
+FCP rsp inf cod: 0x00
+FCP rsp IU     : 00000000 00000000 00000000 00000000
+                 00000000 00000000
+
+scsi 2:0:0:4630896905707208721: scsi scan: INQUIRY pass 2 length 164
+scsi 2:0:0:4630896905707208721: scsi scan: INQUIRY successful with code 0x0
+scsi 2:0:0:4630896905707208721: scsi scan: peripheral device type of 31, \
+no device added
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: 9cb78c16f5da ("scsi: use 64-bit LUNs")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Reviewed-by: Jens Remus <jremus@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Block <bblock@linux.vnet.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 |    2 +-
+ drivers/s390/scsi/zfcp_dbf.h |    4 +++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.c
++++ b/drivers/s390/scsi/zfcp_dbf.c
+@@ -563,8 +563,8 @@ void zfcp_dbf_scsi(char *tag, int level,
+       rec->scsi_retries = sc->retries;
+       rec->scsi_allowed = sc->allowed;
+       rec->scsi_id = sc->device->id;
+-      /* struct zfcp_dbf_scsi needs to be updated to handle 64bit LUNs */
+       rec->scsi_lun = (u32)sc->device->lun;
++      rec->scsi_lun_64_hi = (u32)(sc->device->lun >> 32);
+       rec->host_scribble = (unsigned long)sc->host_scribble;
+       memcpy(rec->scsi_opcode, sc->cmnd,
+--- a/drivers/s390/scsi/zfcp_dbf.h
++++ b/drivers/s390/scsi/zfcp_dbf.h
+@@ -204,7 +204,7 @@ enum zfcp_dbf_scsi_id {
+  * @id: unique number of recovery record type
+  * @tag: identifier string specifying the location of initiation
+  * @scsi_id: scsi device id
+- * @scsi_lun: scsi device logical unit number
++ * @scsi_lun: scsi device logical unit number, low part of 64 bit, old 32 bit
+  * @scsi_result: scsi result
+  * @scsi_retries: current retry number of scsi request
+  * @scsi_allowed: allowed retries
+@@ -214,6 +214,7 @@ enum zfcp_dbf_scsi_id {
+  * @host_scribble: LLD specific data attached to SCSI request
+  * @pl_len: length of paload stored as zfcp_dbf_pay
+  * @fsf_rsp: response for fsf request
++ * @scsi_lun_64_hi: scsi device logical unit number, high part of 64 bit
+  */
+ struct zfcp_dbf_scsi {
+       u8 id;
+@@ -230,6 +231,7 @@ struct zfcp_dbf_scsi {
+       u64 host_scribble;
+       u16 pl_len;
+       struct fcp_resp_with_ext fcp_rsp;
++      u32 scsi_lun_64_hi;
+ } __packed;
+ /**
index 74c4b340a965f4ed34f0cdffb44f2369d18bc488..24e69cd6d5a12dfac9ba62f28dd3c7d64aaaa080 100644 (file)
@@ -30,3 +30,21 @@ ext4-fix-quota-inconsistency-during-orphan-cleanup-for-read-only-mounts.patch
 powerpc-fix-dar-reporting-when-alignment-handler-faults.patch
 block-relax-a-check-in-blk_start_queue.patch
 md-bitmap-disable-bitmap_resize-for-file-backed-bitmaps.patch
+skd-avoid-that-module-unloading-triggers-a-use-after-free.patch
+skd-submit-requests-to-firmware-before-triggering-the-doorbell.patch
+scsi-zfcp-fix-queuecommand-for-scsi_eh-commands-when-dix-enabled.patch
+scsi-zfcp-add-handling-for-fcp_resid_over-to-the-fcp-ingress-path.patch
+scsi-zfcp-fix-capping-of-unsuccessful-gpn_ft-san-response-trace-records.patch
+scsi-zfcp-fix-passing-fsf_req-to-scsi-trace-on-tmf-to-correlate-with-hba.patch
+scsi-zfcp-fix-missing-trace-records-for-early-returns-in-tmf-eh-handlers.patch
+scsi-zfcp-fix-payload-with-full-fcp_rsp-iu-in-scsi-trace-records.patch
+scsi-zfcp-trace-hba-fsf-response-by-default-on-dismiss-or-timedout-late-response.patch
+scsi-zfcp-trace-high-part-of-new-64-bit-scsi-lun.patch
+scsi-megaraid_sas-set-minimum-value-of-resetwaittime-to-be-1-secs.patch
+scsi-megaraid_sas-check-valid-aen-class-range-to-avoid-kernel-panic.patch
+scsi-megaraid_sas-return-pended-ioctls-with-cmd_status-mfi_stat_wrong_state-in-case-adapter-is-dead.patch
+scsi-storvsc-fix-memory-leak-on-ring-buffer-busy.patch
+scsi-sg-remove-save_scat_len.patch
+scsi-sg-use-standard-lists-for-sg_requests.patch
+scsi-sg-off-by-one-in-sg_ioctl.patch
+scsi-sg-factor-out-sg_fill_request_table.patch
diff --git a/queue-4.9/skd-avoid-that-module-unloading-triggers-a-use-after-free.patch b/queue-4.9/skd-avoid-that-module-unloading-triggers-a-use-after-free.patch
new file mode 100644 (file)
index 0000000..fb8d3c8
--- /dev/null
@@ -0,0 +1,78 @@
+From 7277cc67b3916eed47558c64f9c9c0de00a35cda Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bart.vanassche@wdc.com>
+Date: Thu, 17 Aug 2017 13:12:45 -0700
+Subject: skd: Avoid that module unloading triggers a use-after-free
+
+From: Bart Van Assche <bart.vanassche@wdc.com>
+
+commit 7277cc67b3916eed47558c64f9c9c0de00a35cda upstream.
+
+Since put_disk() triggers a disk_release() call and since that
+last function calls blk_put_queue() if disk->queue != NULL, clear
+the disk->queue pointer before calling put_disk(). This avoids
+that unloading the skd kernel module triggers the following
+use-after-free:
+
+WARNING: CPU: 8 PID: 297 at lib/refcount.c:128 refcount_sub_and_test+0x70/0x80
+refcount_t: underflow; use-after-free.
+CPU: 8 PID: 297 Comm: kworker/8:1 Not tainted 4.11.10-300.fc26.x86_64 #1
+Workqueue: events work_for_cpu_fn
+Call Trace:
+ dump_stack+0x63/0x84
+ __warn+0xcb/0xf0
+ warn_slowpath_fmt+0x5a/0x80
+ refcount_sub_and_test+0x70/0x80
+ refcount_dec_and_test+0x11/0x20
+ kobject_put+0x1f/0x50
+ blk_put_queue+0x15/0x20
+ disk_release+0xae/0xf0
+ device_release+0x32/0x90
+ kobject_release+0x67/0x170
+ kobject_put+0x2b/0x50
+ put_disk+0x17/0x20
+ skd_destruct+0x5c/0x890 [skd]
+ skd_pci_probe+0x124d/0x13a0 [skd]
+ local_pci_probe+0x42/0xa0
+ work_for_cpu_fn+0x14/0x20
+ process_one_work+0x19e/0x470
+ worker_thread+0x1dc/0x4a0
+ kthread+0x125/0x140
+ ret_from_fork+0x25/0x30
+
+Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Hannes Reinecke <hare@suse.de>
+Cc: Johannes Thumshirn <jthumshirn@suse.de>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/skd_main.c |   15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+--- a/drivers/block/skd_main.c
++++ b/drivers/block/skd_main.c
+@@ -4622,15 +4622,16 @@ static void skd_free_disk(struct skd_dev
+ {
+       struct gendisk *disk = skdev->disk;
+-      if (disk != NULL) {
+-              struct request_queue *q = disk->queue;
++      if (disk && (disk->flags & GENHD_FL_UP))
++              del_gendisk(disk);
+-              if (disk->flags & GENHD_FL_UP)
+-                      del_gendisk(disk);
+-              if (q)
+-                      blk_cleanup_queue(q);
+-              put_disk(disk);
++      if (skdev->queue) {
++              blk_cleanup_queue(skdev->queue);
++              skdev->queue = NULL;
++              disk->queue = NULL;
+       }
++
++      put_disk(disk);
+       skdev->disk = NULL;
+ }
diff --git a/queue-4.9/skd-submit-requests-to-firmware-before-triggering-the-doorbell.patch b/queue-4.9/skd-submit-requests-to-firmware-before-triggering-the-doorbell.patch
new file mode 100644 (file)
index 0000000..d77e33a
--- /dev/null
@@ -0,0 +1,49 @@
+From 5fbd545cd3fd311ea1d6e8be4cedddd0ee5684c7 Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bart.vanassche@wdc.com>
+Date: Thu, 17 Aug 2017 13:12:46 -0700
+Subject: skd: Submit requests to firmware before triggering the doorbell
+
+From: Bart Van Assche <bart.vanassche@wdc.com>
+
+commit 5fbd545cd3fd311ea1d6e8be4cedddd0ee5684c7 upstream.
+
+Ensure that the members of struct skd_msg_buf have been transferred
+to the PCIe adapter before the doorbell is triggered. This patch
+avoids that I/O fails sporadically and that the following error
+message is reported:
+
+(skd0:STM000196603:[0000:00:09.0]): Completion mismatch comp_id=0x0000 skreq=0x0400 new=0x0000
+
+Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Hannes Reinecke <hare@suse.de>
+Cc: Johannes Thumshirn <jthumshirn@suse.de>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/skd_main.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/block/skd_main.c
++++ b/drivers/block/skd_main.c
+@@ -2163,6 +2163,9 @@ static void skd_send_fitmsg(struct skd_d
+                */
+               qcmd |= FIT_QCMD_MSGSIZE_64;
++      /* Make sure skd_msg_buf is written before the doorbell is triggered. */
++      smp_wmb();
++
+       SKD_WRITEQ(skdev, qcmd, FIT_Q_COMMAND);
+ }
+@@ -2209,6 +2212,9 @@ static void skd_send_special_fitmsg(stru
+       qcmd = skspcl->mb_dma_address;
+       qcmd |= FIT_QCMD_QID_NORMAL + FIT_QCMD_MSGSIZE_128;
++      /* Make sure skd_msg_buf is written before the doorbell is triggered. */
++      smp_wmb();
++
+       SKD_WRITEQ(skdev, qcmd, FIT_Q_COMMAND);
+ }