lkml.org 
[lkml]   [2019]   [Nov]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.3 041/163] RDMA/mlx5: Order num_pending_prefetch properly with synchronize_srcu
    Date
    From: Jason Gunthorpe <jgg@mellanox.com>

    [ Upstream commit aa116b810ac9077a263ed8679fb4d595f180e0eb ]

    During destroy setting live = 0 and then synchronize_srcu() prevents
    num_pending_prefetch from incrementing, and also, ensures that all work
    holding that count is queued on the WQ. Testing before causes races of the
    form:

    CPU0 CPU1
    dereg_mr()
    mlx5_ib_advise_mr_prefetch()
    srcu_read_lock()
    num_pending_prefetch_inc()
    if (!live)
    live = 0
    atomic_read() == 0
    // skip flush_workqueue()
    atomic_inc()
    queue_work();
    srcu_read_unlock()
    WARN_ON(atomic_read()) // Fails

    Swap the order so that the synchronize_srcu() prevents this.

    Fixes: a6bc3875f176 ("IB/mlx5: Protect against prefetch of invalid MR")
    Link: https://lore.kernel.org/r/20191001153821.23621-5-jgg@ziepe.ca
    Reviewed-by: Artemy Kovalyov <artemyko@mellanox.com>
    Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/infiniband/hw/mlx5/mr.c | 5 +++--
    1 file changed, 3 insertions(+), 2 deletions(-)

    diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
    index c4ba8838d2c46..96c8a6835592d 100644
    --- a/drivers/infiniband/hw/mlx5/mr.c
    +++ b/drivers/infiniband/hw/mlx5/mr.c
    @@ -1591,13 +1591,14 @@ static void dereg_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
    */
    mr->live = 0;

    + /* Wait for all running page-fault handlers to finish. */
    + synchronize_srcu(&dev->mr_srcu);
    +
    /* dequeue pending prefetch requests for the mr */
    if (atomic_read(&mr->num_pending_prefetch))
    flush_workqueue(system_unbound_wq);
    WARN_ON(atomic_read(&mr->num_pending_prefetch));

    - /* Wait for all running page-fault handlers to finish. */
    - synchronize_srcu(&dev->mr_srcu);
    /* Destroy all page mappings */
    if (umem_odp->page_list)
    mlx5_ib_invalidate_range(umem_odp,
    --
    2.20.1


    \
     
     \ /
      Last update: 2019-11-04 23:16    [W:4.121 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site