[openib-general] [PATCH] add cq error events

Michael S. Tsirkin mst at mellanox.co.il
Thu Sep 22 03:31:59 PDT 2005


Hello, Roland, Sean!
The following implements reporting error events in mthca.
(I've renamed mthca_cq_event to mthca_cq_completion, for consistency
with qp events).

As a side note, the spec says: "Two types of CQ errors can occur: the CQ can
overrun or it can become inaccessible": I wander whether this should
be interpreted in a sense that that there should be
two types of events: IB_EVENT_CQ_OVERRUN and IB_EVENT_CQ_ACCESS, rather than
just a generic IB_EVENT_CQ_ERR

What do you think?

MST

---

Implement reporting asynchronous cq events.

Signed-off-by: Michael S. Tsirkin <mst at mellanox.co.il>

Index: linux-kernel/drivers/infiniband/hw/mthca/mthca_dev.h
===================================================================
--- linux-kernel/drivers/infiniband/hw/mthca/mthca_dev.h	(revision 3514)
+++ linux-kernel/drivers/infiniband/hw/mthca/mthca_dev.h	(working copy)
@@ -440,7 +440,9 @@ int mthca_init_cq(struct mthca_dev *dev,
 		  struct mthca_cq *cq);
 void mthca_free_cq(struct mthca_dev *dev,
 		   struct mthca_cq *cq);
-void mthca_cq_event(struct mthca_dev *dev, u32 cqn);
+void mthca_cq_completion(struct mthca_dev *dev, u32 cqn);
+void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
+		    enum ib_event_type event_type);
 void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
 		    struct mthca_srq *srq);
 
Index: linux-kernel/drivers/infiniband/hw/mthca/mthca_cq.c
===================================================================
--- linux-kernel/drivers/infiniband/hw/mthca/mthca_cq.c	(revision 3514)
+++ linux-kernel/drivers/infiniband/hw/mthca/mthca_cq.c	(working copy)
@@ -208,7 +208,7 @@ static inline void update_cons_index(str
 	}
 }
 
-void mthca_cq_event(struct mthca_dev *dev, u32 cqn)
+void mthca_cq_completion(struct mthca_dev *dev, u32 cqn)
 {
 	struct mthca_cq *cq;
 
@@ -224,6 +224,35 @@ void mthca_cq_event(struct mthca_dev *de
 	cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
 }
 
+void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
+		    enum ib_event_type event_type)
+{
+	struct mthca_cq *cq;
+	struct ib_event event;
+
+	spin_lock(&dev->cq_table.lock);
+
+	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) {
+		mthca_warn(dev, "Async event for bogus CQ %08x\n", cqn);
+		return;
+	}
+
+	event.device      = &dev->ib_dev;
+	event.event       = event_type;
+	event.element.cq  = &cq->ibcq;
+	if (cq->ibcq.event_handler)
+		cq->ibcq.event_handler(&event, 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,
 		    struct mthca_srq *srq)
 {
Index: linux-kernel/drivers/infiniband/hw/mthca/mthca_eq.c
===================================================================
--- linux-kernel/drivers/infiniband/hw/mthca/mthca_eq.c	(revision 3514)
+++ linux-kernel/drivers/infiniband/hw/mthca/mthca_eq.c	(working copy)
@@ -287,7 +287,7 @@ static int mthca_eq_int(struct mthca_dev
 		case MTHCA_EVENT_TYPE_COMP:
 			disarm_cqn = be32_to_cpu(eqe->event.comp.cqn) & 0xffffff;
 			disarm_cq(dev, eq->eqn, disarm_cqn);
-			mthca_cq_event(dev, disarm_cqn);
+			mthca_cq_completion(dev, disarm_cqn);
 			break;
 
 		case MTHCA_EVENT_TYPE_PATH_MIG:
@@ -349,6 +349,8 @@ static int mthca_eq_int(struct mthca_dev
 				   eqe->event.cq_err.syndrome == 1 ?
 				   "overrun" : "access violation",
 				   be32_to_cpu(eqe->event.cq_err.cqn) & 0xffffff);
+			mthca_cq_event(dev, be32_to_cpu(eqe->event.cq_err.cqn),
+				       IB_EVENT_CQ_ERR);
 			break;
 
 		case MTHCA_EVENT_TYPE_EQ_OVERFLOW:



More information about the general mailing list