From: Hariprasad S Date: Wed, 17 Dec 2014 08:41:02 +0000 (+0530) Subject: RDMA/cxgb4: Serialize CQ event upcalls with CQ destruction X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=c62e68963106fb4d3f45e023e8ab21f1ad2d066e;p=linux-beck.git RDMA/cxgb4: Serialize CQ event upcalls with CQ destruction A race exists where the application can be destroying the CQ concurrently with a HW interrupt indicating a completion has been inserted into the CQ. This can cause an event notification upcall to the application after the CQ has been destroyed. The solution is to serialize looking up the CQ in the IDR table and referencing the CQ in c4iw_ev_handler() with removing the CQID from the IDR table and blocking until the refcnt reaches 0 in c4iw_destroy_cq(). Signed-off-by: Steve Wise Signed-off-by: Hariprasad Shenai Signed-off-by: Roland Dreier --- diff --git a/drivers/infiniband/hw/cxgb4/ev.c b/drivers/infiniband/hw/cxgb4/ev.c index c9df0549f51d..4498a89f4ced 100644 --- a/drivers/infiniband/hw/cxgb4/ev.c +++ b/drivers/infiniband/hw/cxgb4/ev.c @@ -225,13 +225,20 @@ int c4iw_ev_handler(struct c4iw_dev *dev, u32 qid) 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); t4_clear_cq_armed(&chp->cq); 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 { PDBG("%s unknown cqid 0x%x\n", __func__, qid); + spin_unlock_irqrestore(&dev->lock, flag); + } return 0; }