diff --git a/kernel/softirq.c b/kernel/softirq.c
index f84aa48c0e6663de619daa869f6a1274e0cc5b50..9a4500e4c1893ec22e17c4ac98a1d34cc6a0b6cf 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -213,40 +213,35 @@ EXPORT_SYMBOL(local_bh_enable_ip);
 
 #ifdef CONFIG_TRACE_IRQFLAGS
 /*
- * Convoluted means of passing __do_softirq() a message through the various
- * architecture execute_on_stack() bits.
- *
  * When we run softirqs from irq_exit() and thus on the hardirq stack we need
  * to keep the lockdep irq context tracking as tight as possible in order to
  * not miss-qualify lock contexts and miss possible deadlocks.
  */
-static DEFINE_PER_CPU(int, softirq_from_hardirq);
 
-static inline void lockdep_softirq_from_hardirq(void)
+static inline bool lockdep_softirq_start(void)
 {
-	this_cpu_write(softirq_from_hardirq, 1);
-}
+	bool in_hardirq = false;
 
-static inline void lockdep_softirq_start(void)
-{
-	if (this_cpu_read(softirq_from_hardirq))
+	if (trace_hardirq_context(current)) {
+		in_hardirq = true;
 		trace_hardirq_exit();
+	}
+
 	lockdep_softirq_enter();
+
+	return in_hardirq;
 }
 
-static inline void lockdep_softirq_end(void)
+static inline void lockdep_softirq_end(bool in_hardirq)
 {
 	lockdep_softirq_exit();
-	if (this_cpu_read(softirq_from_hardirq)) {
-		this_cpu_write(softirq_from_hardirq, 0);
+
+	if (in_hardirq)
 		trace_hardirq_enter();
-	}
 }
-
 #else
-static inline void lockdep_softirq_from_hardirq(void) { }
-static inline void lockdep_softirq_start(void) { }
-static inline void lockdep_softirq_end(void) { }
+static inline bool lockdep_softirq_start(void) { return false; }
+static inline void lockdep_softirq_end(bool in_hardirq) { }
 #endif
 
 asmlinkage void __do_softirq(void)
@@ -255,6 +250,7 @@ asmlinkage void __do_softirq(void)
 	unsigned long old_flags = current->flags;
 	int max_restart = MAX_SOFTIRQ_RESTART;
 	struct softirq_action *h;
+	bool in_hardirq;
 	__u32 pending;
 	int cpu;
 
@@ -269,7 +265,7 @@ asmlinkage void __do_softirq(void)
 	account_irq_enter_time(current);
 
 	__local_bh_disable(_RET_IP_, SOFTIRQ_OFFSET);
-	lockdep_softirq_start();
+	in_hardirq = lockdep_softirq_start();
 
 	cpu = smp_processor_id();
 restart:
@@ -316,7 +312,7 @@ asmlinkage void __do_softirq(void)
 		wakeup_softirqd();
 	}
 
-	lockdep_softirq_end();
+	lockdep_softirq_end(in_hardirq);
 	account_irq_exit_time(current);
 	__local_bh_enable(SOFTIRQ_OFFSET);
 	WARN_ON_ONCE(in_interrupt());
@@ -365,7 +361,6 @@ void irq_enter(void)
 static inline void invoke_softirq(void)
 {
 	if (!force_irqthreads) {
-		lockdep_softirq_from_hardirq();
 #ifdef CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK
 		/*
 		 * We can safely execute softirq on the current stack if