Messages in this thread | | | Date | Tue, 11 Feb 2020 13:21:20 +0100 | From | Peter Zijlstra <> | Subject | Re: [PATCH] tracing/perf: Move rcu_irq_enter/exit_irqson() to perf trace point hook |
| |
On Mon, Feb 10, 2020 at 05:06:43PM -0500, Steven Rostedt wrote: > diff --git a/include/trace/perf.h b/include/trace/perf.h > index dbc6c74defc3..1c94ce0cd4e2 100644 > --- a/include/trace/perf.h > +++ b/include/trace/perf.h > @@ -39,17 +39,27 @@ perf_trace_##call(void *__data, proto) \ > u64 __count = 1; \ > struct task_struct *__task = NULL; \ > struct hlist_head *head; \ > + bool rcu_watching; \ > int __entry_size; \ > int __data_size; \ > int rctx; \ > \ > + rcu_watching = rcu_is_watching(); \ > + \ > __data_size = trace_event_get_offsets_##call(&__data_offsets, args); \ > \ > + if (!rcu_watching) { \ > + /* Can not use RCU if rcu is not watching and in NMI */ \ > + if (in_nmi()) \ > + return; \ > + rcu_irq_enter_irqson(); \ > + } \ > + \ > head = this_cpu_ptr(event_call->perf_events); \ > if (!bpf_prog_array_valid(event_call) && \ > __builtin_constant_p(!__task) && !__task && \ > hlist_empty(head)) \ > - return; \ > + goto out; \ > \ > __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),\ > sizeof(u64)); \ > @@ -57,7 +67,7 @@ perf_trace_##call(void *__data, proto) \ > \ > entry = perf_trace_buf_alloc(__entry_size, &__regs, &rctx); \ > if (!entry) \ > - return; \ > + goto out; \ > \ > perf_fetch_caller_regs(__regs); \ > \ > @@ -68,6 +78,9 @@ perf_trace_##call(void *__data, proto) \ > perf_trace_run_bpf_submit(entry, __entry_size, rctx, \ > event_call, __count, __regs, \ > head, __task); \ > +out: \ > + if (!rcu_watching) \ > + rcu_irq_exit_irqson(); \ > }
It is probably okay to move that into perf_tp_event(), then this:
> /* > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c > index 1694a6b57ad8..3e6f07b62515 100644 > --- a/kernel/rcu/tree.c > +++ b/kernel/rcu/tree.c > @@ -719,6 +719,7 @@ void rcu_irq_exit_irqson(void) > rcu_irq_exit(); > local_irq_restore(flags); > } > +EXPORT_SYMBOL_GPL(rcu_irq_exit_irqson); > > /* > * Exit an RCU extended quiescent state, which can be either the > @@ -890,6 +891,7 @@ void rcu_irq_enter_irqson(void) > rcu_irq_enter(); > local_irq_restore(flags); > } > +EXPORT_SYMBOL_GPL(rcu_irq_enter_irqson); > > /* > * If any sort of urgency was applied to the current CPU (for example,
can go too. Those things really should not be exported.
| |