tracing: Partial revert of "tracing: Centralize preemptirq tracepoints and unify...
authorSteven Rostedt (VMware) <rostedt@goodmis.org>
Mon, 6 Aug 2018 19:50:58 +0000 (15:50 -0400)
committerSteven Rostedt (VMware) <rostedt@goodmis.org>
Fri, 10 Aug 2018 19:11:25 +0000 (15:11 -0400)
Joel Fernandes created a nice patch that cleaned up the duplicate hooks used
by lockdep and irqsoff latency tracer. It made both use tracepoints. But it
caused lockdep to trigger several false positives. We have not figured out
why yet, but removing lockdep from using the trace event hooks and just call
its helper functions directly (like it use to), makes the problem go away.

This is a partial revert of the clean up patch c3bc8fd637a9 ("tracing:
Centralize preemptirq tracepoints and unify their usage") that adds direct
calls for lockdep, but also keeps most of the clean up done to get rid of
the horrible preprocessor if statements.

Link: http://lkml.kernel.org/r/20180806155058.5ee875f4@gandalf.local.home
Cc: Peter Zijlstra <peterz@infradead.org>
Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
Fixes: c3bc8fd637a9 ("tracing: Centralize preemptirq tracepoints and unify their usage")
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
include/linux/irqflags.h
include/linux/lockdep.h
init/main.c
kernel/locking/lockdep.c
kernel/trace/trace_preemptirq.c

index 50edb9cbbd26e21def075e8bba53472335592638..21619c92c3770ca0cfc1f3381bee2fe8f065da88 100644 (file)
 #ifdef CONFIG_PROVE_LOCKING
   extern void trace_softirqs_on(unsigned long ip);
   extern void trace_softirqs_off(unsigned long ip);
+  extern void lockdep_hardirqs_on(unsigned long ip);
+  extern void lockdep_hardirqs_off(unsigned long ip);
 #else
-# define trace_softirqs_on(ip) do { } while (0)
-# define trace_softirqs_off(ip)        do { } while (0)
+  static inline void trace_softirqs_on(unsigned long ip) { }
+  static inline void trace_softirqs_off(unsigned long ip) { }
+  static inline void lockdep_hardirqs_on(unsigned long ip) { }
+  static inline void lockdep_hardirqs_off(unsigned long ip) { }
 #endif
 
 #ifdef CONFIG_TRACE_IRQFLAGS
index a8113357ceeb763e781f83b1660c9694af7f5e9f..b0d0b51c4d850892f01de631006d0b585697926e 100644 (file)
@@ -267,7 +267,6 @@ struct held_lock {
  * Initialization, self-test and debugging-output methods:
  */
 extern void lockdep_init(void);
-extern void lockdep_init_early(void);
 extern void lockdep_reset(void);
 extern void lockdep_reset_lock(struct lockdep_map *lock);
 extern void lockdep_free_key_range(void *start, unsigned long size);
@@ -408,7 +407,6 @@ static inline void lockdep_on(void)
 # define lock_set_class(l, n, k, s, i)         do { } while (0)
 # define lock_set_subclass(l, s, i)            do { } while (0)
 # define lockdep_init()                                do { } while (0)
-# define lockdep_init_early()                  do { } while (0)
 # define lockdep_init_map(lock, name, key, sub) \
                do { (void)(name); (void)(key); } while (0)
 # define lockdep_set_class(lock, key)          do { (void)(key); } while (0)
index 44fe43be84c1ff16d808523d01f96cf14e2acbf4..5d42e577643ac67e4cd18e74e8994b1159ca8813 100644 (file)
@@ -649,8 +649,6 @@ asmlinkage __visible void __init start_kernel(void)
        call_function_init();
        WARN(!irqs_disabled(), "Interrupts were enabled early\n");
 
-       lockdep_init_early();
-
        early_boot_irqs_disabled = false;
        local_irq_enable();
 
index 03bfaeb9f4e65341a9fb28c79a24739fed9e2a67..e406c5fdb41e9423aca5fd8db32ec8e692983d3b 100644 (file)
@@ -2840,8 +2840,7 @@ static void __trace_hardirqs_on_caller(unsigned long ip)
        debug_atomic_inc(hardirqs_on_events);
 }
 
-static void lockdep_hardirqs_on(void *none, unsigned long ignore,
-                               unsigned long ip)
+void lockdep_hardirqs_on(unsigned long ip)
 {
        if (unlikely(!debug_locks || current->lockdep_recursion))
                return;
@@ -2885,8 +2884,7 @@ static void lockdep_hardirqs_on(void *none, unsigned long ignore,
 /*
  * Hardirqs were disabled:
  */
-static void lockdep_hardirqs_off(void *none, unsigned long ignore,
-                                unsigned long ip)
+void lockdep_hardirqs_off(unsigned long ip)
 {
        struct task_struct *curr = current;
 
@@ -4315,14 +4313,6 @@ out_restore:
        raw_local_irq_restore(flags);
 }
 
-void __init lockdep_init_early(void)
-{
-#ifdef CONFIG_PROVE_LOCKING
-       register_trace_prio_irq_disable(lockdep_hardirqs_off, NULL, INT_MAX);
-       register_trace_prio_irq_enable(lockdep_hardirqs_on, NULL, INT_MIN);
-#endif
-}
-
 void __init lockdep_init(void)
 {
        printk("Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar\n");
index e76b78bf258ef7414294bda8b939f71fe15fc4d2..fa656b25f427b41e42a69a7e81d2f4cc41ad737b 100644 (file)
@@ -19,41 +19,45 @@ static DEFINE_PER_CPU(int, tracing_irq_cpu);
 
 void trace_hardirqs_on(void)
 {
-       if (!this_cpu_read(tracing_irq_cpu))
-               return;
+       if (this_cpu_read(tracing_irq_cpu)) {
+               trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
+               this_cpu_write(tracing_irq_cpu, 0);
+       }
 
-       trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
-       this_cpu_write(tracing_irq_cpu, 0);
+       lockdep_hardirqs_on(CALLER_ADDR0);
 }
 EXPORT_SYMBOL(trace_hardirqs_on);
 
 void trace_hardirqs_off(void)
 {
-       if (this_cpu_read(tracing_irq_cpu))
-               return;
+       if (!this_cpu_read(tracing_irq_cpu)) {
+               this_cpu_write(tracing_irq_cpu, 1);
+               trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
+       }
 
-       this_cpu_write(tracing_irq_cpu, 1);
-       trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
+       lockdep_hardirqs_off(CALLER_ADDR0);
 }
 EXPORT_SYMBOL(trace_hardirqs_off);
 
 __visible void trace_hardirqs_on_caller(unsigned long caller_addr)
 {
-       if (!this_cpu_read(tracing_irq_cpu))
-               return;
+       if (this_cpu_read(tracing_irq_cpu)) {
+               trace_irq_enable_rcuidle(CALLER_ADDR0, caller_addr);
+               this_cpu_write(tracing_irq_cpu, 0);
+       }
 
-       trace_irq_enable_rcuidle(CALLER_ADDR0, caller_addr);
-       this_cpu_write(tracing_irq_cpu, 0);
+       lockdep_hardirqs_on(CALLER_ADDR0);
 }
 EXPORT_SYMBOL(trace_hardirqs_on_caller);
 
 __visible void trace_hardirqs_off_caller(unsigned long caller_addr)
 {
-       if (this_cpu_read(tracing_irq_cpu))
-               return;
+       if (!this_cpu_read(tracing_irq_cpu)) {
+               this_cpu_write(tracing_irq_cpu, 1);
+               trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr);
+       }
 
-       this_cpu_write(tracing_irq_cpu, 1);
-       trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr);
+       lockdep_hardirqs_off(CALLER_ADDR0);
 }
 EXPORT_SYMBOL(trace_hardirqs_off_caller);
 #endif /* CONFIG_TRACE_IRQFLAGS */