Re: [Linux-kernel-mentees] [PATCH] tracing: Annotate ftrace_graph_hash pointer with __rcu
From: "Paul E. McKenney" <paulmck@kernel.org>
Date: 2020-02-05 13:11:12
Also in:
lkml
On Tue, Feb 04, 2020 at 08:01:16PM -0500, Steven Rostedt wrote:
On Mon, 3 Feb 2020 11:33:01 -0500 Joel Fernandes [off-list ref] wrote:quoted
quoted
--- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h@@ -950,22 +950,25 @@ extern void __trace_graph_return(struct trace_array *tr, unsigned long flags, int pc); #ifdef CONFIG_DYNAMIC_FTRACE -extern struct ftrace_hash *ftrace_graph_hash; +extern struct ftrace_hash __rcu *ftrace_graph_hash; extern struct ftrace_hash *ftrace_graph_notrace_hash; static inline int ftrace_graph_addr(struct ftrace_graph_ent *trace) { unsigned long addr = trace->func; int ret = 0; + struct ftrace_hash *hash; preempt_disable_notrace(); - if (ftrace_hash_empty(ftrace_graph_hash)) { + hash = rcu_dereference_protected(ftrace_graph_hash, !preemptible());I think you can use rcu_dereference_sched() here? That way no need to pass !preemptible. A preempt-disabled section is an RCU "sched flavor" section. Flavors are consolidated in the backend, but in the front end the dereference API still do have flavors.Unfortunately, doing it with rcu_dereference_sched() causes a lockdep splat :-P. This is because ftrace can execute when rcu is not "watching" and that will trigger a lockdep error. That means, this origin patch *is* correct. I'm re-applying this one.
I strongly recommend a comment stating why disabling preemption prevents ftrace_graph_hash from going away. I see the synchronize_rcu() after the rcu_assign_pointer() in ftrace_graph_release(), but I don't see anything that waits on CPUs that RCU is not watching. Of course, event tracing -makes- RCU watch when needed, but if that was set up, then lockdep would not have complained. So what am I missing? Thanx, Paul _______________________________________________ Linux-kernel-mentees mailing list Linux-kernel-mentees@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees