@@ -676,6 +676,13 @@ static inline void vma_assert_write_locked(struct vm_area_struct *vma, int pos)
VM_BUG_ON_VMA(vma->vm_lock_seq != READ_ONCE(vma->vm_mm->mm_lock_seq), vma);
}
+static inline void vma_assert_no_reader(struct vm_area_struct *vma)
+{
+ VM_BUG_ON_VMA(rwsem_is_locked(&vma->lock) &&
+ vma->vm_lock_seq != READ_ONCE(vma->vm_mm->mm_lock_seq),
+ vma);
+}
+
#else /* CONFIG_PER_VMA_LOCK */
static inline void vma_init_lock(struct vm_area_struct *vma) {}
@@ -685,6 +692,7 @@ static inline bool vma_read_trylock(struct vm_area_struct *vma)
static inline void vma_read_unlock(struct vm_area_struct *vma) {}
static inline void vma_assert_locked(struct vm_area_struct *vma) {}
static inline void vma_assert_write_locked(struct vm_area_struct *vma, int pos) {}
+static inline void vma_assert_no_reader(struct vm_area_struct *vma) {}
#endif /* CONFIG_PER_VMA_LOCK */
@@ -487,6 +487,8 @@ static void __vm_area_free(struct rcu_head *head)
{
struct vm_area_struct *vma = container_of(head, struct vm_area_struct,
vm_rcu);
+ /* The vma should either have no lock holders or be write-locked. */
+ vma_assert_no_reader(vma);
kmem_cache_free(vm_area_cachep, vma);
}
#endif
Assert there are no holders of VMA lock for reading when it is about to be destroyed. Signed-off-by: Suren Baghdasaryan <surenb@google.com> --- include/linux/mm.h | 8 ++++++++ kernel/fork.c | 2 ++ 2 files changed, 10 insertions(+)