On Mon, 29 Dec 2025 02:54:27 -0800
Thomas Ballasi <[email protected]> wrote:

> It indeed shows whether or not we're in an IRQ, but I believe the
> kernel shouldn't show erronous debugging values. Even though it can be
> obvious that we're in an interrupt, some people might look directly at
> the garbage PID value without having second thoughts and taking it for
> granted. On the other hand, it takes just a small check to mark the
> debugging information as clearly invalid, which complements the IRQ
> context flag.
> 
> If we shouldn't put that check there, I'd happily remove it, but I'd
> tend to think it's a trivial addition that can only be for the best.

I just don't like wasting valuable ring buffer space for something that can
be easily determined without it.

How about this. I just wrote up this patch, and it could be something you
use. I tested it against the sched waking events, by adding:

                __entry->target_cpu     = task_cpu(p);
        ),
 
-       TP_printk("comm=%s pid=%d prio=%d target_cpu=%03d",
+       TP_printk("comm=%s pid=%d prio=%d target_cpu=%03d %s",
                  __entry->comm, __entry->pid, __entry->prio,
-                 __entry->target_cpu)
+                 __entry->target_cpu,
+                 __event_in_irq() ? "(in-irq)" : "")
 );
 
Which produces:

          <idle>-0     [003] d.h4.    44.832126: sched_waking:         
comm=in:imklog pid=619 prio=120 target_cpu=006 (in-irq)
          <idle>-0     [003] d.s3.    44.832180: sched_waking:         
comm=rcu_preempt pid=15 prio=120 target_cpu=001 (in-irq)
       in:imklog-619   [006] d..2.    44.832393: sched_waking:         
comm=rs:main Q:Reg pid=620 prio=120 target_cpu=003 

You can see it adds "(in-irq)" when the even is executed from IRQ context
(soft or hard irq). But I also added __event_in_hardirq() and
__event_in_softirq() if you wanted to distinguish them.

Now you don't need to update what goes into the ring buffer (and waste its
space), but only update the output format that makes it obvious that the
task was in interrupt context or not.

I also used trace-cmd to record the events, and it still parses properly
with no updates to libtraceevent needed.

Would this work for you?

Below is the patch that allows for this:

-- Steve


diff --git a/include/trace/stages/stage3_trace_output.h 
b/include/trace/stages/stage3_trace_output.h
index 1e7b0bef95f5..53a23988a3b8 100644
--- a/include/trace/stages/stage3_trace_output.h
+++ b/include/trace/stages/stage3_trace_output.h
@@ -150,3 +150,11 @@
 
 #undef __get_buf
 #define __get_buf(len)         trace_seq_acquire(p, (len))
+
+#undef __event_in_hardirq
+#undef __event_in_softirq
+#undef __event_in_irq
+
+#define __event_in_hardirq()   (__entry->ent.flags & TRACE_FLAG_HARDIRQ)
+#define __event_in_softirq()   (__entry->ent.flags & TRACE_FLAG_SOFTIRQ)
+#define __event_in_irq()       (__entry->ent.flags & (TRACE_FLAG_HARDIRQ | 
TRACE_FLAG_SOFTIRQ))
diff --git a/include/trace/stages/stage7_class_define.h 
b/include/trace/stages/stage7_class_define.h
index fcd564a590f4..47008897a795 100644
--- a/include/trace/stages/stage7_class_define.h
+++ b/include/trace/stages/stage7_class_define.h
@@ -26,6 +26,25 @@
 #undef __print_hex_dump
 #undef __get_buf
 
+#undef __event_in_hardirq
+#undef __event_in_softirq
+#undef __event_in_irq
+
+/*
+ * The TRACE_FLAG_* are enums. Instead of using TRACE_DEFINE_ENUM(),
+ * use their hardcoded values. These values are parsed by user space
+ * tooling elsewhere so they will never change.
+ *
+ * See "enum trace_flag_type" in linux/trace_events.h:
+ *   TRACE_FLAG_HARDIRQ
+ *   TRACE_FLAG_SOFTIRQ
+ */
+
+/* This is what is displayed in the format files */
+#define __event_in_hardirq()   (REC->common_flags & 0x8)
+#define __event_in_softirq()   (REC->common_flags & 0x10)
+#define __event_in_irq()       (REC->common_flags & 0x18)
+
 /*
  * The below is not executed in the kernel. It is only what is
  * displayed in the print format for userspace to parse.

Reply via email to