bpf: arena: handle memory.max on fault-in with reclaim/OOM - #8625
bpf: arena: handle memory.max on fault-in with reclaim/OOM#8625kernel-patches-daemon-bpf-rc[bot] wants to merge 4 commits into
Conversation
|
Upstream branch: 6655c40 |
545c302 to
16047c2
Compare
|
Upstream branch: 363b15d |
eb4b959 to
5c4215f
Compare
16047c2 to
db603c2
Compare
|
Upstream branch: 5b91f44 |
5c4215f to
8858884
Compare
db603c2 to
ead3878
Compare
|
Upstream branch: 8295c27 |
8858884 to
ff67455
Compare
ead3878 to
f2dbc2c
Compare
|
Upstream branch: 11c1e83 |
ff67455 to
2e8aef0
Compare
f2dbc2c to
28abc40
Compare
|
Upstream branch: 11c1e83 |
2e8aef0 to
f3e50e4
Compare
28abc40 to
1824cf2
Compare
|
Upstream branch: 7d008cd |
f3e50e4 to
21f0e05
Compare
1824cf2 to
6ac2541
Compare
|
Upstream branch: 8c7f55d |
21f0e05 to
073af25
Compare
6ac2541 to
bbe1ae8
Compare
|
Upstream branch: 41c129f |
073af25 to
f9b1439
Compare
bbe1ae8 to
dd2acb0
Compare
|
Upstream branch: 2b1f9f6 |
f9b1439 to
92cb67e
Compare
dd2acb0 to
75f1c0e
Compare
|
Upstream branch: e1d9b82 |
92cb67e to
c9257e3
Compare
75f1c0e to
f776207
Compare
|
Upstream branch: 51476f6 |
c9257e3 to
ca1036f
Compare
f776207 to
b882df0
Compare
|
Upstream branch: 8b365b3 |
ca1036f to
90f26c3
Compare
b882df0 to
818432c
Compare
|
Upstream branch: d114bb9 |
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>
90f26c3 to
0ff9a53
Compare
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