]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 8 Feb 2014 23:07:17 +0000 (15:07 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 8 Feb 2014 23:07:17 +0000 (15:07 -0800)
added patches:
ib-qib-fix-qp-check-when-looping-back-to-from-qp1.patch
mtd-mxc_nand-remove-duplicated-ecc_stats-counting.patch
ore-fix-wrong-math-in-allocation-of-per-device-bio.patch
spidev-fix-hang-when-transfer_one_message-fails.patch

queue-3.4/ib-qib-fix-qp-check-when-looping-back-to-from-qp1.patch [new file with mode: 0644]
queue-3.4/mtd-mxc_nand-remove-duplicated-ecc_stats-counting.patch [new file with mode: 0644]
queue-3.4/ore-fix-wrong-math-in-allocation-of-per-device-bio.patch [new file with mode: 0644]
queue-3.4/series
queue-3.4/spidev-fix-hang-when-transfer_one_message-fails.patch [new file with mode: 0644]

diff --git a/queue-3.4/ib-qib-fix-qp-check-when-looping-back-to-from-qp1.patch b/queue-3.4/ib-qib-fix-qp-check-when-looping-back-to-from-qp1.patch
new file mode 100644 (file)
index 0000000..3d1686e
--- /dev/null
@@ -0,0 +1,46 @@
+From 6e0ea9e6cbcead7fa8c76e3e3b9de4a50c5131c5 Mon Sep 17 00:00:00 2001
+From: Ira Weiny <ira.weiny@intel.com>
+Date: Wed, 18 Dec 2013 08:41:37 -0800
+Subject: IB/qib: Fix QP check when looping back to/from QP1
+
+From: Ira Weiny <ira.weiny@intel.com>
+
+commit 6e0ea9e6cbcead7fa8c76e3e3b9de4a50c5131c5 upstream.
+
+The GSI QP type is compatible with and should be allowed to send data
+to/from any UD QP.  This was found when testing ibacm on the same node
+as an SA.
+
+Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Signed-off-by: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/qib/qib_ud.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/infiniband/hw/qib/qib_ud.c
++++ b/drivers/infiniband/hw/qib/qib_ud.c
+@@ -57,13 +57,20 @@ static void qib_ud_loopback(struct qib_q
+       struct qib_sge *sge;
+       struct ib_wc wc;
+       u32 length;
++      enum ib_qp_type sqptype, dqptype;
+       qp = qib_lookup_qpn(ibp, swqe->wr.wr.ud.remote_qpn);
+       if (!qp) {
+               ibp->n_pkt_drops++;
+               return;
+       }
+-      if (qp->ibqp.qp_type != sqp->ibqp.qp_type ||
++
++      sqptype = sqp->ibqp.qp_type == IB_QPT_GSI ?
++                      IB_QPT_UD : sqp->ibqp.qp_type;
++      dqptype = qp->ibqp.qp_type == IB_QPT_GSI ?
++                      IB_QPT_UD : qp->ibqp.qp_type;
++
++      if (dqptype != sqptype ||
+           !(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) {
+               ibp->n_pkt_drops++;
+               goto drop;
diff --git a/queue-3.4/mtd-mxc_nand-remove-duplicated-ecc_stats-counting.patch b/queue-3.4/mtd-mxc_nand-remove-duplicated-ecc_stats-counting.patch
new file mode 100644 (file)
index 0000000..efa0802
--- /dev/null
@@ -0,0 +1,30 @@
+From 0566477762f9e174e97af347ee9c865f908a5647 Mon Sep 17 00:00:00 2001
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Date: Fri, 29 Nov 2013 14:14:29 +0100
+Subject: mtd: mxc_nand: remove duplicated ecc_stats counting
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+commit 0566477762f9e174e97af347ee9c865f908a5647 upstream.
+
+The ecc_stats.corrected count variable will already be incremented in
+the above framework-layer just after this callback.
+
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/nand/mxc_nand.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/mtd/nand/mxc_nand.c
++++ b/drivers/mtd/nand/mxc_nand.c
+@@ -596,7 +596,6 @@ static int mxc_nand_correct_data_v2_v3(s
+               ecc_stat >>= 4;
+       } while (--no_subpages);
+-      mtd->ecc_stats.corrected += ret;
+       pr_debug("%d Symbol Correctable RS-ECC Error\n", ret);
+       return ret;
diff --git a/queue-3.4/ore-fix-wrong-math-in-allocation-of-per-device-bio.patch b/queue-3.4/ore-fix-wrong-math-in-allocation-of-per-device-bio.patch
new file mode 100644 (file)
index 0000000..33e7d4a
--- /dev/null
@@ -0,0 +1,132 @@
+From aad560b7f63b495f48a7232fd086c5913a676e6f Mon Sep 17 00:00:00 2001
+From: Boaz Harrosh <bharrosh@panasas.com>
+Date: Thu, 21 Nov 2013 17:58:08 +0200
+Subject: ore: Fix wrong math in allocation of per device BIO
+
+From: Boaz Harrosh <bharrosh@panasas.com>
+
+commit aad560b7f63b495f48a7232fd086c5913a676e6f upstream.
+
+At IO preparation we calculate the max pages at each device and
+allocate a BIO per device of that size. The calculation was wrong
+on some unaligned corner cases offset/length combination and would
+make prepare return with -ENOMEM. This would be bad for pnfs-objects
+that would in that case IO through MDS. And fatal for exofs were it
+would fail writes with EIO.
+
+Fix it by doing the proper math, that will work in all cases. (I
+ran a test with all possible offset/length combinations this time
+round).
+
+Also when reading we do not need to allocate for the parity units
+since we jump over them.
+
+Also lower the max_io_length to take into account the parity pages
+so not to allocate BIOs bigger than PAGE_SIZE
+
+Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/exofs/ore.c         |   37 +++++++++++++++++++++++++------------
+ include/scsi/osd_ore.h |    1 +
+ 2 files changed, 26 insertions(+), 12 deletions(-)
+
+--- a/fs/exofs/ore.c
++++ b/fs/exofs/ore.c
+@@ -103,7 +103,7 @@ int ore_verify_layout(unsigned total_com
+       layout->max_io_length =
+               (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - layout->stripe_unit) *
+-                                                      layout->group_width;
++                                      (layout->group_width - layout->parity);
+       if (layout->parity) {
+               unsigned stripe_length =
+                               (layout->group_width - layout->parity) *
+@@ -286,7 +286,8 @@ int  ore_get_rw_state(struct ore_layout
+       if (length) {
+               ore_calc_stripe_info(layout, offset, length, &ios->si);
+               ios->length = ios->si.length;
+-              ios->nr_pages = (ios->length + PAGE_SIZE - 1) / PAGE_SIZE;
++              ios->nr_pages = ((ios->offset & (PAGE_SIZE - 1)) +
++                               ios->length + PAGE_SIZE - 1) / PAGE_SIZE;
+               if (layout->parity)
+                       _ore_post_alloc_raid_stuff(ios);
+       }
+@@ -536,6 +537,7 @@ void ore_calc_stripe_info(struct ore_lay
+       u64     H = LmodS - G * T;
+       u32     N = div_u64(H, U);
++      u32     Nlast;
+       /* "H - (N * U)" is just "H % U" so it's bound to u32 */
+       u32     C = (u32)(H - (N * U)) / stripe_unit + G * group_width;
+@@ -568,6 +570,10 @@ void ore_calc_stripe_info(struct ore_lay
+       si->length = T - H;
+       if (si->length > length)
+               si->length = length;
++
++      Nlast = div_u64(H + si->length + U - 1, U);
++      si->maxdevUnits = Nlast - N;
++
+       si->M = M;
+ }
+ EXPORT_SYMBOL(ore_calc_stripe_info);
+@@ -583,13 +589,16 @@ int _ore_add_stripe_unit(struct ore_io_s
+       int ret;
+       if (per_dev->bio == NULL) {
+-              unsigned pages_in_stripe = ios->layout->group_width *
+-                                      (ios->layout->stripe_unit / PAGE_SIZE);
+-              unsigned nr_pages = ios->nr_pages * ios->layout->group_width /
+-                                      (ios->layout->group_width -
+-                                       ios->layout->parity);
+-              unsigned bio_size = (nr_pages + pages_in_stripe) /
+-                                      ios->layout->group_width;
++              unsigned bio_size;
++
++              if (!ios->reading) {
++                      bio_size = ios->si.maxdevUnits;
++              } else {
++                      bio_size = (ios->si.maxdevUnits + 1) *
++                           (ios->layout->group_width - ios->layout->parity) /
++                           ios->layout->group_width;
++              }
++              bio_size *= (ios->layout->stripe_unit / PAGE_SIZE);
+               per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size);
+               if (unlikely(!per_dev->bio)) {
+@@ -609,8 +618,12 @@ int _ore_add_stripe_unit(struct ore_io_s
+               added_len = bio_add_pc_page(q, per_dev->bio, pages[pg],
+                                           pglen, pgbase);
+               if (unlikely(pglen != added_len)) {
+-                      ORE_DBGMSG("Failed bio_add_pc_page bi_vcnt=%u\n",
+-                                 per_dev->bio->bi_vcnt);
++                      /* If bi_vcnt == bi_max then this is a SW BUG */
++                      ORE_DBGMSG("Failed bio_add_pc_page bi_vcnt=0x%x "
++                                 "bi_max=0x%x BIO_MAX=0x%x cur_len=0x%x\n",
++                                 per_dev->bio->bi_vcnt,
++                                 per_dev->bio->bi_max_vecs,
++                                 BIO_MAX_PAGES_KMALLOC, cur_len);
+                       ret = -ENOMEM;
+                       goto out;
+               }
+@@ -1099,7 +1112,7 @@ int ore_truncate(struct ore_layout *layo
+               size_attr->attr = g_attr_logical_length;
+               size_attr->attr.val_ptr = &size_attr->newsize;
+-              ORE_DBGMSG("trunc(0x%llx) obj_offset=0x%llx dev=%d\n",
++              ORE_DBGMSG2("trunc(0x%llx) obj_offset=0x%llx dev=%d\n",
+                            _LLU(oc->comps->obj.id), _LLU(obj_size), i);
+               ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1,
+                                       &size_attr->attr);
+--- a/include/scsi/osd_ore.h
++++ b/include/scsi/osd_ore.h
+@@ -102,6 +102,7 @@ struct ore_striping_info {
+       unsigned unit_off;
+       unsigned cur_pg;
+       unsigned cur_comp;
++      unsigned maxdevUnits;
+ };
+ struct ore_io_state;
index 668422b6f02cccb1c4e7101475e69cc61f05e2ab..5cfae288efab62ddfb7d5af942074dc98f5b7044 100644 (file)
@@ -5,3 +5,7 @@ mmc-atmel-mci-fix-timeout-errors-in-sdio-mode-when-using-dma.patch
 slub-fix-calculation-of-cpu-slabs.patch
 turbostat-use-gcc-s-cpuid-functions-to-support-pic.patch
 acpi-init-flag-use-of-acpi-and-acpi-idioms-for-power-supplies-to-regulator-api.patch
+mtd-mxc_nand-remove-duplicated-ecc_stats-counting.patch
+ore-fix-wrong-math-in-allocation-of-per-device-bio.patch
+ib-qib-fix-qp-check-when-looping-back-to-from-qp1.patch
+spidev-fix-hang-when-transfer_one_message-fails.patch
diff --git a/queue-3.4/spidev-fix-hang-when-transfer_one_message-fails.patch b/queue-3.4/spidev-fix-hang-when-transfer_one_message-fails.patch
new file mode 100644 (file)
index 0000000..2fa7db8
--- /dev/null
@@ -0,0 +1,43 @@
+From e120cc0dcf2880a4c5c0a6cb27b655600a1cfa1d Mon Sep 17 00:00:00 2001
+From: Daniel Santos <daniel.santos@pobox.com>
+Date: Sun, 5 Jan 2014 17:39:26 -0600
+Subject: spidev: fix hang when transfer_one_message fails
+
+From: Daniel Santos <daniel.santos@pobox.com>
+
+commit e120cc0dcf2880a4c5c0a6cb27b655600a1cfa1d upstream.
+
+This corrects a problem in spi_pump_messages() that leads to an spi
+message hanging forever when a call to transfer_one_message() fails.
+This failure occurs in my MCP2210 driver when the cs_change bit is set
+on the last transfer in a message, an operation which the hardware does
+not support.
+
+Rationale
+Since the transfer_one_message() returns an int, we must presume that it
+may fail.  If transfer_one_message() should never fail, it should return
+void.  Thus, calls to transfer_one_message() should properly manage a
+failure.
+
+Fixes: ffbbdd21329f3 (spi: create a message queueing infrastructure)
+Signed-off-by: Daniel Santos <daniel.santos@pobox.com>
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -572,7 +572,9 @@ static void spi_pump_messages(struct kth
+       ret = master->transfer_one_message(master, master->cur_msg);
+       if (ret) {
+               dev_err(&master->dev,
+-                      "failed to transfer one message from queue\n");
++                      "failed to transfer one message from queue: %d\n", ret);
++              master->cur_msg->status = ret;
++              spi_finalize_current_message(master);
+               return;
+       }
+ }