Commit 099bfaa7 authored by David Miller's avatar David Miller Committed by Alexei Starovoitov

bpf/stackmap: Dont trylock mmap_sem with PREEMPT_RT and interrupts disabled

In a RT kernel down_read_trylock() cannot be used from NMI context and
up_read_non_owner() is another problematic issue.

So in such a configuration, simply elide the annotated stackmap and
just report the raw IPs.

In the longer term, it might be possible to provide a atomic friendly
versions of the page cache traversal which will at least provide the info
if the pages are resident and don't need to be paged in.

[ tglx: Use IS_ENABLED() to avoid the #ifdeffery, fixup the irq work
  	callback and add a comment ]
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20200224145644.708960317@linutronix.de
parent 66150d0d
...@@ -40,6 +40,9 @@ static void do_up_read(struct irq_work *entry) ...@@ -40,6 +40,9 @@ static void do_up_read(struct irq_work *entry)
{ {
struct stack_map_irq_work *work; struct stack_map_irq_work *work;
if (WARN_ON_ONCE(IS_ENABLED(CONFIG_PREEMPT_RT)))
return;
work = container_of(entry, struct stack_map_irq_work, irq_work); work = container_of(entry, struct stack_map_irq_work, irq_work);
up_read_non_owner(work->sem); up_read_non_owner(work->sem);
work->sem = NULL; work->sem = NULL;
...@@ -288,10 +291,19 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs, ...@@ -288,10 +291,19 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
struct stack_map_irq_work *work = NULL; struct stack_map_irq_work *work = NULL;
if (irqs_disabled()) { if (irqs_disabled()) {
work = this_cpu_ptr(&up_read_work); if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
if (atomic_read(&work->irq_work.flags) & IRQ_WORK_BUSY) work = this_cpu_ptr(&up_read_work);
/* cannot queue more up_read, fallback */ if (atomic_read(&work->irq_work.flags) & IRQ_WORK_BUSY) {
/* cannot queue more up_read, fallback */
irq_work_busy = true;
}
} else {
/*
* PREEMPT_RT does not allow to trylock mmap sem in
* interrupt disabled context. Force the fallback code.
*/
irq_work_busy = true; irq_work_busy = true;
}
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment