mm: fix a lockdep issue in vma_assert_write_locked
Subsystems (2)
Suren Baghdasaryan
reviewerPATCH 1/1 mm: fix a lockdep issue in vma_assert_write_locked
__is_vma_write_locked() can be used only when mmap_lock is write-locked to guarantee vm_lock_seq and mm_lock_seq stability during the check. Therefore it asserts this condition before further checks. Because of that it can't be used unless the user expects the mmap_lock to be write-locked. vma_assert_locked() can't assume this before ensuring that VMA is not read-locked.
Change the order of the checks in vma_assert_locked() to check if the VMA is read-locked first and only then assert if it's not write-locked.
--- include/linux/mm.h | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
include/linux/mm.h +6 -10
@@ -668,6 +668,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);
@@ -707,22 +708,17 @@ static inline bool vma_try_start_write(struct vm_area_struct *vma)return true; } -static inline void vma_assert_locked (struct vm_area_struct *vma) +static inline void vma_assert_write_locked (struct vm_area_struct *vma) {int mm_lock_seq; -if (__is_vma_write_locked (vma, &mm_lock_seq)) -return ; - -lockdep_assert_held (&vma->vm_lock->lock); -VM_BUG_ON_VMA (!rwsem_is_locked (&vma->vm_lock->lock), vma); +VM_BUG_ON_VMA (!__is_vma_write_locked (vma, &mm_lock_seq), vma); } -static inline void vma_assert_write_locked (struct vm_area_struct *vma) +static inline void vma_assert_locked (struct vm_area_struct *vma) { -int mm_lock_seq; - -VM_BUG_ON_VMA (!__is_vma_write_locked (vma, &mm_lock_seq), 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)
Signature · 1 line
2.41.0.455.g037347b96a-goog
Suren Baghdasaryan
reviewerQuoted 10 lines · Suren Baghdasaryan
__is_vma_write_locked()can be used only whenmmap_lockis write-locked to guaranteevm_lock_seqandmm_lock_seqstability during the check. Therefore it asserts this condition before further checks. Because of that it can't be used unless the user expects themmap_lockto be write-locked.vma_assert_locked()can't assume this before ensuring that VMA is not read-locked.
Change the order of the checks invma_assert_locked()to check if the VMA is read-locked first and only then assert if it's not write-locked.
Quoted 6 lines
Fixes 50b88b63e3e4 ("mm: handle userfaults under VMA lock")Reported-by Liam R. Howlett <[email protected]>Reported-by [email protected]Signed-off-by Suren Baghdasaryan <[email protected]>
Should have mentioned that this patch is for mm-unstable.
Quoted 47 lines
--- include/linux/mm.h | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)include/linux/mm.h +6
-11@@ -668,6 +668,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);@@ -707,22 +708,17 @@ static inline bool vma_try_start_write(struct vm_area_struct *vma)return true; } -static inline void vma_assert_locked (struct vm_area_struct *vma) +static inline void vma_assert_write_locked (struct vm_area_struct *vma) {int mm_lock_seq; -if (__is_vma_write_locked (vma, &mm_lock_seq)) -return ; - -lockdep_assert_held (&vma->vm_lock->lock); -VM_BUG_ON_VMA (!rwsem_is_locked (&vma->vm_lock->lock), vma); +VM_BUG_ON_VMA (!__is_vma_write_locked (vma, &mm_lock_seq), vma); } -static inline void vma_assert_write_locked (struct vm_area_struct *vma) +static inline void vma_assert_locked (struct vm_area_struct *vma) { -int mm_lock_seq; - -VM_BUG_ON_VMA (!__is_vma_write_locked (vma, &mm_lock_seq), 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) --2.41.0.455.g037347b96a-goog