On Sat, Aug 31, 2013 at 01:11:19AM -0400, Steven Rostedt wrote: > From: "Steven Rostedt (Red Hat)" <rost...@goodmis.org> > > For the ftrace_ops that use RCU read locks, and can not be called by > unsafe RCU functions (those outside of RCU tracking), have them not > update the RCU unsafe function records when they are being registered > or unregistered. > > The ftrace function records store a counter of all the ftrace_ops > callbacks that are hooked to the function the record represents. > As unsafe RCU functions do not call callbacks that do not specify > that they do not use RCU, do not update those records. > > Cc: Jiri Olsa <jo...@redhat.com> > Cc: Paul E. McKenney <paul...@linux.vnet.ibm.com> > Signed-off-by: Steven Rostedt <rost...@goodmis.org>
Acked-by: Paul E. McKenney <paul...@linux.vnet.ibm.com> > --- > kernel/trace/ftrace.c | 19 +++++++++++++++++-- > 1 file changed, 17 insertions(+), 2 deletions(-) > > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c > index 3750360..d61f431 100644 > --- a/kernel/trace/ftrace.c > +++ b/kernel/trace/ftrace.c > @@ -1168,6 +1168,12 @@ static struct ftrace_page *ftrace_new_pgs; > static struct ftrace_page *ftrace_pages_start; > static struct ftrace_page *ftrace_pages; > > +/* > + * Hash of functions that are not safe to be called by > + * callbacks that use RCU read locks. > + */ > +static struct ftrace_hash *ftrace_unsafe_rcu; > + > static bool ftrace_hash_empty(struct ftrace_hash *hash) > { > return !hash || !hash->count; > @@ -1638,6 +1644,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops > *ops, > { > struct ftrace_hash *hash; > struct ftrace_hash *other_hash; > + struct ftrace_hash *rcu_hash; > struct ftrace_page *pg; > struct dyn_ftrace *rec; > int count = 0; > @@ -1647,6 +1654,12 @@ static void __ftrace_hash_rec_update(struct ftrace_ops > *ops, > if (!(ops->flags & FTRACE_OPS_FL_ENABLED)) > return; > > + /* Ignore rcu unsafe functions unless ops handles them */ > + if (ops->flags & FTRACE_OPS_FL_RCU_SAFE) > + rcu_hash = NULL; > + else > + rcu_hash = ftrace_unsafe_rcu; > + > /* > * In the filter_hash case: > * If the count is zero, we update all records. > @@ -1680,6 +1693,10 @@ static void __ftrace_hash_rec_update(struct ftrace_ops > *ops, > int in_hash = 0; > int match = 0; > > + /* Ignore all in the rcu unsafe hash */ > + if (ftrace_lookup_ip(rcu_hash, rec->ip)) > + continue; > + > if (all) { > /* > * Only the filter_hash affects all records. > @@ -4291,8 +4308,6 @@ struct notifier_block ftrace_module_exit_nb = { > extern struct ftrace_func_finder *__start_ftrace_unsafe_rcu[]; > extern struct ftrace_func_finder *__stop_ftrace_unsafe_rcu[]; > > -static struct ftrace_hash *ftrace_unsafe_rcu; > - > static void __init create_unsafe_rcu_hash(void) > { > struct ftrace_func_finder *finder; > -- > 1.7.10.4 > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/