lkml.org 
[lkml]   [2022]   [Jun]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.10 01/26] IB/rdmavt: add missing locks in rvt_ruc_loopback
    Date
    From: Niels Dossche <dossche.niels@gmail.com>

    [ Upstream commit 22cbc6c2681a0a4fe76150270426e763d52353a4 ]

    The documentation of the function rvt_error_qp says both r_lock and
    s_lock need to be held when calling that function.
    It also asserts using lockdep that both of those locks are held.
    rvt_error_qp is called form rvt_send_cq, which is called from
    rvt_qp_complete_swqe, which is called from rvt_send_complete, which is
    called from rvt_ruc_loopback in two places. Both of these places do not
    hold r_lock. Fix this by acquiring a spin_lock of r_lock in both of
    these places.
    The r_lock acquiring cannot be added in rvt_qp_complete_swqe because
    some of its other callers already have r_lock acquired.

    Link: https://lore.kernel.org/r/20220228195144.71946-1-dossche.niels@gmail.com
    Signed-off-by: Niels Dossche <dossche.niels@gmail.com>
    Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/infiniband/sw/rdmavt/qp.c | 6 +++++-
    1 file changed, 5 insertions(+), 1 deletion(-)

    diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c
    index d8d52a00a1be..585a9c76e518 100644
    --- a/drivers/infiniband/sw/rdmavt/qp.c
    +++ b/drivers/infiniband/sw/rdmavt/qp.c
    @@ -2826,7 +2826,7 @@ void rvt_qp_iter(struct rvt_dev_info *rdi,
    EXPORT_SYMBOL(rvt_qp_iter);

    /*
    - * This should be called with s_lock held.
    + * This should be called with s_lock and r_lock held.
    */
    void rvt_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe,
    enum ib_wc_status status)
    @@ -3185,7 +3185,9 @@ void rvt_ruc_loopback(struct rvt_qp *sqp)
    rvp->n_loop_pkts++;
    flush_send:
    sqp->s_rnr_retry = sqp->s_rnr_retry_cnt;
    + spin_lock(&sqp->r_lock);
    rvt_send_complete(sqp, wqe, send_status);
    + spin_unlock(&sqp->r_lock);
    if (local_ops) {
    atomic_dec(&sqp->local_ops_pending);
    local_ops = 0;
    @@ -3239,7 +3241,9 @@ void rvt_ruc_loopback(struct rvt_qp *sqp)
    spin_unlock_irqrestore(&qp->r_lock, flags);
    serr_no_r_lock:
    spin_lock_irqsave(&sqp->s_lock, flags);
    + spin_lock(&sqp->r_lock);
    rvt_send_complete(sqp, wqe, send_status);
    + spin_unlock(&sqp->r_lock);
    if (sqp->ibqp.qp_type == IB_QPT_RC) {
    int lastwqe;

    --
    2.35.1
    \
     
     \ /
      Last update: 2022-06-01 16:09    [W:7.399 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site