]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sif: rq: Added synchronization between sif_flush_rq and sif_post_recv
authorWei Lin Guay <wei.lin.guay@oracle.com>
Fri, 24 Jun 2016 13:19:33 +0000 (15:19 +0200)
committerKnut Omang <knut.omang@oracle.com>
Sun, 3 Jul 2016 14:44:17 +0000 (16:44 +0200)
Orabug: 23491094

The sif_flush_rq retrieves the rq_sw->last_seq without acquiring
the rq lock. Thus, adding the lock in sif_flush_rq to ensure that
the FLUSH-IN-ERR completion(rq_sw->last_seq) is only being generated
after post_recv(rq_sw->last_seq) has completed.

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

index 6d120f22e12a7a985e5224b751620f13ad885b9e..bf079af70f83d2ff4ac02de6ec7848922ea45517 100644 (file)
@@ -303,6 +303,7 @@ int sif_flush_rq(struct sif_dev *sdev, struct sif_rq *rq, struct sif_qp *target_
        struct sif_rq_sw *rq_sw = get_sif_rq_sw(sdev, rq->index);
        int ret = 0;
        u32 head, tail;
+       unsigned long flags;
        enum sif_mqp_type mqp_type = SIF_MQP_SW;
        DECLARE_SIF_CQE_POLL(sdev, lcqe);
 
@@ -397,6 +398,7 @@ int sif_flush_rq(struct sif_dev *sdev, struct sif_rq *rq, struct sif_qp *target_
                 * valid:
                 */
 flush_rq_again:
+               spin_lock_irqsave(&rq->lock, flags);
                head = get_psif_rq_hw__head_indx(&rq->d);
                tail = rq_sw->next_seq;
                real_len = rq_length(rq, head, tail & ((1 << 14) - 1)) & ((1 << 14) - 1);
@@ -442,6 +444,7 @@ flush_rq_again:
                                        if (!cq) {
                                                sif_log(sdev, SIF_RQ,
                                                        "recevied cq is NULL");
+                                               spin_unlock_irqrestore(&rq->lock, flags);
                                                goto free_rq_error;
                                        }
                                        cq_sw = get_sif_cq_sw(sdev, cq->index);
@@ -463,6 +466,7 @@ flush_rq_again:
                        }
                        set_bit(FLUSH_RQ_FIRST_TIME, &rq_sw->flags);
                }
+               spin_unlock_irqrestore(&rq->lock, flags);
 
                /* Now find the actual 32 bit seq.no */
                head = tail - real_len;