From: Dennis Dalessandro Date: Thu, 9 Jan 2014 16:56:29 +0000 (-0500) Subject: IB/qib: Port upstream commits to 3.12 X-Git-Tag: compat-rdma-2014-01-30~7 X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=757eeabd848d8bb455ce669186004515c96b0424;p=~emulex%2Fcompat-rdma_3.12.git IB/qib: Port upstream commits to 3.12 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 --- 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 index 0000000..9623cb7 --- /dev/null +++ b/linux-next-cherry-picks/0010-IB-qib-Convert-qib_user_sdma_pin_pages-to-use-get_us.patch @@ -0,0 +1,56 @@ +From 603e7729920e42b3c2f4dbfab9eef4878cb6e8fa Mon Sep 17 00:00:00 2001 +From: Jan Kara +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: +Reviewed-by: Mike Marciniszyn +Signed-off-by: Jan Kara +Signed-off-by: Roland Dreier +--- + 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 + 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 index 0000000..513aaa4 --- /dev/null +++ b/linux-next-cherry-picks/0011-IB-qib-Fix-txselect-regression.patch @@ -0,0 +1,52 @@ +From 2fadd83184d58701f1116ca578465b5a75f9417c Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +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: +Signed-off-by: Mike Marciniszyn +Signed-off-by: Roland Dreier +--- + 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 +