FROMGIT: mm: allow vma_start_read_locked/vma_start_read_locked_nested to fail
With upcoming replacement of vm_lock with vm_refcnt, we need to handle a possibility of vma_start_read_locked/vma_start_read_locked_nested failing due to refcount overflow. Prepare for such possibility by changing these APIs and adjusting their users. Link: https://lkml.kernel.org/r/20250213224655.1680278-8-surenb@google.com Signed-off-by: Suren Baghdasaryan <surenb@google.com> Cc: Lokesh Gidra <lokeshgidra@google.com> Tested-by: Shivank Garg <shivankg@amd.com> Link: https://lkml.kernel.org/r/5e19ec93-8307-47c2-bb13-3ddf7150624e@amd.com Cc: Christian Brauner <brauner@kernel.org> 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: Hugh Dickins <hughd@google.com> Cc: Jann Horn <jannh@google.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Klara Modin <klarasmodin@gmail.com> Cc: Liam R. Howlett <Liam.Howlett@Oracle.com> Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Cc: Mateusz Guzik <mjguzik@gmail.com> Cc: Matthew Wilcox <willy@infradead.org> Cc: Mel Gorman <mgorman@techsingularity.net> Cc: Michal Hocko <mhocko@suse.com> Cc: Minchan Kim <minchan@google.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Pasha Tatashin <pasha.tatashin@soleen.com> Cc: "Paul E . McKenney" <paulmck@kernel.org> Cc: Peter Xu <peterx@redhat.com> Cc: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Shakeel Butt <shakeel.butt@linux.dev> Cc: Sourav Panda <souravpanda@google.com> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Wei Yang <richard.weiyang@gmail.com> Cc: Will Deacon <will@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> (cherry picked from commit fb9ecf376b469be193e09a2c416c94dc14036adc https: //git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-unstable) Bug: 322132947 Change-Id: Iacd8eb722166af47ac7d14551cee4ecdb1432569 Signed-off-by: Suren Baghdasaryan <surenb@google.com>
This commit is contained in:
committed by
Giuliano Procida
parent
0a886c1125
commit
955dd9159e
+4
-2
@@ -734,10 +734,11 @@ static inline bool vma_start_read(struct vm_area_struct *vma)
|
||||
* not be used in such cases because it might fail due to mm_lock_seq overflow.
|
||||
* This functionality is used to obtain vma read lock and drop the mmap read lock.
|
||||
*/
|
||||
static inline void vma_start_read_locked_nested(struct vm_area_struct *vma, int subclass)
|
||||
static inline bool vma_start_read_locked_nested(struct vm_area_struct *vma, int subclass)
|
||||
{
|
||||
mmap_assert_locked(vma->vm_mm);
|
||||
down_read_nested(&vma->vm_lock.lock, subclass);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -746,10 +747,11 @@ static inline void vma_start_read_locked_nested(struct vm_area_struct *vma, int
|
||||
* not be used in such cases because it might fail due to mm_lock_seq overflow.
|
||||
* This functionality is used to obtain vma read lock and drop the mmap read lock.
|
||||
*/
|
||||
static inline void vma_start_read_locked(struct vm_area_struct *vma)
|
||||
static inline bool vma_start_read_locked(struct vm_area_struct *vma)
|
||||
{
|
||||
mmap_assert_locked(vma->vm_mm);
|
||||
down_read(&vma->vm_lock.lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void vma_end_read(struct vm_area_struct *vma)
|
||||
|
||||
+23
-7
@@ -84,8 +84,12 @@ static struct vm_area_struct *uffd_lock_vma(struct mm_struct *mm,
|
||||
|
||||
mmap_read_lock(mm);
|
||||
vma = find_vma_and_prepare_anon(mm, address);
|
||||
if (!IS_ERR(vma))
|
||||
vma_start_read_locked(vma);
|
||||
if (!IS_ERR(vma)) {
|
||||
bool locked = vma_start_read_locked(vma);
|
||||
|
||||
if (!locked)
|
||||
vma = ERR_PTR(-EAGAIN);
|
||||
}
|
||||
|
||||
mmap_read_unlock(mm);
|
||||
return vma;
|
||||
@@ -1458,12 +1462,24 @@ static int uffd_move_lock(struct mm_struct *mm,
|
||||
|
||||
mmap_read_lock(mm);
|
||||
err = find_vmas_mm_locked(mm, dst_start, src_start, dst_vmap, src_vmap);
|
||||
if (!err) {
|
||||
vma_start_read_locked(*dst_vmap);
|
||||
if (*dst_vmap != *src_vmap)
|
||||
vma_start_read_locked_nested(*src_vmap,
|
||||
SINGLE_DEPTH_NESTING);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (!vma_start_read_locked(*dst_vmap)) {
|
||||
err = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Nothing further to do if both vmas are locked. */
|
||||
if (*dst_vmap == *src_vmap)
|
||||
goto out;
|
||||
|
||||
if (!vma_start_read_locked_nested(*src_vmap, SINGLE_DEPTH_NESTING)) {
|
||||
/* Undo dst_vmap locking if src_vmap failed to lock */
|
||||
vma_end_read(*dst_vmap);
|
||||
err = -EAGAIN;
|
||||
}
|
||||
out:
|
||||
mmap_read_unlock(mm);
|
||||
return err;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user