On Mon, Jul 06, 2026 at 05:57:24AM -0700, Usama Arif wrote:
> > @@ -2443,8 +2443,12 @@ static unsigned long pagemap_page_category(struct 
> > pagemap_scan_private *p,
> >  
> >             categories = PAGE_IS_PRESENT;
> >  
> > -           if (!pte_uffd(pte))
> > -                   categories |= PAGE_IS_WRITTEN;
> > +           if (!pte_uffd(pte)) {
> > +                   if (userfaultfd_wp(vma))
> > +                           categories |= PAGE_IS_WRITTEN;
> > +                   if (userfaultfd_rwp(vma))
> > +                           categories |= PAGE_IS_ACCESSED;
> > +           }
> 
> The above is an ABI change for existing PAGEMAP_SCAN users although not
> sure if there is someone that cares. Would below be a better alternative
> to limit the ABI change?
> 
> if (!pte_uffd(pte)) {
>       if (userfaultfd_rwp(vma))
>               categories |= PAGE_IS_ACCESSED;
>       else
>               categories |= PAGE_IS_WRITTEN;
> }

You're right that it changes what PAGEMAP_SCAN returns outside a
VM_UFFD_WP VMA. I think that is the intent rather than a side effect --
the commit message calls it out explicitly as a UAPI narrowing.

PAGE_IS_WRITTEN is documented as "Page has been written to from the time
it was write protected". Outside a write-protected VMA there is no such
point in time, so the flag has no defined meaning there -- and the
current code sets it unconditionally on every present, non-uffd PTE,
which makes it a constant duplicate of PAGE_IS_PRESENT. A caller cannot
use it to tell written pages from merely-present ones.

Scoping it to VM_UFFD_WP makes the bit mean what it is documented to
mean. A consumer that read PAGE_IS_WRITTEN on a non-WP range was reading
a value that never carried write information, so I don't think there is a
meaningful user to regress.

And in the unlikely event an actual user turns up that depends on the
current behaviour, we can always switch to your else-form -- it is a
small change and keeps the old value.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov

Reply via email to