Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: cpumap: Fix possible rcpu kthread hung

Fix the following cpumap kthread hung. The issue is currently occurring
when __cpu_map_load_bpf_program fails (e.g if the bpf prog has not
BPF_XDP_CPUMAP as expected_attach_type)

$./test_progs -n 101
101/1 cpumap_with_progs:OK
101 xdp_cpumap_attach:OK
Summary: 1/1 PASSED, 0 SKIPPED, 0 FAILED
[ 369.996478] INFO: task cpumap/0/map:7:205 blocked for more than 122 seconds.
[ 369.998463] Not tainted 5.8.0-rc4-01472-ge57892f50a07 #212
[ 370.000102] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 370.001918] cpumap/0/map:7 D 0 205 2 0x00004000
[ 370.003228] Call Trace:
[ 370.003930] __schedule+0x5c7/0xf50
[ 370.004901] ? io_schedule_timeout+0xb0/0xb0
[ 370.005934] ? static_obj+0x31/0x80
[ 370.006788] ? mark_held_locks+0x24/0x90
[ 370.007752] ? cpu_map_bpf_prog_run_xdp+0x6c0/0x6c0
[ 370.008930] schedule+0x6f/0x160
[ 370.009728] schedule_preempt_disabled+0x14/0x20
[ 370.010829] kthread+0x17b/0x240
[ 370.011433] ? kthread_create_worker_on_cpu+0xd0/0xd0
[ 370.011944] ret_from_fork+0x1f/0x30
[ 370.012348]
Showing all locks held in the system:
[ 370.013025] 1 lock held by khungtaskd/33:
[ 370.013432] #0: ffffffff82b24720 (rcu_read_lock){....}-{1:2}, at: debug_show_all_locks+0x28/0x1c3

[ 370.014461] =============================================

Fixes: 9216477449f3 ("bpf: cpumap: Add the possibility to attach an eBPF program to cpumap")
Reported-by: Jakub Sitnicki <jakub@cloudflare.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Tested-by: Jakub Sitnicki <jakub@cloudflare.com>
Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
Link: https://lore.kernel.org/bpf/e54f2aabf959f298939e5507b09c48f8c2e380be.1595170625.git.lorenzo@kernel.org

authored by

Lorenzo Bianconi and committed by
Alexei Starovoitov
c576b9c7 343ead28

+7 -4
+7 -4
kernel/bpf/cpumap.c
··· 453 453 rcpu->map_id = map_id; 454 454 rcpu->value.qsize = value->qsize; 455 455 456 + if (fd > 0 && __cpu_map_load_bpf_program(rcpu, fd)) 457 + goto free_ptr_ring; 458 + 456 459 /* Setup kthread */ 457 460 rcpu->kthread = kthread_create_on_node(cpu_map_kthread_run, rcpu, numa, 458 461 "cpumap/%d/map:%d", cpu, map_id); 459 462 if (IS_ERR(rcpu->kthread)) 460 - goto free_ptr_ring; 463 + goto free_prog; 461 464 462 465 get_cpu_map_entry(rcpu); /* 1-refcnt for being in cmap->cpu_map[] */ 463 466 get_cpu_map_entry(rcpu); /* 1-refcnt for kthread */ 464 - 465 - if (fd > 0 && __cpu_map_load_bpf_program(rcpu, fd)) 466 - goto free_ptr_ring; 467 467 468 468 /* Make sure kthread runs on a single CPU */ 469 469 kthread_bind(rcpu->kthread, cpu); ··· 471 471 472 472 return rcpu; 473 473 474 + free_prog: 475 + if (rcpu->prog) 476 + bpf_prog_put(rcpu->prog); 474 477 free_ptr_ring: 475 478 ptr_ring_cleanup(rcpu->queue, NULL); 476 479 free_queue: