Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Bogendoerfer <tbogendoerfer@suse.de>2017-12-01 10:20:19 +0100
committerThomas Bogendoerfer <tbogendoerfer@suse.de>2017-12-01 10:20:52 +0100
commit20cef465c6195e02be63a6b3c8eee87396fa064c (patch)
tree88a375e0eb877bdfd68785b631592650bd9c5b4e
parentd46c8ded3b0ee6a1e4c3d7e2270adc78abdab156 (diff)
iw_cxgb4: atomically flush the qp (bsc#1064802 bsc#1066129).
-rw-r--r--patches.drivers/iw_cxgb4-atomically-flush-the-qp.patch76
-rw-r--r--series.conf1
2 files changed, 77 insertions, 0 deletions
diff --git a/patches.drivers/iw_cxgb4-atomically-flush-the-qp.patch b/patches.drivers/iw_cxgb4-atomically-flush-the-qp.patch
new file mode 100644
index 0000000000..e23d43f4a9
--- /dev/null
+++ b/patches.drivers/iw_cxgb4-atomically-flush-the-qp.patch
@@ -0,0 +1,76 @@
+From: Steve Wise <swise@opengridcomputing.com>
+Date: Thu, 9 Nov 2017 07:21:26 -0800
+Subject: iw_cxgb4: atomically flush the qp
+Patch-mainline: v4.15-rc1
+Git-commit: bc52e9ca74b9a395897bb640c6671b2cbf716032
+References: bsc#1064802 bsc#1066129
+
+__flush_qp() has a race condition where during the flush operation,
+the qp lock is released allowing another thread to possibly post a WR,
+which corrupts the queue state, possibly causing crashes. The lock was
+released to preserve the cq/qp locking hierarchy of cq first, then qp.
+However releasing the qp lock is not necessary; both RQ and SQ CQ locks
+can be acquired first, followed by the qp lock, and then the RQ and SQ
+flushing can be done w/o unlocking.
+
+Signed-off-by: Steve Wise <swise@opengridcomputing.com>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/infiniband/hw/cxgb4/qp.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+--- a/drivers/infiniband/hw/cxgb4/qp.c
++++ b/drivers/infiniband/hw/cxgb4/qp.c
+@@ -1255,31 +1255,34 @@ static void __flush_qp(struct c4iw_qp *q
+
+ pr_debug("qhp %p rchp %p schp %p\n", qhp, rchp, schp);
+
+- /* locking hierarchy: cq lock first, then qp lock. */
++ /* locking hierarchy: cqs lock first, then qp lock. */
+ spin_lock_irqsave(&rchp->lock, flag);
++ if (schp != rchp)
++ spin_lock(&schp->lock);
+ spin_lock(&qhp->lock);
+
+ if (qhp->wq.flushed) {
+ spin_unlock(&qhp->lock);
++ if (schp != rchp)
++ spin_unlock(&schp->lock);
+ spin_unlock_irqrestore(&rchp->lock, flag);
+ return;
+ }
+ qhp->wq.flushed = 1;
++ t4_set_wq_in_error(&qhp->wq);
+
+ c4iw_flush_hw_cq(rchp);
+ c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count);
+ rq_flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count);
+- spin_unlock(&qhp->lock);
+- spin_unlock_irqrestore(&rchp->lock, flag);
+
+- /* locking hierarchy: cq lock first, then qp lock. */
+- spin_lock_irqsave(&schp->lock, flag);
+- spin_lock(&qhp->lock);
+ if (schp != rchp)
+ c4iw_flush_hw_cq(schp);
+ sq_flushed = c4iw_flush_sq(qhp);
++
+ spin_unlock(&qhp->lock);
+- spin_unlock_irqrestore(&schp->lock, flag);
++ if (schp != rchp)
++ spin_unlock(&schp->lock);
++ spin_unlock_irqrestore(&rchp->lock, flag);
+
+ if (schp == rchp) {
+ if (t4_clear_cq_armed(&rchp->cq) &&
+@@ -1313,8 +1316,8 @@ static void flush_qp(struct c4iw_qp *qhp
+ rchp = to_c4iw_cq(qhp->ibqp.recv_cq);
+ schp = to_c4iw_cq(qhp->ibqp.send_cq);
+
+- t4_set_wq_in_error(&qhp->wq);
+ if (qhp->ibqp.uobject) {
++ t4_set_wq_in_error(&qhp->wq);
+ t4_set_cq_in_error(&rchp->cq);
+ spin_lock_irqsave(&rchp->comp_handler_lock, flag);
+ (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context);
diff --git a/series.conf b/series.conf
index b9b42e40d0..d4bd52770b 100644
--- a/series.conf
+++ b/series.conf
@@ -5676,6 +5676,7 @@
patches.drivers/IB-core-Only-maintain-real-QPs-in-the-security-lists.patch
patches.drivers/iw_cxgb4-Fix-possible-circular-dependency-locking-wa.patch
patches.drivers/iw_cxgb4-only-call-the-cq-comp_handler-when-the-cq-i.patch
+ patches.drivers/iw_cxgb4-atomically-flush-the-qp.patch
patches.suse/mm-Handle-0-flags-in-_calc_vm_trans-macro.patch
patches.suse/mm-introduce-MAP_SHARED_VALIDATE-a-mechanism-to-safe.patch
patches.suse/mm-Remove-VM_FAULT_HWPOISON_LARGE_MASK.patch