Pass the softirq vector number to lockdep on callback execution so that
we know which one is involved while holding a lock. We will then be able
to pick up the proper LOCK_USED_IN_*_SOFTIRQ index to perform the
finegrained verifications.

Signed-off-by: Frederic Weisbecker <frede...@kernel.org>
Cc: Mauro Carvalho Chehab <mche...@s-opensource.com>
Cc: Joel Fernandes <j...@joelfernandes.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Pavan Kondeti <pkond...@codeaurora.org>
Cc: Paul E . McKenney <paul...@linux.vnet.ibm.com>
Cc: David S . Miller <da...@davemloft.net>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Sebastian Andrzej Siewior <bige...@linutronix.de>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
---
 include/linux/irqflags.h | 12 ++++++------
 kernel/softirq.c         |  8 ++++----
 lib/locking-selftest.c   |  4 ++--
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h
index 21619c92c377..623030a74866 100644
--- a/include/linux/irqflags.h
+++ b/include/linux/irqflags.h
@@ -43,13 +43,13 @@ do {                                                \
 do {                                           \
        current->hardirq_context--;             \
 } while (0)
-# define lockdep_softirq_enter()               \
+# define lockdep_softirq_enter(__VEC)          \
 do {                                           \
-       current->softirq_context++;             \
+       current->softirq_context |= BIT(__VEC); \
 } while (0)
-# define lockdep_softirq_exit()                        \
+# define lockdep_softirq_exit(__VEC)           \
 do {                                           \
-       current->softirq_context--;             \
+       current->softirq_context &= ~BIT(__VEC);\
 } while (0)
 #else
 # define trace_hardirqs_on()           do { } while (0)
@@ -60,8 +60,8 @@ do {                                          \
 # define trace_softirqs_enabled(p)     0
 # define trace_hardirq_enter()         do { } while (0)
 # define trace_hardirq_exit()          do { } while (0)
-# define lockdep_softirq_enter()       do { } while (0)
-# define lockdep_softirq_exit()                do { } while (0)
+# define lockdep_softirq_enter(vec)    do { } while (0)
+# define lockdep_softirq_exit(vec)     do { } while (0)
 #endif
 
 #if defined(CONFIG_IRQSOFF_TRACER) || \
diff --git a/kernel/softirq.c b/kernel/softirq.c
index d28813306b2c..2dcaef813acb 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -229,18 +229,15 @@ static inline bool lockdep_softirq_start(void)
                trace_hardirq_exit();
        }
 
-       lockdep_softirq_enter();
-
        return in_hardirq;
 }
 
 static inline void lockdep_softirq_end(bool in_hardirq)
 {
-       lockdep_softirq_exit();
-
        if (in_hardirq)
                trace_hardirq_enter();
 }
+
 #else
 static inline bool lockdep_softirq_start(void) { return false; }
 static inline void lockdep_softirq_end(bool in_hardirq) { }
@@ -288,9 +285,12 @@ asmlinkage __visible void __softirq_entry 
__do_softirq(void)
 
                kstat_incr_softirqs_this_cpu(vec_nr);
 
+               lockdep_softirq_enter(vec_nr);
                trace_softirq_entry(vec_nr);
                h->action(h);
                trace_softirq_exit(vec_nr);
+               lockdep_softirq_exit(vec_nr);
+
                if (unlikely(prev_count != preempt_count())) {
                        pr_err("huh, entered softirq %u %s %p with 
preempt_count %08x, exited with %08x?\n",
                               vec_nr, softirq_to_name[vec_nr], h->action,
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index 1e1bbf171eca..2bd782d7f2e5 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -197,11 +197,11 @@ static void init_shared_classes(void)
 #define SOFTIRQ_ENTER()                                \
                local_bh_disable();             \
                local_irq_disable();            \
-               lockdep_softirq_enter();        \
+               lockdep_softirq_enter(0);       \
                WARN_ON(!in_softirq());
 
 #define SOFTIRQ_EXIT()                         \
-               lockdep_softirq_exit();         \
+               lockdep_softirq_exit(0);        \
                local_irq_enable();             \
                local_bh_enable();
 
-- 
2.17.1

Reply via email to