]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
RDMA/ocrdma: Allow expansion of the SQ CQEs via buddy CQ expansion of the QP
authorSelvin Xavier <selvin.xavier@emulex.com>
Thu, 18 Dec 2014 08:43:03 +0000 (14:13 +0530)
committerRoland Dreier <roland@purestorage.com>
Wed, 18 Feb 2015 16:31:03 +0000 (08:31 -0800)
If the SQ and RQ of the QP in error state uses separate CQs, traverse
the list of QPs using each CQs and invoke the buddy CQ handler for
both SQ and RQ.

Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/hw/ocrdma/ocrdma_hw.c

index 47999bb2b5f591af9fa47ebda22e062dbaed2bdc..f283626164138fbc319155f59604ad9d9b9b73ae 100644 (file)
@@ -834,20 +834,20 @@ static int ocrdma_mq_cq_handler(struct ocrdma_dev *dev, u16 cq_id)
        return 0;
 }
 
-static void ocrdma_qp_buddy_cq_handler(struct ocrdma_dev *dev,
-                                      struct ocrdma_cq *cq)
+static struct ocrdma_cq *_ocrdma_qp_buddy_cq_handler(struct ocrdma_dev *dev,
+                               struct ocrdma_cq *cq, bool sq)
 {
-       unsigned long flags;
        struct ocrdma_qp *qp;
-       bool buddy_cq_found = false;
-       /* Go through list of QPs in error state which are using this CQ
-        * and invoke its callback handler to trigger CQE processing for
-        * error/flushed CQE. It is rare to find more than few entries in
-        * this list as most consumers stops after getting error CQE.
-        * List is traversed only once when a matching buddy cq found for a QP.
-        */
-       spin_lock_irqsave(&dev->flush_q_lock, flags);
-       list_for_each_entry(qp, &cq->sq_head, sq_entry) {
+       struct list_head *cur;
+       struct ocrdma_cq *bcq = NULL;
+       struct list_head *head = sq?(&cq->sq_head):(&cq->rq_head);
+
+       list_for_each(cur, head) {
+               if (sq)
+                       qp = list_entry(cur, struct ocrdma_qp, sq_entry);
+               else
+                       qp = list_entry(cur, struct ocrdma_qp, rq_entry);
+
                if (qp->srq)
                        continue;
                /* if wq and rq share the same cq, than comp_handler
@@ -859,19 +859,41 @@ static void ocrdma_qp_buddy_cq_handler(struct ocrdma_dev *dev,
                 * if completion came on rq, sq's cq is buddy cq.
                 */
                if (qp->sq_cq == cq)
-                       cq = qp->rq_cq;
+                       bcq = qp->rq_cq;
                else
-                       cq = qp->sq_cq;
-               buddy_cq_found = true;
-               break;
+                       bcq = qp->sq_cq;
+               return bcq;
        }
+       return NULL;
+}
+
+static void ocrdma_qp_buddy_cq_handler(struct ocrdma_dev *dev,
+                                      struct ocrdma_cq *cq)
+{
+       unsigned long flags;
+       struct ocrdma_cq *bcq = NULL;
+
+       /* Go through list of QPs in error state which are using this CQ
+        * and invoke its callback handler to trigger CQE processing for
+        * error/flushed CQE. It is rare to find more than few entries in
+        * this list as most consumers stops after getting error CQE.
+        * List is traversed only once when a matching buddy cq found for a QP.
+        */
+       spin_lock_irqsave(&dev->flush_q_lock, flags);
+       /* Check if buddy CQ is present.
+        * true - Check for  SQ CQ
+        * false - Check for RQ CQ
+        */
+       bcq = _ocrdma_qp_buddy_cq_handler(dev, cq, true);
+       if (bcq == NULL)
+               bcq = _ocrdma_qp_buddy_cq_handler(dev, cq, false);
        spin_unlock_irqrestore(&dev->flush_q_lock, flags);
-       if (buddy_cq_found == false)
-               return;
-       if (cq->ibcq.comp_handler) {
-               spin_lock_irqsave(&cq->comp_handler_lock, flags);
-               (*cq->ibcq.comp_handler) (&cq->ibcq, cq->ibcq.cq_context);
-               spin_unlock_irqrestore(&cq->comp_handler_lock, flags);
+
+       /* if there is valid buddy cq, look for its completion handler */
+       if (bcq && bcq->ibcq.comp_handler) {
+               spin_lock_irqsave(&bcq->comp_handler_lock, flags);
+               (*bcq->ibcq.comp_handler) (&bcq->ibcq, bcq->ibcq.cq_context);
+               spin_unlock_irqrestore(&bcq->comp_handler_lock, flags);
        }
 }