diff options
author | Kalderon, Michal <Michal.Kalderon@cavium.com> | 2018-04-05 09:59:29 +0300 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2018-04-05 11:10:14 -0600 |
commit | 09c4854fde84421726a90249b4c20df2492f425f (patch) | |
tree | 92ccd2ca5b71eeffbe639218e52865c4fbce7e5a /drivers | |
parent | 39e00b6cf65831469a57333a929b8ca986892798 (diff) | |
download | linux-09c4854fde84421726a90249b4c20df2492f425f.tar.bz2 |
RDMA/qedr: Fix wmb usage in qedr
This patch comes as a result of Sinan Kaya's work and the decision that
writel() must be a strong enough barrier for DMA.
wmb usages in qedr driver have either been removed where they were there
only to order DMA accesses, and replaced with smp_wmb and comments for the
places that the barrier was there for SMP reasons.
Fixes: 561e5d48968b ("RDMA/qedr: eliminate duplicate barriers on weakly-ordered archs")
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/hw/qedr/verbs.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c index 1835dc9eb3e3..26a698927d2e 100644 --- a/drivers/infiniband/hw/qedr/verbs.c +++ b/drivers/infiniband/hw/qedr/verbs.c @@ -804,8 +804,6 @@ static inline void qedr_init_cq_params(struct qedr_cq *cq, static void doorbell_cq(struct qedr_cq *cq, u32 cons, u8 flags) { - /* Flush data before signalling doorbell */ - wmb(); cq->db.data.agg_flags = flags; cq->db.data.value = cpu_to_le32(cons); writeq(cq->db.raw, cq->db_addr); @@ -1812,8 +1810,7 @@ static int qedr_update_qp_state(struct qedr_dev *dev, */ if (rdma_protocol_roce(&dev->ibdev, 1)) { - wmb(); - writel_relaxed(qp->rq.db_data.raw, qp->rq.db); + writel(qp->rq.db_data.raw, qp->rq.db); /* Make sure write takes effect */ mmiowb(); } @@ -3198,9 +3195,16 @@ int qedr_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, * vane. However this is not harmful (as long as the producer value is * unchanged). For performance reasons we avoid checking for this * redundant doorbell. + * + * qp->wqe_wr_id is accessed during qedr_poll_cq, as + * soon as we give the doorbell, we could get a completion + * for this wr, therefore we need to make sure that the + * memory is updated before giving the doorbell. + * During qedr_poll_cq, rmb is called before accessing the + * cqe. This covers for the smp_rmb as well. */ - wmb(); - writel_relaxed(qp->sq.db_data.raw, qp->sq.db); + smp_wmb(); + writel(qp->sq.db_data.raw, qp->sq.db); /* Make sure write sticks */ mmiowb(); @@ -3286,8 +3290,14 @@ int qedr_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr, qedr_inc_sw_prod(&qp->rq); - /* Flush all the writes before signalling doorbell */ - wmb(); + /* qp->rqe_wr_id is accessed during qedr_poll_cq, as + * soon as we give the doorbell, we could get a completion + * for this wr, therefore we need to make sure that the + * memory is update before giving the doorbell. + * During qedr_poll_cq, rmb is called before accessing the + * cqe. This covers for the smp_rmb as well. + */ + smp_wmb(); qp->rq.db_data.data.value++; |