|
@@ -1066,7 +1066,7 @@ static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp,
|
|
struct c4iw_cq *schp)
|
|
struct c4iw_cq *schp)
|
|
{
|
|
{
|
|
int count;
|
|
int count;
|
|
- int flushed;
|
|
|
|
|
|
+ int rq_flushed, sq_flushed;
|
|
unsigned long flag;
|
|
unsigned long flag;
|
|
|
|
|
|
PDBG("%s qhp %p rchp %p schp %p\n", __func__, qhp, rchp, schp);
|
|
PDBG("%s qhp %p rchp %p schp %p\n", __func__, qhp, rchp, schp);
|
|
@@ -1084,27 +1084,40 @@ static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp,
|
|
|
|
|
|
c4iw_flush_hw_cq(rchp);
|
|
c4iw_flush_hw_cq(rchp);
|
|
c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count);
|
|
c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count);
|
|
- flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count);
|
|
|
|
|
|
+ rq_flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count);
|
|
spin_unlock(&qhp->lock);
|
|
spin_unlock(&qhp->lock);
|
|
spin_unlock_irqrestore(&rchp->lock, flag);
|
|
spin_unlock_irqrestore(&rchp->lock, flag);
|
|
- if (flushed) {
|
|
|
|
- spin_lock_irqsave(&rchp->comp_handler_lock, flag);
|
|
|
|
- (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context);
|
|
|
|
- spin_unlock_irqrestore(&rchp->comp_handler_lock, flag);
|
|
|
|
- }
|
|
|
|
|
|
|
|
/* locking hierarchy: cq lock first, then qp lock. */
|
|
/* locking hierarchy: cq lock first, then qp lock. */
|
|
spin_lock_irqsave(&schp->lock, flag);
|
|
spin_lock_irqsave(&schp->lock, flag);
|
|
spin_lock(&qhp->lock);
|
|
spin_lock(&qhp->lock);
|
|
if (schp != rchp)
|
|
if (schp != rchp)
|
|
c4iw_flush_hw_cq(schp);
|
|
c4iw_flush_hw_cq(schp);
|
|
- flushed = c4iw_flush_sq(qhp);
|
|
|
|
|
|
+ sq_flushed = c4iw_flush_sq(qhp);
|
|
spin_unlock(&qhp->lock);
|
|
spin_unlock(&qhp->lock);
|
|
spin_unlock_irqrestore(&schp->lock, flag);
|
|
spin_unlock_irqrestore(&schp->lock, flag);
|
|
- if (flushed) {
|
|
|
|
- spin_lock_irqsave(&schp->comp_handler_lock, flag);
|
|
|
|
- (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context);
|
|
|
|
- spin_unlock_irqrestore(&schp->comp_handler_lock, flag);
|
|
|
|
|
|
+
|
|
|
|
+ if (schp == rchp) {
|
|
|
|
+ if (t4_clear_cq_armed(&rchp->cq) &&
|
|
|
|
+ (rq_flushed || sq_flushed)) {
|
|
|
|
+ spin_lock_irqsave(&rchp->comp_handler_lock, flag);
|
|
|
|
+ (*rchp->ibcq.comp_handler)(&rchp->ibcq,
|
|
|
|
+ rchp->ibcq.cq_context);
|
|
|
|
+ spin_unlock_irqrestore(&rchp->comp_handler_lock, flag);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if (t4_clear_cq_armed(&rchp->cq) && rq_flushed) {
|
|
|
|
+ spin_lock_irqsave(&rchp->comp_handler_lock, flag);
|
|
|
|
+ (*rchp->ibcq.comp_handler)(&rchp->ibcq,
|
|
|
|
+ rchp->ibcq.cq_context);
|
|
|
|
+ spin_unlock_irqrestore(&rchp->comp_handler_lock, flag);
|
|
|
|
+ }
|
|
|
|
+ if (t4_clear_cq_armed(&schp->cq) && sq_flushed) {
|
|
|
|
+ spin_lock_irqsave(&schp->comp_handler_lock, flag);
|
|
|
|
+ (*schp->ibcq.comp_handler)(&schp->ibcq,
|
|
|
|
+ schp->ibcq.cq_context);
|
|
|
|
+ spin_unlock_irqrestore(&schp->comp_handler_lock, flag);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|