Messages in this thread | | | Date | Tue, 11 Feb 2020 16:34:52 +0100 | From | Peter Zijlstra <> | Subject | Re: [PATCH v2] tracing/perf: Move rcu_irq_enter/exit_irqson() to perf trace point hook |
| |
On Tue, Feb 11, 2020 at 09:50:47AM -0500, Steven Rostedt wrote: > diff --git a/kernel/events/core.c b/kernel/events/core.c > index 455451d24b4a..0abbf5e2ee62 100644 > --- a/kernel/events/core.c > +++ b/kernel/events/core.c > @@ -8941,6 +8941,7 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size, > { > struct perf_sample_data data; > struct perf_event *event; > + bool rcu_watching = rcu_is_watching(); > > struct perf_raw_record raw = { > .frag = { > @@ -8949,6 +8950,17 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size, > }, > }; > > + if (!rcu_watching) { > + /* > + * If nmi_enter() is traced, it is possible that > + * RCU may not be watching "yet", and this is called. > + * We can not call rcu_irq_enter_irqson() in this case. > + */ > + if (unlikely(in_nmi())) > + goto out;
unless I'm mistaken, we can simply do rcu_nmi_enter() in this case, and rcu_nmi_exit() on the other end.
> + rcu_irq_enter_irqson(); > + } > + > perf_sample_data_init(&data, 0, 0); > data.raw = &raw; > > @@ -8985,8 +8997,11 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size, > unlock: > rcu_read_unlock(); > } > - > + if (!rcu_watching) > + rcu_irq_exit_irqson(); > +out: > perf_swevent_put_recursion_context(rctx); > + > }
| |