RDMA/ocrdma: Allow expansion of the SQ CQEs via buddy CQ expansion of the QP
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>
This commit is contained in:
Родитель
380676ea2b
Коммит
043e9deed9
|
@ -834,20 +834,20 @@ static int ocrdma_mq_cq_handler(struct ocrdma_dev *dev, u16 cq_id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ocrdma_qp_buddy_cq_handler(struct ocrdma_dev *dev,
|
static struct ocrdma_cq *_ocrdma_qp_buddy_cq_handler(struct ocrdma_dev *dev,
|
||||||
struct ocrdma_cq *cq)
|
struct ocrdma_cq *cq, bool sq)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct ocrdma_qp *qp;
|
struct ocrdma_qp *qp;
|
||||||
bool buddy_cq_found = false;
|
struct list_head *cur;
|
||||||
/* Go through list of QPs in error state which are using this CQ
|
struct ocrdma_cq *bcq = NULL;
|
||||||
* and invoke its callback handler to trigger CQE processing for
|
struct list_head *head = sq?(&cq->sq_head):(&cq->rq_head);
|
||||||
* error/flushed CQE. It is rare to find more than few entries in
|
|
||||||
* this list as most consumers stops after getting error CQE.
|
list_for_each(cur, head) {
|
||||||
* List is traversed only once when a matching buddy cq found for a QP.
|
if (sq)
|
||||||
*/
|
qp = list_entry(cur, struct ocrdma_qp, sq_entry);
|
||||||
spin_lock_irqsave(&dev->flush_q_lock, flags);
|
else
|
||||||
list_for_each_entry(qp, &cq->sq_head, sq_entry) {
|
qp = list_entry(cur, struct ocrdma_qp, rq_entry);
|
||||||
|
|
||||||
if (qp->srq)
|
if (qp->srq)
|
||||||
continue;
|
continue;
|
||||||
/* if wq and rq share the same cq, than comp_handler
|
/* 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 completion came on rq, sq's cq is buddy cq.
|
||||||
*/
|
*/
|
||||||
if (qp->sq_cq == cq)
|
if (qp->sq_cq == cq)
|
||||||
cq = qp->rq_cq;
|
bcq = qp->rq_cq;
|
||||||
else
|
else
|
||||||
cq = qp->sq_cq;
|
bcq = qp->sq_cq;
|
||||||
buddy_cq_found = true;
|
return bcq;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
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);
|
spin_unlock_irqrestore(&dev->flush_q_lock, flags);
|
||||||
if (buddy_cq_found == false)
|
|
||||||
return;
|
/* if there is valid buddy cq, look for its completion handler */
|
||||||
if (cq->ibcq.comp_handler) {
|
if (bcq && bcq->ibcq.comp_handler) {
|
||||||
spin_lock_irqsave(&cq->comp_handler_lock, flags);
|
spin_lock_irqsave(&bcq->comp_handler_lock, flags);
|
||||||
(*cq->ibcq.comp_handler) (&cq->ibcq, cq->ibcq.cq_context);
|
(*bcq->ibcq.comp_handler) (&bcq->ibcq, bcq->ibcq.cq_context);
|
||||||
spin_unlock_irqrestore(&cq->comp_handler_lock, flags);
|
spin_unlock_irqrestore(&bcq->comp_handler_lock, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче