• Jason Gunthorpe's avatar
    mm/mmu_notifiers: add a get/put scheme for the registration · 2c7933f5
    Jason Gunthorpe authored
    Many places in the kernel have a flow where userspace will create some
    object and that object will need to connect to the subsystem's
    mmu_notifier subscription for the duration of its lifetime.
    
    In this case the subsystem is usually tracking multiple mm_structs and it
    is difficult to keep track of what struct mmu_notifier's have been
    allocated for what mm's.
    
    Since this has been open coded in a variety of exciting ways, provide core
    functionality to do this safely.
    
    This approach uses the struct mmu_notifier_ops * as a key to determine if
    the subsystem has a notifier registered on the mm or not. If there is a
    registration then the existing notifier struct is returned, otherwise the
    ops->alloc_notifiers() is used to create a new per-subsystem notifier for
    the mm.
    
    The destroy side incorporates an async call_srcu based destruction which
    will avoid bugs in the callers such as commit 6d7c3cde ("mm/hmm: fix
    use after free with struct hmm in the mmu notifiers").
    
    Since we are inside the mmu notifier core locking is fairly simple, the
    allocation uses the same approach as for mmu_notifier_mm, the write side
    of the mmap_sem makes everything deterministic and we only need to do
    hlist_add_head_rcu() under the mm_take_all_locks(). The new users count
    and the discoverability in the hlist is fully serialized by the
    mmu_notifier_mm->lock.
    
    Link: https://lore.kernel.org/r/20190806231548.25242-4-jgg@ziepe.caCo-developed-by: default avatarChristoph Hellwig <hch@infradead.org>
    Signed-off-by: default avatarChristoph Hellwig <hch@infradead.org>
    Reviewed-by: default avatarRalph Campbell <rcampbell@nvidia.com>
    Tested-by: default avatarRalph Campbell <rcampbell@nvidia.com>
    Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
    2c7933f5
mmu_notifier.c 16 KB