]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 18 Oct 2015 01:00:40 +0000 (18:00 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 18 Oct 2015 01:00:40 +0000 (18:00 -0700)
added patches:
3w-9xxx-don-t-unmap-bounce-buffered-commands.patch

queue-4.1/3w-9xxx-don-t-unmap-bounce-buffered-commands.patch [new file with mode: 0644]
queue-4.1/series

diff --git a/queue-4.1/3w-9xxx-don-t-unmap-bounce-buffered-commands.patch b/queue-4.1/3w-9xxx-don-t-unmap-bounce-buffered-commands.patch
new file mode 100644 (file)
index 0000000..1e6b8c8
--- /dev/null
@@ -0,0 +1,106 @@
+From 15e3d5a285ab9283136dba34bbf72886d9146706 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Sat, 3 Oct 2015 19:16:07 +0200
+Subject: 3w-9xxx: don't unmap bounce buffered commands
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christoph Hellwig <hch@lst.de>
+
+commit 15e3d5a285ab9283136dba34bbf72886d9146706 upstream.
+
+3w controller don't dma map small single SGL entry commands but instead
+bounce buffer them.  Add a helper to identify these commands and don't
+call scsi_dma_unmap for them.
+
+Based on an earlier patch from James Bottomley.
+
+Fixes: 118c85 ("3w-9xxx: fix command completion race")
+Reported-by: Tóth Attila <atoth@atoth.sote.hu>
+Tested-by: Tóth Attila <atoth@atoth.sote.hu>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Adam Radford <aradford@gmail.com>
+Signed-off-by: James Bottomley <JBottomley@Odin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/3w-9xxx.c |   28 +++++++++++++++++++++-------
+ 1 file changed, 21 insertions(+), 7 deletions(-)
+
+--- a/drivers/scsi/3w-9xxx.c
++++ b/drivers/scsi/3w-9xxx.c
+@@ -212,6 +212,17 @@ static const struct file_operations twa_
+       .llseek         = noop_llseek,
+ };
++/*
++ * The controllers use an inline buffer instead of a mapped SGL for small,
++ * single entry buffers.  Note that we treat a zero-length transfer like
++ * a mapped SGL.
++ */
++static bool twa_command_mapped(struct scsi_cmnd *cmd)
++{
++      return scsi_sg_count(cmd) != 1 ||
++              scsi_bufflen(cmd) >= TW_MIN_SGL_LENGTH;
++}
++
+ /* This function will complete an aen request from the isr */
+ static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
+ {
+@@ -1339,7 +1350,8 @@ static irqreturn_t twa_interrupt(int irq
+                               }
+                               /* Now complete the io */
+-                              scsi_dma_unmap(cmd);
++                              if (twa_command_mapped(cmd))
++                                      scsi_dma_unmap(cmd);
+                               cmd->scsi_done(cmd);
+                               tw_dev->state[request_id] = TW_S_COMPLETED;
+                               twa_free_request_id(tw_dev, request_id);
+@@ -1582,7 +1594,8 @@ static int twa_reset_device_extension(TW
+                               struct scsi_cmnd *cmd = tw_dev->srb[i];
+                               cmd->result = (DID_RESET << 16);
+-                              scsi_dma_unmap(cmd);
++                              if (twa_command_mapped(cmd))
++                                      scsi_dma_unmap(cmd);
+                               cmd->scsi_done(cmd);
+                       }
+               }
+@@ -1765,12 +1778,14 @@ static int twa_scsi_queue_lck(struct scs
+       retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
+       switch (retval) {
+       case SCSI_MLQUEUE_HOST_BUSY:
+-              scsi_dma_unmap(SCpnt);
++              if (twa_command_mapped(SCpnt))
++                      scsi_dma_unmap(SCpnt);
+               twa_free_request_id(tw_dev, request_id);
+               break;
+       case 1:
+               SCpnt->result = (DID_ERROR << 16);
+-              scsi_dma_unmap(SCpnt);
++              if (twa_command_mapped(SCpnt))
++                      scsi_dma_unmap(SCpnt);
+               done(SCpnt);
+               tw_dev->state[request_id] = TW_S_COMPLETED;
+               twa_free_request_id(tw_dev, request_id);
+@@ -1831,8 +1846,7 @@ static int twa_scsiop_execute_scsi(TW_De
+               /* Map sglist from scsi layer to cmd packet */
+               if (scsi_sg_count(srb)) {
+-                      if ((scsi_sg_count(srb) == 1) &&
+-                          (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
++                      if (!twa_command_mapped(srb)) {
+                               if (srb->sc_data_direction == DMA_TO_DEVICE ||
+                                   srb->sc_data_direction == DMA_BIDIRECTIONAL)
+                                       scsi_sg_copy_to_buffer(srb,
+@@ -1905,7 +1919,7 @@ static void twa_scsiop_execute_scsi_comp
+ {
+       struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+-      if (scsi_bufflen(cmd) < TW_MIN_SGL_LENGTH &&
++      if (!twa_command_mapped(cmd) &&
+           (cmd->sc_data_direction == DMA_FROM_DEVICE ||
+            cmd->sc_data_direction == DMA_BIDIRECTIONAL)) {
+               if (scsi_sg_count(cmd) == 1) {
index 5f41b80c6afa86b396be26f9c2250dba2ffc6d64..908226ae22b2ee1c8839ad117dfdd74b0719a8b2 100644 (file)
@@ -199,3 +199,4 @@ serial-atmel-fix-error-path-of-probe-function.patch
 intel_pstate-fix-overflow-in-busy_scaled-due-to-long-delay.patch
 mm-slab-fix-unexpected-index-mapping-result-of-kmalloc_size-index_node-1.patch
 mips-fix-console-output-for-fulong2e-system.patch
+3w-9xxx-don-t-unmap-bounce-buffered-commands.patch