Skip to contentSkip to conversation

tracing, sched: mark preempt_schedule() notrace

PATCH In review Lai Jiangshan 3 participants 5 messages Aug 18, 2009 – Aug 19, 2009

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 tracing, sched: mark preempt_schedule() notrace

Current preempt_schedule() is not marked notrace. It may be infinite recursion in __trace_graph_return().

preempt_schedule()
__trace_graph_return()
ftrace_preempt_disable() (!!return false!!) ftrace_preempt_enable()
preempt_enable_notrace()
preempt_schedule() (need_resched() may be true again)

It hardly happens, but marking preempt_schedule() notrace makes it safer.

One interesting thing is that preempt_schedule() is in the blacklist of kprobe subsystem. "__kprobes" implies "notrace". But preempt_schedule() cannot be marked __kprobes for it has been marked __sched. It is in the blacklist makes me consider this: should it be marked "notrace" -- YES.

---

kernel/sched.c +1 -1
index 5184580..2e9e209 100644
@@ -5534,7 +5534,7 @@ out:
  * off of preempt_enable. Kernel preemptions off return from interrupt
  * occur there and call schedule directly.
  */
-asmlinkage void __sched preempt_schedule(void)
+asmlinkage void __sched notrace preempt_schedule(void)
 {
 	struct thread_info *ti = current_thread_info();
 
#1 lore raw
Quoted 10 lines · Lai Jiangshan

Current preempt_schedule() is not marked notrace. It may be infinite recursion in __trace_graph_return().

preempt_schedule()
__trace_graph_return()
ftrace_preempt_disable() (!!return false!!) ftrace_preempt_enable()
preempt_enable_notrace()
preempt_schedule() (need_resched() may be true again)

It would happen in __trace_graph_return() , when preempt_schedule() has finished its job. It's very unlikely the TIF_NEED_RESCHED is set just after (because it has just been cleared).
But why not. In that case, preempt_schedule() is called again but it's not a real tracing recursion.

That seems like a normal behaviour actually.

Quoted 33 lines

It hardly happens, but marking preempt_schedule() notrace makes it safer.

One interesting thing is that preempt_schedule() is in the blacklist of kprobe subsystem. "__kprobes" implies "notrace". But preempt_schedule() cannot be marked __kprobes for it has been marked __sched. It is in the blacklist makes me consider this: should it be marked "notrace" -- YES.

---

kernel/sched.c +1 -1
index 5184580..2e9e209 100644
@@ -5534,7 +5534,7 @@ out:
  * off of preempt_enable. Kernel preemptions off return from interrupt
  * occur there and call schedule directly.
  */
-asmlinkage void __sched preempt_schedule(void)
+asmlinkage void __sched notrace preempt_schedule(void)
 {
 	struct thread_info *ti = current_thread_info();
 
#2 lore raw
Quoted 14 lines · Frederic Weisbecker
Quoted 10 lines · Lai Jiangshan

Current preempt_schedule() is not marked notrace. It may be infinite recursion in __trace_graph_return().

preempt_schedule()
__trace_graph_return()
ftrace_preempt_disable() (!!return false!!) ftrace_preempt_enable()
preempt_enable_notrace()
preempt_schedule() (need_resched() may be true again)

Quoted 7 lines

It would happen in __trace_graph_return() , when preempt_schedule() has finished its job. It's very unlikely the TIF_NEED_RESCHED is set just after (because it has just been cleared).
But why not. In that case, preempt_schedule() is called again but it's not a real tracing recursion.

That seems like a normal behaviour actually.

In fact, this is actually something to be traced. I would not add a notrace to it. This is not saving anything, the trace_graph_return does not need to worry about stack overflow, since the return code already freed the stack.

-- Steve

#3 lore raw
Quoted 21 lines · Steven Rostedt
Quoted 18 lines · Frederic Weisbecker
Quoted 9 lines · Lai Jiangshan

Current preempt_schedule() is not marked notrace. It may be infinite recursion in __trace_graph_return().

preempt_schedule()
__trace_graph_return()
ftrace_preempt_disable() (!!return false!!) ftrace_preempt_enable()
preempt_enable_notrace()
preempt_schedule() (need_resched() may be true again)

It would happen in __trace_graph_return() , when preempt_schedule() has finished its job. It's very unlikely the TIF_NEED_RESCHED is set just after (because it has just been cleared).
But why not. In that case, preempt_schedule() is called again but it's not a real tracing recursion.

Quoted 7 lines
Quoted 1 line

That seems like a normal behaviour actually.

In fact, this is actually something to be traced. I would not add a notrace to it. This is not saving anything, the trace_graph_return does not need to worry about stack overflow, since the return code already freed the stack.

You're right, I forgot to read trace_graph_return(). trace_graph_return() protects itself from recursion.

Since there is no may-recursive trace_func_graph_ret_t. Just omit this patch.
Sorry for bothered you all.

#4 lore raw
In reply to Frederic Weisbecker
Quoted 13 lines · Frederic Weisbecker
Quoted 9 lines · Lai Jiangshan

Current preempt_schedule() is not marked notrace. It may be infinite recursion in __trace_graph_return().

preempt_schedule()
__trace_graph_return()
ftrace_preempt_disable() (!!return false!!) ftrace_preempt_enable()
preempt_enable_notrace()
preempt_schedule() (need_resched() may be true again)

Quoted 3 lines

It would happen in __trace_graph_return() , when preempt_schedule() has finished its job. It's very unlikely the TIF_NEED_RESCHED is set just after (because it has just been cleared).

It hardly happen ...
This doesn't mean it'll never happen.

Quoted 6 lines

But why not. In that case, preempt_schedule() is called again but it's not a real tracing recursion.

That seems like a normal behaviour actually.

It's not normal behavior, preempt_schedule() will not call preempt_schedule() recursively in any situation when trace is off.

Here, preempt_schedule() is called from __trace_graph_return() when trace_function_graph is on.

preempt_schedule()
__trace_graph_return()

    preempt_schedule()
      __trace_graph_return()
        ....

So, it's a real tracing recursion.
It hurts the stack.