Skip to content

bpf: arena: handle memory.max on fault-in with reclaim/OOM - #8625

Closed
kernel-patches-daemon-bpf-rc[bot] wants to merge 4 commits into
bpf-next_basefrom
series/1140666=>bpf-next
Closed

bpf: arena: handle memory.max on fault-in with reclaim/OOM#8625
kernel-patches-daemon-bpf-rc[bot] wants to merge 4 commits into
bpf-next_basefrom
series/1140666=>bpf-next

Conversation

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown

Pull request for series with
subject: bpf: arena: handle memory.max on fault-in with reclaim/OOM
version: 2
url: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: 6655c40
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: 363b15d
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: 5b91f44
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: 8295c27
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: 11c1e83
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: 11c1e83
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: 7d008cd
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: 8c7f55d
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: 41c129f
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: 2b1f9f6
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: e1d9b82
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: 51476f6
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: 8b365b3
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

@kernel-patches-daemon-bpf-rc

Copy link
Copy Markdown
Author

Upstream branch: d114bb9
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1140666
version: 2

mrpre added 4 commits August 8, 2026 03:16
bpf_map_alloc_pages() picks the allocator via can_alloc_pages(), a
conservative guess for BPF program context that is always false under
PREEMPT_RT. So even a caller that really is sleepable gets the
non-blocking allocator, which never reclaims and never engages the OOM
machinery.

Add bpf_map_alloc_page_sleepable() for callers that know they are
sleepable. It allocates from the map's numa_node, like the other map
allocators. The next patch uses it from the arena page fault handler.

Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
arena_vm_fault() allocated the page while holding arena->spinlock, so it
could only use the non-blocking allocator. Once the memcg is at
memory.max that allocation just fails, the fault turns into
VM_FAULT_SIGSEGV, and the process gets a SIGSEGV on a perfectly valid
arena address. Hitting memory.max is routine (e.g. page cache from
reading a big file), so this kills innocent processes.

Rework the fault handler:

- Preallocate the page before taking the lock, like do_anonymous_page()
  does, so it can sleep, reclaim and go through the OOM path, and return
  VM_FAULT_OOM on failure so the memcg OOM handler runs instead of a fake
  segfault.

- A lockless probe skips that preallocation when a page is already mapped
  (e.g. allocated by the bpf program), so the common case wastes no
  allocation. The rare race where such a page is freed before we take the
  lock falls back to the non-blocking allocator under the lock.

- Return VM_FAULT_SIGBUS for the non-recoverable errors (lock failure,
  range-tree and page-table failures) instead of VM_FAULT_SIGSEGV; only
  BPF_F_SEGV_ON_FAULT, and a scratch-page hole under that flag, is a real
  user addressing error and keeps VM_FAULT_SIGSEGV.

- Tidy up the error labels.

Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
cgroup_helpers has write_cgroup_file()/write_cgroup_file_parent() but no
read counterpart. Add read_cgroup_file() and read_cgroup_file_parent() so
a forked child can read a cgroup file (e.g. memory.current) from the work
dir owned by the parent that set the environment up, without hand-building
the /mnt/... path.

Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
A child joins a memcg capped at 64M and faults an arena in until it runs
out of the budget. Without the kernel fix the child dies with SIGSEGV on
a valid arena address; with it, the child is killed by the memcg OOM
killer.

With the fix:

  serial_test_arena_memcg:PASS:child killed by signal
  serial_test_arena_memcg:PASS:not killed by SIGSEGV
  #5       arena_memcg:OK

  # dmesg
   arena_vm_fault+0x655/0xa90
  Memory cgroup out of memory: Killed process 512, file-rss:67920kB

Without the fix:

  serial_test_arena_memcg:PASS:child killed by signal
  serial_test_arena_memcg:FAIL:not killed by SIGSEGV: actual 11
  #5       arena_memcg:FAIL

  # dmesg
  test_progs[508]: segfault at 100004025000 ...

Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant