]> git.openfabrics.org - ~emulex/for-vlad/old/compat-rdma.git/commitdiff
IB/qib: Port upstream commits to 3.12
authorDennis Dalessandro <dennis.dalessandro@intel.com>
Thu, 9 Jan 2014 16:56:29 +0000 (11:56 -0500)
committerDennis Dalessandro <dennis.dalessandro@intel.com>
Thu, 9 Jan 2014 16:56:29 +0000 (11:56 -0500)
2fadd83 IB/qib: Fix txselect regression
603e772 IB/qib: Convert qib_user_sdma_pin_pages() to use get_user_pages_fast()

Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
linux-next-cherry-picks/0010-IB-qib-Convert-qib_user_sdma_pin_pages-to-use-get_us.patch [new file with mode: 0644]
linux-next-cherry-picks/0011-IB-qib-Fix-txselect-regression.patch [new file with mode: 0644]

diff --git a/linux-next-cherry-picks/0010-IB-qib-Convert-qib_user_sdma_pin_pages-to-use-get_us.patch b/linux-next-cherry-picks/0010-IB-qib-Convert-qib_user_sdma_pin_pages-to-use-get_us.patch
new file mode 100644 (file)
index 0000000..9623cb7
--- /dev/null
@@ -0,0 +1,56 @@
+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(&current->mm->mmap_sem);
+               ret = qib_user_sdma_queue_pkts(dd, ppd, pq,
+                               iov, dim, &list, &mxp, &ndesc);
+-              up_write(&current->mm->mmap_sem);
+-
+               if (ret < 0)
+                       goto done_unlock;
+               else {
+-- 
+1.7.0.7
+
diff --git a/linux-next-cherry-picks/0011-IB-qib-Fix-txselect-regression.patch b/linux-next-cherry-picks/0011-IB-qib-Fix-txselect-regression.patch
new file mode 100644 (file)
index 0000000..513aaa4
--- /dev/null
@@ -0,0 +1,52 @@
+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
+