Re: [PATCH v6 bpf-next] bpf: Populate mmap-able array map memory lazily

Song Liu <[email protected]>
Newsgroups org.kernel.vger.bpf
Message-ID <CAPhsuW7otRv+xvJ9f8tstH4Mwp3FrkT1Qgbnvzun-39_D35K4Q@mail.gmail.com>
On Thu, Aug 13, 2026 at 5:06 PM <[email protected]> wrote:
[...]
>
> > diff --git kernel/bpf/syscall.c kernel/bpf/syscall.c
> > index 7d8c3e8e6d62e..9e5e65e73dfa4 100644
> > --- kernel/bpf/syscall.c
> > +++ kernel/bpf/syscall.c
> > @@ -1076,9 +1076,21 @@ static void bpf_map_mmap_close(struct vm_area_struct *vma)
> >               bpf_map_write_active_dec(map);
> >  }
> >
> > +/* Called for maps that populate their memory-mapped region lazily. */
> > +static vm_fault_t bpf_map_mmap_fault(struct vm_fault *vmf)
> > +{
> > +     struct bpf_map *map = vmf->vma->vm_private_data;
> > +
> > +     if (!map->ops->map_mmap_fault)
> > +             return VM_FAULT_SIGBUS;
> > +
> > +     return map->ops->map_mmap_fault(map, vmf);
> > +}
> > +
> >  static const struct vm_operations_struct bpf_map_default_vmops = {
> >       .open           = bpf_map_mmap_open,
> >       .close          = bpf_map_mmap_close,
> > +     .fault          = bpf_map_mmap_fault,
> >  };
>
> Can this affect ringbuf maps? Both ringbuf_map_ops and user_ringbuf_map_ops
> provide .map_mmap but not .map_mmap_fault, and neither overrides vm_ops, so
> they now use bpf_map_default_vmops.fault. Before this patch a fault on
> their VMAs had no .fault handler, which let do_fault() take the path that
> re-checks the PTE under the PTL:
>
> mm/memory.c:do_fault() {
>     if (!vma->vm_ops->fault) {
>             vmf->pte = pte_offset_map_lock(vmf->vma->vm_mm, vmf->pmd,
>                                            vmf->address, &vmf->ptl);
>             ...
>             if (unlikely(pte_none(ptep_get(vmf->pte))))
>                     ret = VM_FAULT_SIGBUS;
>             else
>                     ret = VM_FAULT_NOPAGE;
>     ...
> }
>
> That re-check exists so a fault racing the zero-PTE window of a
> read/modify/write update (like change_pte_range() for mprotect() or
> clear_soft_dirty() for /proc/pid/clear_refs) sees the updated entry and
> returns VM_FAULT_NOPAGE instead of SIGBUS.
>
> After this patch bpf_map_mmap_fault() returns VM_FAULT_SIGBUS immediately
> when map_mmap_fault is NULL, so the PTL re-check never happens. Could this
> send SIGBUS to a userspace thread reading a ring buffer while another
> thread calls mprotect() on the same mapping?
>
> The comment says the handler is "Called for maps that populate their
> memory-mapped region lazily," but it is installed on the shared vm_ops and
> actually called for all mmap-able maps, including the eagerly-populated
> ringbufs.

Both comments appears to be valid. I incorporated the feedbacks in v7.

Thanks,
Song
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.