Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/vma: add+use vma lockdep acquire/release defines

The code is littered with inscrutable and duplicative lockdep
incantations, replace these with defines which explain what is going on
and add commentary to explain what we're doing.

If lockdep is disabled these become no-ops. We must use defines so
_RET_IP_ remains meaningful.

These are self-documenting and aid readability of the code.

Additionally, instead of using the confusing rwsem_*() form for something
that is emphatically not an rwsem, we instead explicitly use
lock_[acquired, release]_shared/exclusive() lockdep invocations since we
are doing something rather custom here and these make more sense to use.

No functional change intended.

Link: https://lkml.kernel.org/r/fdae72441949ecf3b4a0ed3510da803e881bb153.1769198904.git.lorenzo.stoakes@oracle.com
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Reviewed-by: Suren Baghdasaryan <surenb@google.com>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Waiman Long <longman@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Lorenzo Stoakes and committed by
Andrew Morton
1f2e7efc 180355d4

+39 -8
+34 -3
include/linux/mmap_lock.h
··· 78 78 79 79 #ifdef CONFIG_PER_VMA_LOCK 80 80 81 + /* 82 + * VMA locks do not behave like most ordinary locks found in the kernel, so we 83 + * cannot quite have full lockdep tracking in the way we would ideally prefer. 84 + * 85 + * Read locks act as shared locks which exclude an exclusive lock being 86 + * taken. We therefore mark these accordingly on read lock acquire/release. 87 + * 88 + * Write locks are acquired exclusively per-VMA, but released in a shared 89 + * fashion, that is upon vma_end_write_all(), we update the mmap's seqcount such 90 + * that write lock is released. 91 + * 92 + * We therefore cannot track write locks per-VMA, nor do we try. Mitigating this 93 + * is the fact that, of course, we do lockdep-track the mmap lock rwsem which 94 + * must be held when taking a VMA write lock. 95 + * 96 + * We do, however, want to indicate that during either acquisition of a VMA 97 + * write lock or detachment of a VMA that we require the lock held be exclusive, 98 + * so we utilise lockdep to do so. 99 + */ 100 + #define __vma_lockdep_acquire_read(vma) \ 101 + lock_acquire_shared(&vma->vmlock_dep_map, 0, 1, NULL, _RET_IP_) 102 + #define __vma_lockdep_release_read(vma) \ 103 + lock_release(&vma->vmlock_dep_map, _RET_IP_) 104 + #define __vma_lockdep_acquire_exclusive(vma) \ 105 + lock_acquire_exclusive(&vma->vmlock_dep_map, 0, 0, NULL, _RET_IP_) 106 + #define __vma_lockdep_release_exclusive(vma) \ 107 + lock_release(&vma->vmlock_dep_map, _RET_IP_) 108 + /* Only meaningful if CONFIG_LOCK_STAT is defined. */ 109 + #define __vma_lockdep_stat_mark_acquired(vma) \ 110 + lock_acquired(&vma->vmlock_dep_map, _RET_IP_) 111 + 81 112 static inline void mm_lock_seqcount_init(struct mm_struct *mm) 82 113 { 83 114 seqcount_init(&mm->mm_lock_seq); ··· 207 176 struct mm_struct *mm = vma->vm_mm; 208 177 int newcnt; 209 178 210 - rwsem_release(&vma->vmlock_dep_map, _RET_IP_); 211 - 179 + __vma_lockdep_release_read(vma); 212 180 newcnt = __vma_refcount_put_return(vma); 181 + 213 182 /* 214 183 * __vma_enter_locked() may be sleeping waiting for readers to drop 215 184 * their reference count, so wake it up if we were the last reader ··· 238 207 VM_REFCNT_LIMIT))) 239 208 return false; 240 209 241 - rwsem_acquire_read(&vma->vmlock_dep_map, 0, 1, _RET_IP_); 210 + __vma_lockdep_acquire_read(vma); 242 211 return true; 243 212 } 244 213
+5 -5
mm/mmap_lock.c
··· 72 72 if (!refcount_add_not_zero(VM_REFCNT_EXCLUDE_READERS_FLAG, &vma->vm_refcnt)) 73 73 return 0; 74 74 75 - rwsem_acquire(&vma->vmlock_dep_map, 0, 0, _RET_IP_); 75 + __vma_lockdep_acquire_exclusive(vma); 76 76 err = rcuwait_wait_event(&vma->vm_mm->vma_writer_wait, 77 77 refcount_read(&vma->vm_refcnt) == tgt_refcnt, 78 78 state); ··· 85 85 WARN_ON_ONCE(!detaching); 86 86 err = 0; 87 87 } 88 - rwsem_release(&vma->vmlock_dep_map, _RET_IP_); 88 + __vma_lockdep_release_exclusive(vma); 89 89 return err; 90 90 } 91 - lock_acquired(&vma->vmlock_dep_map, _RET_IP_); 91 + __vma_lockdep_stat_mark_acquired(vma); 92 92 93 93 return 1; 94 94 } ··· 97 97 { 98 98 *detached = refcount_sub_and_test(VM_REFCNT_EXCLUDE_READERS_FLAG, 99 99 &vma->vm_refcnt); 100 - rwsem_release(&vma->vmlock_dep_map, _RET_IP_); 100 + __vma_lockdep_release_exclusive(vma); 101 101 } 102 102 103 103 int __vma_start_write(struct vm_area_struct *vma, unsigned int mm_lock_seq, ··· 204 204 goto err; 205 205 } 206 206 207 - rwsem_acquire_read(&vma->vmlock_dep_map, 0, 1, _RET_IP_); 207 + __vma_lockdep_acquire_read(vma); 208 208 209 209 if (unlikely(vma->vm_mm != mm)) 210 210 goto err_unstable;