--- /dev/null
+From 603e7729920e42b3c2f4dbfab9eef4878cb6e8fa Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Fri, 4 Oct 2013 09:29:12 -0400
+Subject: [PATCH] IB/qib: Convert qib_user_sdma_pin_pages() to use get_user_pages_fast()
+
+qib_user_sdma_queue_pkts() gets called with mmap_sem held for
+writing. Except for get_user_pages() deep down in
+qib_user_sdma_pin_pages() we don't seem to need mmap_sem at all. Even
+more interestingly the function qib_user_sdma_queue_pkts() (and also
+qib_user_sdma_coalesce() called somewhat later) call copy_from_user()
+which can hit a page fault and we deadlock on trying to get mmap_sem
+when handling that fault.
+
+So just make qib_user_sdma_pin_pages() use get_user_pages_fast() and
+leave mmap_sem locking for mm.
+
+This deadlock has actually been observed in the wild when the node
+is under memory pressure.
+
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+---
+ drivers/infiniband/hw/qib/qib_user_sdma.c | 6 +-----
+ 1 files changed, 1 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.c b/drivers/infiniband/hw/qib/qib_user_sdma.c
+index d0a0ea0..165aee2 100644
+--- a/drivers/infiniband/hw/qib/qib_user_sdma.c
++++ b/drivers/infiniband/hw/qib/qib_user_sdma.c
+@@ -594,8 +594,7 @@ static int qib_user_sdma_pin_pages(const struct qib_devdata *dd,
+ else
+ j = npages;
+
+- ret = get_user_pages(current, current->mm, addr,
+- j, 0, 1, pages, NULL);
++ ret = get_user_pages_fast(addr, j, 0, pages);
+ if (ret != j) {
+ i = 0;
+ j = ret;
+@@ -1294,11 +1293,8 @@ int qib_user_sdma_writev(struct qib_ctxtdata *rcd,
+ int mxp = 8;
+ int ndesc = 0;
+
+- down_write(¤t->mm->mmap_sem);
+ ret = qib_user_sdma_queue_pkts(dd, ppd, pq,
+ iov, dim, &list, &mxp, &ndesc);
+- up_write(¤t->mm->mmap_sem);
+-
+ if (ret < 0)
+ goto done_unlock;
+ else {
+--
+1.7.0.7
+
--- /dev/null
+From 2fadd83184d58701f1116ca578465b5a75f9417c Mon Sep 17 00:00:00 2001
+From: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Date: Fri, 25 Oct 2013 11:17:59 -0400
+Subject: [PATCH] IB/qib: Fix txselect regression
+
+Commit 7fac33014f54("IB/qib: checkpatch fixes") was overzealous in
+removing a simple_strtoul for a parse routine, setup_txselect(). That
+routine is required to handle a multi-value string.
+
+Unwind that aspect of the fix.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+---
+ drivers/infiniband/hw/qib/qib_iba7322.c | 11 +++++------
+ 1 files changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c
+index 016e742..5bfc02f 100644
+--- a/drivers/infiniband/hw/qib/qib_iba7322.c
++++ b/drivers/infiniband/hw/qib/qib_iba7322.c
+@@ -6190,21 +6190,20 @@ static int setup_txselect(const char *str, struct kernel_param *kp)
+ {
+ struct qib_devdata *dd;
+ unsigned long val;
+- int ret;
+-
++ char *n;
+ if (strlen(str) >= MAX_ATTEN_LEN) {
+ pr_info("txselect_values string too long\n");
+ return -ENOSPC;
+ }
+- ret = kstrtoul(str, 0, &val);
+- if (ret || val >= (TXDDS_TABLE_SZ + TXDDS_EXTRA_SZ +
++ val = simple_strtoul(str, &n, 0);
++ if (n == str || val >= (TXDDS_TABLE_SZ + TXDDS_EXTRA_SZ +
+ TXDDS_MFG_SZ)) {
+ pr_info("txselect_values must start with a number < %d\n",
+ TXDDS_TABLE_SZ + TXDDS_EXTRA_SZ + TXDDS_MFG_SZ);
+- return ret ? ret : -EINVAL;
++ return -EINVAL;
+ }
+-
+ strcpy(txselect_list, str);
++
+ list_for_each_entry(dd, &qib_dev_list, list)
+ if (dd->deviceid == PCI_DEVICE_ID_QLOGIC_IB_7322)
+ set_no_qsfp_atten(dd, 1);
+--
+1.7.0.7
+