lkml.org 
[lkml]   [2020]   [May]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch V9 07/39] x86/entry: Cleanup idtentry_enter/exit() leftovers
    Now that everything is converted to conditional RCU handling remove
    idtentry_enter/exit() and tidy up the conditional functions.

    This does not remove rcu_irq_exit_preempt() to avoid conflicts with the RCU
    tree. Will be removed once all of this hit Linus tree.

    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    ---
    V9: New patch
    ---
    arch/x86/entry/common.c | 67 +++++++++++++++++-----------------------
    arch/x86/include/asm/idtentry.h | 12 -------
    2 files changed, 30 insertions(+), 49 deletions(-)

    --- a/arch/x86/entry/common.c
    +++ b/arch/x86/entry/common.c
    @@ -515,7 +515,6 @@ SYSCALL_DEFINE0(ni_syscall)
    * idtentry_enter_cond_rcu - Handle state tracking on idtentry with conditional
    * RCU handling
    * @regs: Pointer to pt_regs of interrupted context
    - * @cond_rcu: Invoke rcu_irq_enter() only if RCU is not watching
    *
    * Invokes:
    * - lockdep irqflag state tracking as low level ASM entry disabled
    @@ -545,12 +544,12 @@ SYSCALL_DEFINE0(ni_syscall)
    * The return value must be fed into the rcu_exit argument of
    * idtentry_exit_cond_rcu().
    */
    -bool noinstr idtentry_enter_cond_rcu(struct pt_regs *regs, bool cond_rcu)
    +bool noinstr idtentry_enter_cond_rcu(struct pt_regs *regs)
    {
    if (user_mode(regs)) {
    enter_from_user_mode();
    } else {
    - if (!cond_rcu || !__rcu_is_watching()) {
    + if (!__rcu_is_watching()) {
    /*
    * If RCU is not watching then the same careful
    * sequence vs. lockdep and tracing is required
    @@ -605,52 +604,44 @@ void noinstr idtentry_exit_cond_rcu(stru
    if (user_mode(regs)) {
    prepare_exit_to_usermode(regs);
    } else if (regs->flags & X86_EFLAGS_IF) {
    + /*
    + * If RCU was not watching on entry this needs to be done
    + * carefully and needs the same ordering of lockdep/tracing
    + * and RCU as the return to user mode path.
    + */
    + if (rcu_exit) {
    + instrumentation_begin();
    + /* Tell the tracer that IRET will enable interrupts */
    + trace_hardirqs_on_prepare();
    + lockdep_hardirqs_on_prepare(CALLER_ADDR0);
    + instrumentation_end();
    + rcu_irq_exit();
    + lockdep_hardirqs_on(CALLER_ADDR0);
    + return;
    + }
    +
    + instrumentation_begin();
    +
    /* Check kernel preemption, if enabled */
    if (IS_ENABLED(CONFIG_PREEMPTION)) {
    - /*
    - * This needs to be done very carefully.
    - * idtentry_enter() invoked rcu_irq_enter(). This
    - * needs to be undone before scheduling.
    - *
    - * Preemption is disabled inside of RCU idle
    - * sections. When the task returns from
    - * preempt_schedule_irq(), RCU is still watching.
    - *
    - * rcu_irq_exit_preempt() has additional state
    - * checking if CONFIG_PROVE_RCU=y
    - */
    if (!preempt_count()) {
    + /* Sanity check RCU and thread stack */
    + rcu_irq_exit_check_preempt();
    if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
    WARN_ON_ONCE(!on_thread_stack());
    - instrumentation_begin();
    - if (rcu_exit)
    - rcu_irq_exit_preempt();
    if (need_resched())
    preempt_schedule_irq();
    - /* Covers both tracing and lockdep */
    - trace_hardirqs_on();
    - instrumentation_end();
    - return;
    }
    }
    - /*
    - * If preemption is disabled then this needs to be done
    - * carefully with respect to RCU. The exception might come
    - * from a RCU idle section in the idle task due to the fact
    - * that safe_halt() enables interrupts. So this needs the
    - * same ordering of lockdep/tracing and RCU as the return
    - * to user mode path.
    - */
    - instrumentation_begin();
    - /* Tell the tracer that IRET will enable interrupts */
    - trace_hardirqs_on_prepare();
    - lockdep_hardirqs_on_prepare(CALLER_ADDR0);
    + /* Covers both tracing and lockdep */
    + trace_hardirqs_on();
    +
    instrumentation_end();
    - if (rcu_exit)
    - rcu_irq_exit();
    - lockdep_hardirqs_on(CALLER_ADDR0);
    } else {
    - /* IRQ flags state is correct already. Just tell RCU. */
    + /*
    + * IRQ flags state is correct already. Just tell RCU if it
    + * was not watching on entry.
    + */
    if (rcu_exit)
    rcu_irq_exit();
    }
    --- a/arch/x86/include/asm/idtentry.h
    +++ b/arch/x86/include/asm/idtentry.h
    @@ -10,19 +10,9 @@
    void idtentry_enter_user(struct pt_regs *regs);
    void idtentry_exit_user(struct pt_regs *regs);

    -bool idtentry_enter_cond_rcu(struct pt_regs *regs, bool cond_rcu);
    +bool idtentry_enter_cond_rcu(struct pt_regs *regs);
    void idtentry_exit_cond_rcu(struct pt_regs *regs, bool rcu_exit);

    -static __always_inline void idtentry_enter(struct pt_regs *regs)
    -{
    - idtentry_enter_cond_rcu(regs, false);
    -}
    -
    -static __always_inline void idtentry_exit(struct pt_regs *regs)
    -{
    - idtentry_exit_cond_rcu(regs, true);
    -}
    -
    /**
    * DECLARE_IDTENTRY - Declare functions for simple IDT entry points
    * No error code pushed by hardware
    \
     
     \ /
      Last update: 2020-05-21 22:32    [W:3.514 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site