On Fri, Jun 9, 2023 at 8:03 AM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote: > > On Thu, Jun 08, 2023 at 05:51:57PM -0700, Suren Baghdasaryan wrote: > > static inline bool folio_lock_or_retry(struct folio *folio, > > - struct mm_struct *mm, unsigned int flags) > > + struct vm_area_struct *vma, unsigned int flags, > > + bool *lock_dropped) > > I hate these double-return-value functions. > > How about this for an API: > > vm_fault_t folio_lock_fault(struct folio *folio, struct vm_fault *vmf) > { > might_sleep(); > if (folio_trylock(folio)) > return 0; > return __folio_lock_fault(folio, vmf); > } > > Then the users look like ... > > > @@ -3580,8 +3581,10 @@ static vm_fault_t remove_device_exclusive_entry(struct vm_fault *vmf) > > if (!folio_try_get(folio)) > > return 0; > > > > - if (!folio_lock_or_retry(folio, vma->vm_mm, vmf->flags)) { > > + if (!folio_lock_or_retry(folio, vma, vmf->flags, &lock_dropped)) { > > folio_put(folio); > > + if (lock_dropped && vmf->flags & FAULT_FLAG_VMA_LOCK) > > + return VM_FAULT_VMA_UNLOCKED | VM_FAULT_RETRY; > > return VM_FAULT_RETRY; > > } > > ret = folio_lock_fault(folio, vmf); > if (ret) > return ret; > > > @@ -3837,9 +3840,9 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) > > goto out_release; > > } > > > > - locked = folio_lock_or_retry(folio, vma->vm_mm, vmf->flags); > > - > > - if (!locked) { > > + if (!folio_lock_or_retry(folio, vma, vmf->flags, &lock_dropped)) { > > + if (lock_dropped && vmf->flags & FAULT_FLAG_VMA_LOCK) > > + ret |= VM_FAULT_VMA_UNLOCKED; > > ret |= VM_FAULT_RETRY; > > goto out_release; > > } > > ret |= folio_lock_fault(folio, vmf); > if (ret & VM_FAULT_RETRY) > goto out_release; > > ie instead of trying to reconstruct what __folio_lock_fault() did from > its outputs, we just let folio_lock_fault() tell us what it did. Thanks for taking a look! Ok, I think what you are suggesting is to have a new set of folio_lock_fault()/__folio_lock_fault() functions which return vm_fault_t directly, __folio_lock_fault() will use __folio_lock_or_retry() internally and will adjust its return value based on __folio_lock_or_retry()'s return and the lock releasing rules described in the comments for __folio_lock_or_retry(). Is my understanding correct?