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. Maybe call the parameter "detaching" and switch the 0 and 1?