Messages in this thread | | | Date | Tue, 29 Sep 2015 11:58:18 -0400 | From | Steven Rostedt <> | Subject | Re: [RFC][PATCH 11/11] sched: More notrace |
| |
On Tue, 29 Sep 2015 11:28:36 +0200 Peter Zijlstra <peterz@infradead.org> wrote:
> preempt_schedule_common() is marked notrace, but it does not use > _notrace() preempt_count functions and __schedule() is also not marked > notrace, which means that its perfectly possible to end up in the > tracer from preempt_schedule_common(). > > So either we need more notrace, or we need to remove notrace from > preempt_schedule_common().
Yep, there's some history to this. This was originally the issue that caused function tracing to go into infinite recursion. But now we have preempt_schedule_notrace(), which is used by the function tracer, and that function must not be traced till preemption is disabled.
Now if function tracing is running and we take an interrupt when NEED_RESCHED is set, it calls
preempt_schedule_common() (not traced)
But then that calls preempt_disable() (traced)
function tracer calls preempt_disable_notrace() followed by preempt_enable_notrace() which will see NEED_RESCHED set, and it will call preempt_schedule_notrace(), which stops the recursion, but still calls __schedule() here, and that means when we return, we call the __schedule() from preempt_schedule_common().
That said, I prefer this patch. Preemption is disabled before calling __schedule(), and we get rid of a one round recursion with the scheduler.
Feel free to add any of the above to your change log.
Acked-by: Steven Rostedt <rostedt@goodmis.org>
-- Steve
> > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> > --- > kernel/sched/core.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > --- a/kernel/sched/core.c > +++ b/kernel/sched/core.c > @@ -3044,7 +3044,7 @@ pick_next_task(struct rq *rq, struct tas > * > * WARNING: must be called with preemption disabled! > */ > -static void __sched __schedule(bool preempt) > +static void __sched notrace __schedule(bool preempt) > { > struct task_struct *prev, *next; > unsigned long *switch_count; > @@ -3190,9 +3190,9 @@ void __sched schedule_preempt_disabled(v > static void __sched notrace preempt_schedule_common(void) > { > do { > - preempt_disable(); > + preempt_disable_notrace(); > __schedule(true); > - sched_preempt_enable_no_resched(); > + preempt_enable_no_resched_notrace(); > > /* > * Check again in case we missed a preemption opportunity >
| |