]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sif: cq: Do not invalidate the CQ until completion of events
authorWei Lin Guay <wei.lin.guay@oracle.com>
Tue, 14 Jun 2016 12:33:07 +0000 (14:33 +0200)
committerKnut Omang <knut.omang@oracle.com>
Sun, 3 Jul 2016 14:01:47 +0000 (16:01 +0200)
The CQ completion event might be performed while the CQ
has been invalidated. Besides, adding a check in the
sif_req_notify_cq for not rearming the CQ if the CQ
has been invalidated.

This fixes a scenario reported in Orabug: #23491094.

Signed-off-by: Wei Lin Guay <wei.lin.guay@oracle.com>
Reviewed-by: Knut Omang <knut.omang@oracle.com>
drivers/infiniband/hw/sif/sif_cq.c

index 08466881ceed93fa437e663549107d8e54a416e3..7d0dc4b8fd6f5ff8dc583aa7ab46aaef5ef2badb 100644 (file)
@@ -325,6 +325,12 @@ int destroy_cq(struct sif_cq *cq)
                atomic_add(miss_cnt, &sdev->cq_miss_cnt);
                atomic_add(miss_occ, &sdev->cq_miss_occ);
        }
+
+       /* Wait for any in-progress event queue entry for this CQ to be finished */
+       if (atomic_dec_and_test(&cq->refcnt))
+               complete(&cq->cleanup_ok);
+       wait_for_completion(&cq->cleanup_ok);
+
        ret = sif_invalidate_cq_hw(sdev, index, PCM_WAIT);
        if (ret) {
                sif_log(sdev, SIF_INFO,
@@ -347,11 +353,6 @@ int sif_release_cq(struct sif_dev *sdev, int index)
        struct sif_pd *pd = cq->pd;
        struct sif_cq_sw *cq_sw = get_sif_cq_sw(sdev, index);
 
-       /* Wait for any in-progress event queue entry for this CQ to be finished */
-       if (atomic_dec_and_test(&cq->refcnt))
-               complete(&cq->cleanup_ok);
-       wait_for_completion(&cq->cleanup_ok);
-
        /* Make sure any completions on the cq TLB invalidate
         * for priv.qp does arrive before the cq is destroyed..
         */
@@ -907,6 +908,10 @@ int sif_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
        if (flags & IB_CQ_SOLICITED)
                wr.se = 1;
 
+       /* If a CQ is not valid, do not rearm the CQ. */
+       if (!get_psif_cq_hw__valid(&cq->d))
+               return 0;
+
        /* We should never miss events in psif so we have no need for a separate
         *  handling of IB_CQ_REPORT_MISSED_EVENTS - ignore it.
         */