The latency tracer format has a nice column to indicate IRQ state, but
this is not able to tell us about NMI state.

When tracing perf interrupt handlers (which often run in NMI context)
it is very useful to see how the events nest.

Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org>
---
 kernel/trace/trace.c        |    1 +
 kernel/trace/trace.h        |    1 +
 kernel/trace/trace_output.c |   10 +++++++---
 3 files changed, 9 insertions(+), 3 deletions(-)

--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1662,6 +1662,7 @@ tracing_generic_entry_update(struct trac
 #else
                TRACE_FLAG_IRQS_NOSUPPORT |
 #endif
+               ((pc & NMI_MASK    ) ? TRACE_FLAG_NMI     : 0) |
                ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) |
                ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) |
                (tif_need_resched() ? TRACE_FLAG_NEED_RESCHED : 0) |
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -125,6 +125,7 @@ enum trace_flag_type {
        TRACE_FLAG_HARDIRQ              = 0x08,
        TRACE_FLAG_SOFTIRQ              = 0x10,
        TRACE_FLAG_PREEMPT_RESCHED      = 0x20,
+       TRACE_FLAG_NMI                  = 0x40,
 };
 
 #define TRACE_BUF_SIZE         1024
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -389,7 +389,9 @@ int trace_print_lat_fmt(struct trace_seq
        char irqs_off;
        int hardirq;
        int softirq;
+       int nmi;
 
+       nmi = entry->flags & TRACE_FLAG_NMI;
        hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
        softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
 
@@ -415,10 +417,12 @@ int trace_print_lat_fmt(struct trace_seq
        }
 
        hardsoft_irq =
+               (nmi && hardirq)     ? 'Z' :
+               nmi                  ? 'z' :
                (hardirq && softirq) ? 'H' :
-               hardirq ? 'h' :
-               softirq ? 's' :
-               '.';
+               hardirq              ? 'h' :
+               softirq              ? 's' :
+                                      '.' ;
 
        trace_seq_printf(s, "%c%c%c",
                         irqs_off, need_resched, hardsoft_irq);


Reply via email to