Re: [PATCH 6/6] userfaultfd: collapse VM_UFFD_{MISSING,WP,MINOR,RWP} into single VM_UFFD
flat view
From: Lance Yang <lance.yang@linux.dev>
Date: 2026-08-24 08:28:02
Also in:
linux-doc, linux-fsdevel, linux-mm, lkml
On 2026/8/24 16:17, Mike Rapoport wrote:
Hi Lance, On Mon, Aug 24, 2026 at 03:11:26PM +0800, Lance Yang wrote:quoted
On Sun, Aug 23, 2026 at 03:17:43PM +0300, Mike Rapoport (Microsoft) wrote: [...]quoted
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 83587d34b189..193f6e65d875 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c@@ -50,10 +50,10 @@ struct mfill_state {pmd_t *pmd; }; -static bool anon_can_userfault(struct vm_area_struct *vma, vm_flags_t vm_flags) +static bool anon_can_userfault(struct vm_area_struct *vma, unsigned int mode) { /* anonymous memory does not support MINOR mode */ - if (vm_flags & VM_UFFD_MINOR) + if (mode & UFFD_MODE_MINOR) return false; return true; }@@ -462,7 +462,7 @@ static int mfill_copy_folio_locked(struct folio *folio, unsigned long src_addr)} #define MFILL_RETRY_STATE_VMA_FLAGS \ - append_vma_flags(__VMA_UFFD_FLAGS, VMA_SHARED_BIT) + append_vma_flags(VMA_UFFD, VMA_SHARED_BIT)Looks like this drops registration mode from the retry snapshot. Assume a shared shmem VMA is registered for MISSING and COPY reaches mfill_copy_folio_retry(). While locks are dropped, the same userfaultfd| can re-register the range for MINOR. VMA_UFFD, VM_SHARED, ops, file and pgoff all stay unchanged, so the old COPY can continue instead of returning -EAGAIN ... no?Good catch, thanks!
Cheers!
quoted hunk ↗ jump to hunk
quoted
Maybe something like this?I prefer to add mode to the retry_state:diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 193f6e65d875..a0377f7ecc69 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c@@ -471,6 +471,7 @@ static int mfill_copy_folio_locked(struct folio *folio, unsigned long src_addr) */ struct mfill_retry_state { const struct vm_uffd_ops *ops; + unsigned long mode; struct file *file; vma_flags_t flags; pgoff_t pgoff;@@ -482,6 +483,7 @@ static void mfill_retry_state_save(struct mfill_retry_state *s, s->flags = vma_flags_and_mask(&vma->flags, MFILL_RETRY_STATE_VMA_FLAGS); s->ops = vma_uffd_ops(vma); s->pgoff = vma_start_pgoff(vma); + s->mode = uffd_mode(vma); if (vma->vm_file) s->file = get_file(vma->vm_file);@@ -493,8 +495,9 @@ static bool mfill_retry_state_changed(struct mfill_retry_state *state, vma_flags_t flags = vma_flags_and_mask(&vma->flags, MFILL_RETRY_STATE_VMA_FLAGS); - /* Have any UFFD flags (missing, WP, minor) changed? */ - if (!vma_flags_same_pair(&state->flags, &flags)) + /* UFFD registration mode or VMA sharing changed */ + if (!vma_flags_same_pair(&state->flags, &flags) || + s->mode != uffd_mode(vma))
I assume you meant s/s->mode/state->mode/ With that, LGTM :)
return true; /* VMA type or effective uffd_ops changed while the lock was dropped */quoted
Cheers, Lance
Cheers, Lance