Browse Source

ftrace: Fix indexing of t_hash_start() from t_next()

t_hash_start() does not increment *pos, where as t_next() must. But when
t_next() does increment *pos, it must still pass in the original *pos to
t_hash_start() otherwise it will skip the first instance:

 # cd /sys/kernel/debug/tracing
 # echo schedule:traceoff > set_ftrace_filter
 # echo do_IRQ:traceoff > set_ftrace_filter
 # echo call_rcu > set_ftrace_filter
 # cat set_ftrace_filter
call_rcu
schedule:traceoff:unlimited
do_IRQ:traceoff:unlimited

The above called t_hash_start() from t_start() as there was only one
function (call_rcu), but if we add another function:

 # echo xfrm_policy_destroy_rcu >> set_ftrace_filter
 # cat set_ftrace_filter
call_rcu
xfrm_policy_destroy_rcu
do_IRQ:traceoff:unlimited

The "schedule:traceoff" disappears.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Steven Rostedt (VMware) 8 years ago
parent
commit
fcdc712579
1 changed files with 3 additions and 2 deletions
  1. 3 2
      kernel/trace/ftrace.c

+ 3 - 2
kernel/trace/ftrace.c

@@ -3205,6 +3205,7 @@ static void *
 t_next(struct seq_file *m, void *v, loff_t *pos)
 {
 	struct ftrace_iterator *iter = m->private;
+	loff_t l = *pos; /* t_hash_start() must use original pos */
 	void *ret;
 
 	if (unlikely(ftrace_disabled))
@@ -3216,13 +3217,13 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
 	if (iter->flags & FTRACE_ITER_PRINTALL) {
 		/* next must increment pos, and t_hash_start does not */
 		(*pos)++;
-		return t_hash_start(m, pos);
+		return t_hash_start(m, &l);
 	}
 
 	ret = t_func_next(m, pos);
 
 	if (!ret)
-		return t_hash_start(m, pos);
+		return t_hash_start(m, &l);
 
 	return ret;
 }