Re: [RFC][PATCH 11/11] sched: More notrace

From: Steven Rostedt
Date: Tue Sep 29 2015 - 11:58:49 EST


On Tue, 29 Sep 2015 11:28:36 +0200
Peter Zijlstra <peterz@xxxxxxxxxxxxx> 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@xxxxxxxxxxx>

-- Steve

>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
> ---
> 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
>

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/