Commit 0b6e6a38 authored by Michael S. Tsirkin's avatar Michael S. Tsirkin Committed by Linus Torvalds

[PATCH] IB/mthca: improve CQ locking part 1

Avoid taking the CQ table lock in the fast path path by using
synchronize_irq() after removing a CQ from the table to make sure that
no completion events are still in progress.  This gets a nice speedup
(about 4%) in IP over IB on my hardware.
Signed-off-by: default avatarMichael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: default avatarRoland Dreier <roland@topspin.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent aab64dc6
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/hardirq.h>
#include <ib_pack.h> #include <ib_pack.h>
...@@ -181,11 +182,7 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn) ...@@ -181,11 +182,7 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn)
{ {
struct mthca_cq *cq; struct mthca_cq *cq;
spin_lock(&dev->cq_table.lock);
cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1)); cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1));
if (cq)
atomic_inc(&cq->refcount);
spin_unlock(&dev->cq_table.lock);
if (!cq) { if (!cq) {
mthca_warn(dev, "Completion event for bogus CQ %08x\n", cqn); mthca_warn(dev, "Completion event for bogus CQ %08x\n", cqn);
...@@ -193,9 +190,6 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn) ...@@ -193,9 +190,6 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn)
} }
cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
if (atomic_dec_and_test(&cq->refcount))
wake_up(&cq->wait);
} }
void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn) void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn)
...@@ -783,6 +777,11 @@ void mthca_free_cq(struct mthca_dev *dev, ...@@ -783,6 +777,11 @@ void mthca_free_cq(struct mthca_dev *dev,
cq->cqn & (dev->limits.num_cqs - 1)); cq->cqn & (dev->limits.num_cqs - 1));
spin_unlock_irq(&dev->cq_table.lock); spin_unlock_irq(&dev->cq_table.lock);
if (dev->mthca_flags & MTHCA_FLAG_MSI_X)
synchronize_irq(dev->eq_table.eq[MTHCA_EQ_COMP].msi_x_vector);
else
synchronize_irq(dev->pdev->irq);
atomic_dec(&cq->refcount); atomic_dec(&cq->refcount);
wait_event(cq->wait, !atomic_read(&cq->refcount)); wait_event(cq->wait, !atomic_read(&cq->refcount));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment