On Fri, Jun 9, 2023 at 11:49 AM Suren Baghdasaryan <surenb@xxxxxxxxxx> wrote: > > 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? Oh, after rereading I think you are suggesting to replace folio_lock_or_retry()/__folio_lock_or_retry() with folio_lock_fault()/__folio_lock_fault(), not to add them. Is that right?