• Jason Gunthorpe's avatar
    RDMA/odp: Lift umem_mutex out of ib_umem_odp_unmap_dma_pages() · 9dc775e7
    Jason Gunthorpe authored
    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: 81713d37 ("IB/mlx5: Add implicit MR support")
    Link: https://lore.kernel.org/r/20191001153821.23621-4-jgg@ziepe.caReviewed-by: default avatarArtemy Kovalyov <artemyko@mellanox.com>
    Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
    9dc775e7
umem_odp.c 22.8 KB