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