OSDN Git Service

RDMA/odp: Lift umem_mutex out of ib_umem_odp_unmap_dma_pages()
authorJason Gunthorpe <jgg@mellanox.com>
Tue, 1 Oct 2019 15:38:18 +0000 (12:38 -0300)
committerJason Gunthorpe <jgg@mellanox.com>
Fri, 4 Oct 2019 18:54:21 +0000 (15:54 -0300)
commit9dc775e7f5508f848661bbfb2e15683affb85f24
treeaeb8c269379663f95cb5a03a9d2b1a7b264d8a01
parentf28b1932eaae183b80bd8c7abecae167a0e5c61a
RDMA/odp: Lift umem_mutex out of ib_umem_odp_unmap_dma_pages()

This fixes a race of the form:
    CPU0                               CPU1
mlx5_ib_invalidate_range()     mlx5_ib_invalidate_range()
 // This one actually makes npages == 0
 ib_umem_odp_unmap_dma_pages()
 if (npages == 0 && !dying)
  // This one does nothing
  ib_umem_odp_unmap_dma_pages()
  if (npages == 0 && !dying)
     dying = 1;
                                    dying = 1;
    schedule_work(&umem_odp->work);
     // Double schedule of the same work
     schedule_work(&umem_odp->work);  // BOOM

npages and dying must be read and written under the umem_mutex lock.

Since whenever ib_umem_odp_unmap_dma_pages() is called mlx5 must also call
mlx5_ib_update_xlt, and both need to be done in the same locking region,
hoist the lock out of unmap.

This avoids an expensive double critical section in
mlx5_ib_invalidate_range().

Fixes: 81713d3788d2 ("IB/mlx5: Add implicit MR support")
Link: https://lore.kernel.org/r/20191001153821.23621-4-jgg@ziepe.ca
Reviewed-by: Artemy Kovalyov <artemyko@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/umem_odp.c
drivers/infiniband/hw/mlx5/odp.c