• Peter Zijlstra's avatar
    sched/core: More notrace annotations · 499d7955
    Peter Zijlstra authored
    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().
    
    Steve says:
    
      | 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.
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Reviewed-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Acked-by: default avatarSteven Rostedt <rostedt@goodmis.org>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Mike Galbraith <efault@gmx.de>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    499d7955
core.c 205 KB