On Fri, Jan 10, 2025 at 2:26 PM Vlastimil Babka <vbabka@xxxxxxx> wrote: > > On 1/10/25 16:56, Suren Baghdasaryan wrote: > >> > --- a/mm/memory.c > >> > +++ b/mm/memory.c > >> > @@ -6370,9 +6370,41 @@ struct vm_area_struct *lock_mm_and_find_vma(struct mm_struct *mm, > >> > #endif > >> > > >> > #ifdef CONFIG_PER_VMA_LOCK > >> > +static inline bool __vma_enter_locked(struct vm_area_struct *vma, unsigned int tgt_refcnt) > >> > +{ > >> > + /* > >> > + * If vma is detached then only vma_mark_attached() can raise the > >> > + * vm_refcnt. mmap_write_lock prevents racing with vma_mark_attached(). > >> > + */ > >> > + if (!refcount_add_not_zero(VMA_LOCK_OFFSET, &vma->vm_refcnt)) > >> > + return false; > >> > + > >> > + rwsem_acquire(&vma->vmlock_dep_map, 0, 0, _RET_IP_); > >> > + rcuwait_wait_event(&vma->vm_mm->vma_writer_wait, > >> > + refcount_read(&vma->vm_refcnt) == tgt_refcnt, > >> > + TASK_UNINTERRUPTIBLE); > >> > + lock_acquired(&vma->vmlock_dep_map, _RET_IP_); > >> > + > >> > + return true; > >> > +} > >> > + > >> > +static inline void __vma_exit_locked(struct vm_area_struct *vma, bool *detached) > >> > +{ > >> > + *detached = refcount_sub_and_test(VMA_LOCK_OFFSET, &vma->vm_refcnt); > >> > + rwsem_release(&vma->vmlock_dep_map, _RET_IP_); > >> > +} > >> > + > >> > void __vma_start_write(struct vm_area_struct *vma, unsigned int mm_lock_seq) > >> > { > >> > - down_write(&vma->vm_lock.lock); > >> > + bool locked; > >> > + > >> > + /* > >> > + * __vma_enter_locked() returns false immediately if the vma is not > >> > + * attached, otherwise it waits until refcnt is (VMA_LOCK_OFFSET + 1) > >> > + * indicating that vma is attached with no readers. > >> > + */ > >> > + locked = __vma_enter_locked(vma, VMA_LOCK_OFFSET + 1); > >> > >> Wonder if it would be slightly better if tgt_refcount was just 1 (or 0 > >> below in vma_mark_detached()) and the VMA_LOCK_OFFSET added to it in > >> __vma_enter_locked() itself as it's the one adding it in the first place. > > > > Well, it won't be called tgt_refcount then. Maybe "bool vma_attached" > > and inside __vma_enter_locked() we do: > > > > unsigned int tgt_refcnt = VMA_LOCK_OFFSET + vma_attached ? 1 : 0; > > > > Is that better? > > Yeah I think so as it centralizes the target refcount logic into a single > place __vma_enter_locked(). > Hm but then it's weird that __vma_start_write() would set vma_attached to > true and yet it handles also a case where it's not attached. Ah, good point. > Maybe call the parameter "detaching" and switch the 0 and 1? Yes, that would be less confusing. Thanks for the suggestion, I'll use it.