aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRoland Dreier <roland@topspin.com>2005-01-14 23:16:54 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-14 23:16:54 -0800
commite02b65fcf6627e620e9dfd6f0d284c6756f6130f (patch)
tree5eff6f6cd1b7843c7fbfc49dd05e165a9be45203 /drivers
parent066091f5ee6f018a07c1c47993b01529f05b487d (diff)
downloadhistory-e02b65fcf6627e620e9dfd6f0d284c6756f6130f.tar.gz
[PATCH] InfiniBand/mthca: add needed rmb() in event queue poll
Add an rmb() between checking the ownership bit of an event queue entry and reading the contents of the EQE. Without this barrier, the CPU could read stale contents of the EQE before HW writes the EQE but have the read of the ownership bit reordered until after HW finishes writing, which leads to the driver processing an incorrect event. This was actually observed to happen when multiple completion queues are in heavy use on an IBM JS20 PowerPC 970 system. Also explain the existing rmb() in completion queue poll (there for the same reason) and slightly improve debugging output. Signed-off-by: Roland Dreier <roland@topspin.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c9
-rw-r--r--drivers/infiniband/hw/mthca/mthca_eq.c8
2 files changed, 14 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index 02dcf5610f985c..8a4498f891673e 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004 Topspin Communications. All rights reserved.
+ * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -391,6 +391,10 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
if (!next_cqe_sw(cq))
return -EAGAIN;
+ /*
+ * Make sure we read CQ entry contents after we've checked the
+ * ownership bit.
+ */
rmb();
cqe = get_cqe(cq, cq->cons_index);
@@ -768,7 +772,8 @@ void mthca_free_cq(struct mthca_dev *dev,
u32 *ctx = MAILBOX_ALIGN(mailbox);
int j;
- printk(KERN_ERR "context for CQN %x\n", cq->cqn);
+ printk(KERN_ERR "context for CQN %x (cons index %x, next sw %d)\n",
+ cq->cqn, cq->cons_index, next_cqe_sw(cq));
for (j = 0; j < 16; ++j)
printk(KERN_ERR "[%2x] %08x\n", j * 4, be32_to_cpu(ctx[j]));
}
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
index 010d624546188c..6f46cacae67921 100644
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004 Topspin Communications. All rights reserved.
+ * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -240,6 +240,12 @@ static void mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq)
int set_ci = 0;
eqe = get_eqe(eq, eq->cons_index);
+ /*
+ * Make sure we read EQ entry contents after we've
+ * checked the ownership bit.
+ */
+ rmb();
+
switch (eqe->type) {
case MTHCA_EVENT_TYPE_COMP:
disarm_cqn = be32_to_cpu(eqe->event.comp.cqn) & 0xffffff;