mirror of
https://github.com/lkl/linux.git
synced 2025-12-19 16:13:19 +09:00
mm: handle userfaults under VMA lock
Enable handle_userfault to operate under VMA lock by releasing VMA lock instead of mmap_lock and retrying. Note that FAULT_FLAG_RETRY_NOWAIT should never be used when handling faults under per-VMA lock protection because that would break the assumption that lock is dropped on retry. [surenb@google.com: fix a lockdep issue in vma_assert_write_locked] Link: https://lkml.kernel.org/r/20230712195652.969194-1-surenb@google.com Link: https://lkml.kernel.org/r/20230630211957.1341547-7-surenb@google.com Signed-off-by: Suren Baghdasaryan <surenb@google.com> Acked-by: Peter Xu <peterx@redhat.com> Cc: Alistair Popple <apopple@nvidia.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christian Brauner <brauner@kernel.org> Cc: Christoph Hellwig <hch@lst.de> Cc: David Hildenbrand <david@redhat.com> Cc: David Howells <dhowells@redhat.com> Cc: Davidlohr Bueso <dave@stgolabs.net> Cc: Hillf Danton <hdanton@sina.com> Cc: "Huang, Ying" <ying.huang@intel.com> Cc: Hugh Dickins <hughd@google.com> Cc: Jan Kara <jack@suse.cz> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Josef Bacik <josef@toxicpanda.com> Cc: Laurent Dufour <ldufour@linux.ibm.com> Cc: Liam R. Howlett <Liam.Howlett@oracle.com> Cc: Lorenzo Stoakes <lstoakes@gmail.com> Cc: Matthew Wilcox <willy@infradead.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Michel Lespinasse <michel@lespinasse.org> Cc: Minchan Kim <minchan@google.com> Cc: Pavel Tatashin <pasha.tatashin@soleen.com> Cc: Punit Agrawal <punit.agrawal@bytedance.com> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Yu Zhao <yuzhao@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
committed by
Andrew Morton
parent
1235ccd05b
commit
29a22b9e08
@@ -679,6 +679,7 @@ static inline void vma_end_read(struct vm_area_struct *vma)
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/* WARNING! Can only be used if mmap_lock is expected to be write-locked */
|
||||
static bool __is_vma_write_locked(struct vm_area_struct *vma, int *mm_lock_seq)
|
||||
{
|
||||
mmap_assert_write_locked(vma->vm_mm);
|
||||
@@ -721,6 +722,12 @@ static inline void vma_assert_write_locked(struct vm_area_struct *vma)
|
||||
VM_BUG_ON_VMA(!__is_vma_write_locked(vma, &mm_lock_seq), vma);
|
||||
}
|
||||
|
||||
static inline void vma_assert_locked(struct vm_area_struct *vma)
|
||||
{
|
||||
if (!rwsem_is_locked(&vma->vm_lock->lock))
|
||||
vma_assert_write_locked(vma);
|
||||
}
|
||||
|
||||
static inline void vma_mark_detached(struct vm_area_struct *vma, bool detached)
|
||||
{
|
||||
/* When detaching vma should be write-locked */
|
||||
@@ -737,6 +744,14 @@ static inline void release_fault_lock(struct vm_fault *vmf)
|
||||
mmap_read_unlock(vmf->vma->vm_mm);
|
||||
}
|
||||
|
||||
static inline void assert_fault_locked(struct vm_fault *vmf)
|
||||
{
|
||||
if (vmf->flags & FAULT_FLAG_VMA_LOCK)
|
||||
vma_assert_locked(vmf->vma);
|
||||
else
|
||||
mmap_assert_locked(vmf->vma->vm_mm);
|
||||
}
|
||||
|
||||
struct vm_area_struct *lock_vma_under_rcu(struct mm_struct *mm,
|
||||
unsigned long address);
|
||||
|
||||
@@ -762,6 +777,11 @@ static inline void release_fault_lock(struct vm_fault *vmf)
|
||||
mmap_read_unlock(vmf->vma->vm_mm);
|
||||
}
|
||||
|
||||
static inline void assert_fault_locked(struct vm_fault *vmf)
|
||||
{
|
||||
mmap_assert_locked(vmf->vma->vm_mm);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PER_VMA_LOCK */
|
||||
|
||||
extern const struct vm_operations_struct vma_dummy_vm_ops;
|
||||
|
||||
Reference in New Issue
Block a user