The following commit has been merged into the x86/entry branch of tip:

Commit-ID:     b614345f52bcde8299a53132f5e48a9eb5a1f320
Gitweb:        
https://git.kernel.org/tip/b614345f52bcde8299a53132f5e48a9eb5a1f320
Author:        Peter Zijlstra <pet...@infradead.org>
AuthorDate:    Fri, 29 May 2020 23:27:39 +02:00
Committer:     Thomas Gleixner <t...@linutronix.de>
CommitterDate: Sat, 30 May 2020 10:00:10 +02:00

x86/entry: Clarify irq_{enter,exit}_rcu()

Because:

  irq_enter_rcu() includes lockdep_hardirq_enter()
  irq_exit_rcu() does *NOT* include lockdep_hardirq_exit()

Which resulted in two 'stray' lockdep_hardirq_exit() calls in
idtentry.h, and me spending a long time trying to find the matching
enter calls.

Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org>
Signed-off-by: Thomas Gleixner <t...@linutronix.de>
Link: https://lkml.kernel.org/r/20200529213321.359433...@infradead.org

---
 arch/x86/include/asm/idtentry.h |  2 --
 kernel/softirq.c                | 19 +++++++++++++------
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h
index d214a30..f8e2737 100644
--- a/arch/x86/include/asm/idtentry.h
+++ b/arch/x86/include/asm/idtentry.h
@@ -206,7 +206,6 @@ __visible noinstr void func(struct pt_regs *regs,           
        \
        kvm_set_cpu_l1tf_flush_l1d();                                   \
        __##func (regs, (u8)error_code);                                \
        irq_exit_rcu();                                                 \
-       lockdep_hardirq_exit();                                         \
        instrumentation_end();                                          \
        idtentry_exit_cond_rcu(regs, rcu_exit);                         \
 }                                                                      \
@@ -249,7 +248,6 @@ __visible noinstr void func(struct pt_regs *regs)           
        \
        kvm_set_cpu_l1tf_flush_l1d();                                   \
        run_on_irqstack_cond(__##func, regs, regs);                     \
        irq_exit_rcu();                                                 \
-       lockdep_hardirq_exit();                                         \
        instrumentation_end();                                          \
        idtentry_exit_cond_rcu(regs, rcu_exit);                         \
 }                                                                      \
diff --git a/kernel/softirq.c b/kernel/softirq.c
index beb8e3a..a3eb6eb 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -404,12 +404,7 @@ static inline void tick_irq_exit(void)
 #endif
 }
 
-/**
- * irq_exit_rcu() - Exit an interrupt context without updating RCU
- *
- * Also processes softirqs if needed and possible.
- */
-void irq_exit_rcu(void)
+static inline void __irq_exit_rcu(void)
 {
 #ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED
        local_irq_disable();
@@ -425,6 +420,18 @@ void irq_exit_rcu(void)
 }
 
 /**
+ * irq_exit_rcu() - Exit an interrupt context without updating RCU
+ *
+ * Also processes softirqs if needed and possible.
+ */
+void irq_exit_rcu(void)
+{
+       __irq_exit_rcu();
+        /* must be last! */
+       lockdep_hardirq_exit();
+}
+
+/**
  * irq_exit - Exit an interrupt context, update RCU and lockdep
  *
  * Also processes softirqs if needed and possible.

Reply via email to