On Fri, 2013-08-02 at 14:57 -0400, Steven Rostedt wrote:

> The tracer started within the NMI, but out of sheer (bad) luck. That's
> because the NMI code has no logic to handle tracing interrupts on or
> off, due to the problems they cause. We may at most be able to just
> ignore all NMIs by adding a 'in_nmi()' check. I can send you a patch if
> you want.

It was trivial enough to make. Maybe this will fix things for you.

-- Steve

diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index 2aefbee..500b2e0 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -453,13 +453,13 @@ EXPORT_SYMBOL_GPL(stop_critical_timings);
 #ifdef CONFIG_PROVE_LOCKING
 void time_hardirqs_on(unsigned long a0, unsigned long a1)
 {
-       if (!preempt_trace() && irq_trace())
+       if (!in_nmi() && !preempt_trace() && irq_trace())
                stop_critical_timing(a0, a1);
 }
 
 void time_hardirqs_off(unsigned long a0, unsigned long a1)
 {
-       if (!preempt_trace() && irq_trace())
+       if (!in_nmi() && !preempt_trace() && irq_trace())
                start_critical_timing(a0, a1);
 }
 
@@ -486,28 +486,28 @@ inline void print_irqtrace_events(struct task_struct 
*curr)
  */
 void trace_hardirqs_on(void)
 {
-       if (!preempt_trace() && irq_trace())
+       if (!in_nmi() && !preempt_trace() && irq_trace())
                stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1);
 }
 EXPORT_SYMBOL(trace_hardirqs_on);
 
 void trace_hardirqs_off(void)
 {
-       if (!preempt_trace() && irq_trace())
+       if (!in_nmi() && !preempt_trace() && irq_trace())
                start_critical_timing(CALLER_ADDR0, CALLER_ADDR1);
 }
 EXPORT_SYMBOL(trace_hardirqs_off);
 
 void trace_hardirqs_on_caller(unsigned long caller_addr)
 {
-       if (!preempt_trace() && irq_trace())
+       if (!in_nmi() && !preempt_trace() && irq_trace())
                stop_critical_timing(CALLER_ADDR0, caller_addr);
 }
 EXPORT_SYMBOL(trace_hardirqs_on_caller);
 
 void trace_hardirqs_off_caller(unsigned long caller_addr)
 {
-       if (!preempt_trace() && irq_trace())
+       if (!in_nmi() && !preempt_trace() && irq_trace())
                start_critical_timing(CALLER_ADDR0, caller_addr);
 }
 EXPORT_SYMBOL(trace_hardirqs_off_caller);
@@ -518,13 +518,13 @@ EXPORT_SYMBOL(trace_hardirqs_off_caller);
 #ifdef CONFIG_PREEMPT_TRACER
 void trace_preempt_on(unsigned long a0, unsigned long a1)
 {
-       if (preempt_trace() && !irq_trace())
+       if (!in_nmi() && preempt_trace() && !irq_trace())
                stop_critical_timing(a0, a1);
 }
 
 void trace_preempt_off(unsigned long a0, unsigned long a1)
 {
-       if (preempt_trace() && !irq_trace())
+       if (!in_nmi() && preempt_trace() && !irq_trace())
                start_critical_timing(a0, a1);
 }
 #endif /* CONFIG_PREEMPT_TRACER */


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to