• Jason Gunthorpe's avatar
    RDMA/odp: Use mmu_interval_notifier_insert() · f25a546e
    Jason Gunthorpe authored
    Replace the internal interval tree based mmu notifier with the new common
    mmu_interval_notifier_insert() API. This removes a lot of code and fixes a
    deadlock that can be triggered in ODP:
    
     zap_page_range()
      mmu_notifier_invalidate_range_start()
       [..]
        ib_umem_notifier_invalidate_range_start()
           down_read(&per_mm->umem_rwsem)
      unmap_single_vma()
        [..]
          __split_huge_page_pmd()
            mmu_notifier_invalidate_range_start()
            [..]
               ib_umem_notifier_invalidate_range_start()
                  down_read(&per_mm->umem_rwsem)   // DEADLOCK
    
            mmu_notifier_invalidate_range_end()
               up_read(&per_mm->umem_rwsem)
      mmu_notifier_invalidate_range_end()
         up_read(&per_mm->umem_rwsem)
    
    The umem_rwsem is held across the range_start/end as the ODP algorithm for
    invalidate_range_end cannot tolerate changes to the interval
    tree. However, due to the nested invalidation regions the second
    down_read() can deadlock if there are competing writers. The new core code
    provides an alternative scheme to solve this problem.
    
    Fixes: ca748c39 ("RDMA/umem: Get rid of per_mm->notifier_count")
    Link: https://lore.kernel.org/r/20191112202231.3856-6-jgg@ziepe.caTested-by: default avatarArtemy Kovalyov <artemyko@mellanox.com>
    Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
    f25a546e
ib_umem_odp.h 4.82 KB