summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornp <np@FreeBSD.org>2016-06-01 18:46:54 +0000
committernp <np@FreeBSD.org>2016-06-01 18:46:54 +0000
commitca40d6fbcb0eb738d074fb7f45127d0722832b12 (patch)
tree1c8f1f50dbfff55accf6c1d014e832401ea75d2e
parent25669dd1d9562b9b1717d5ef59b15e1716c81634 (diff)
downloadFreeBSD-src-ca40d6fbcb0eb738d074fb7f45127d0722832b12.zip
FreeBSD-src-ca40d6fbcb0eb738d074fb7f45127d0722832b12.tar.gz
iw_cxgbe: Fix panic that occurs when c4iw_ev_handler tries to acquire
comp_handler_lock but c4iw_destroy_cq has already freed the CQ memory (which is where the lock resides). Submitted by: Krishnamraju Eraparaju @ Chelsio Sponsored by: Chelsio Communications
-rw-r--r--sys/dev/cxgbe/iw_cxgbe/ev.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/sys/dev/cxgbe/iw_cxgbe/ev.c b/sys/dev/cxgbe/iw_cxgbe/ev.c
index b0a9e13..f4ea0c7 100644
--- a/sys/dev/cxgbe/iw_cxgbe/ev.c
+++ b/sys/dev/cxgbe/iw_cxgbe/ev.c
@@ -194,13 +194,22 @@ int c4iw_ev_handler(struct sge_iq *iq, const struct rsp_ctrl *rc)
struct c4iw_cq *chp;
unsigned long flag;
+ spin_lock_irqsave(&dev->lock, flag);
chp = get_chp(dev, qid);
if (chp) {
+ atomic_inc(&chp->refcnt);
+ spin_unlock_irqrestore(&dev->lock, flag);
+
spin_lock_irqsave(&chp->comp_handler_lock, flag);
(*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context);
spin_unlock_irqrestore(&chp->comp_handler_lock, flag);
- } else
+ if (atomic_dec_and_test(&chp->refcnt))
+ wake_up(&chp->wait);
+ } else {
CTR2(KTR_IW_CXGBE, "%s unknown cqid 0x%x", __func__, qid);
+ spin_unlock_irqrestore(&dev->lock, flag);
+ }
+
return 0;
}
#endif
OpenPOWER on IntegriCloud