On Mon, Oct 14, 2019 at 10:12 AM Song Liu <songliubraving@xxxxxx> wrote: > > bpf stackmap with build-id lookup (BPF_F_STACK_BUILD_ID) can trigger A-A > deadlock on rq_lock(): > > rcu: INFO: rcu_sched detected stalls on CPUs/tasks: > [...] > Call Trace: > try_to_wake_up+0x1ad/0x590 > wake_up_q+0x54/0x80 > rwsem_wake+0x8a/0xb0 > bpf_get_stack+0x13c/0x150 > bpf_prog_fbdaf42eded9fe46_on_event+0x5e3/0x1000 > bpf_overflow_handler+0x60/0x100 > __perf_event_overflow+0x4f/0xf0 > perf_swevent_overflow+0x99/0xc0 > ___perf_sw_event+0xe7/0x120 > __schedule+0x47d/0x620 > schedule+0x29/0x90 > futex_wait_queue_me+0xb9/0x110 > futex_wait+0x139/0x230 > do_futex+0x2ac/0xa50 > __x64_sys_futex+0x13c/0x180 > do_syscall_64+0x42/0x100 > entry_SYSCALL_64_after_hwframe+0x44/0xa9 > > This can be reproduced by: > 1. Start a multi-thread program that does parallel mmap() and malloc(); > 2. taskset the program to 2 CPUs; > 3. Attach bpf program to trace_sched_switch and gather stackmap with > build-id, e.g. with trace.py from bcc tools: > trace.py -U -p <pid> -s <some-bin,some-lib> t:sched:sched_switch > > A sample reproducer is attached at the end. > > This could also trigger deadlock with other locks that are nested with > rq_lock. > > Fix this by checking whether irqs are disabled. Since rq_lock and all > other nested locks are irq safe, it is safe to do up_read() when irqs are > not disable. If the irqs are disabled, postpone up_read() in irq_work. > > Fixes: commit 615755a77b24 ("bpf: extend stackmap to save binary_build_id+offset instead of address") > Cc: stable@xxxxxxxxxxxxxxx # v4.17+ > Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> > Cc: Alexei Starovoitov <ast@xxxxxxxxxx> > Cc: Daniel Borkmann <daniel@xxxxxxxxxxxxx> > Signed-off-by: Song Liu <songliubraving@xxxxxx> I fixed 'Fixes' tag and applied to bpf-next. Thanks