[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250630195243.701516-2-wander@redhat.com>
Date: Mon, 30 Jun 2025 16:52:38 -0300
From: Wander Lairson Costa <wander@...hat.com>
To: Ingo Molnar <mingo@...hat.com>,
Peter Zijlstra <peterz@...radead.org>,
Juri Lelli <juri.lelli@...hat.com>,
Vincent Guittot <vincent.guittot@...aro.org>,
Dietmar Eggemann <dietmar.eggemann@....com>,
Steven Rostedt <rostedt@...dmis.org>,
Ben Segall <bsegall@...gle.com>,
Mel Gorman <mgorman@...e.de>,
Valentin Schneider <vschneid@...hat.com>,
Masami Hiramatsu <mhiramat@...nel.org>,
Mathieu Desnoyers <mathieu.desnoyers@...icios.com>,
Wander Lairson Costa <wander@...hat.com>,
Thomas Gleixner <tglx@...utronix.de>,
Boqun Feng <boqun.feng@...il.com>,
David Woodhouse <dwmw@...zon.co.uk>,
linux-kernel@...r.kernel.org (open list),
linux-trace-kernel@...r.kernel.org (open list:TRACING)
Cc: Arnaldo Carvalho de Melo <acme@...nel.org>,
Clark Williams <williams@...hat.com>,
Gabriele Monaco <gmonaco@...hat.com>
Subject: [PATCH v2 1/2] trace/preemptirq: reduce overhead of irq_enable/disable tracepoints
The irqsoff tracer is rarely enabled in production systems due to the
non-negligible overhead it introduces—even when unused. This is caused
by how trace_hardirqs_on/off() are always invoked in
local_irq_enable/disable(), evaluate the tracepoint static key.
This patch reduces the overhead in the common case where the tracepoint
is disabled by performing the static key check earlier, avoiding the
call to trace_hardirqs_on/off() entirely.
This makes the impact of disabled preemptirq IRQ tracing negligible in
performance-sensitive environments.
Signed-off-by: Wander Lairson Costa <wander@...hat.com>
Suggested-by: Steven Rostedt <rostedt@...dmis.org>
Cc: Arnaldo Carvalho de Melo <acme@...nel.org>
Cc: Clark Williams <williams@...hat.com>
Cc: Gabriele Monaco <gmonaco@...hat.com>
Cc: Juri Lelli <juri.lelli@...hat.com>
---
include/linux/irqflags.h | 30 +++++++++++++++++++++---------
kernel/trace/trace_preemptirq.c | 3 +++
2 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h
index 57b074e0cfbb..40e456fa3d10 100644
--- a/include/linux/irqflags.h
+++ b/include/linux/irqflags.h
@@ -17,6 +17,7 @@
#include <linux/cleanup.h>
#include <asm/irqflags.h>
#include <asm/percpu.h>
+#include <linux/tracepoint-defs.h>
struct task_struct;
@@ -197,9 +198,17 @@ extern void warn_bogus_irq_restore(void);
*/
#ifdef CONFIG_TRACE_IRQFLAGS
+DECLARE_TRACEPOINT(irq_enable);
+DECLARE_TRACEPOINT(irq_disable);
+
+#define __trace_enabled(tp) \
+ (IS_ENABLED(CONFIG_PROVE_LOCKING) || \
+ tracepoint_enabled(tp))
+
#define local_irq_enable() \
do { \
- trace_hardirqs_on(); \
+ if (__trace_enabled(irq_enable)) \
+ trace_hardirqs_on(); \
raw_local_irq_enable(); \
} while (0)
@@ -207,31 +216,34 @@ extern void warn_bogus_irq_restore(void);
do { \
bool was_disabled = raw_irqs_disabled();\
raw_local_irq_disable(); \
- if (!was_disabled) \
+ if (__trace_enabled(irq_disable) && \
+ !was_disabled) \
trace_hardirqs_off(); \
} while (0)
#define local_irq_save(flags) \
do { \
raw_local_irq_save(flags); \
- if (!raw_irqs_disabled_flags(flags)) \
+ if (__trace_enabled(irq_disable) && \
+ !raw_irqs_disabled_flags(flags)) \
trace_hardirqs_off(); \
} while (0)
#define local_irq_restore(flags) \
do { \
- if (!raw_irqs_disabled_flags(flags)) \
+ if (__trace_enabled(irq_enable) && \
+ !raw_irqs_disabled_flags(flags)) \
trace_hardirqs_on(); \
raw_local_irq_restore(flags); \
} while (0)
-#define safe_halt() \
- do { \
- trace_hardirqs_on(); \
- raw_safe_halt(); \
+#define safe_halt() \
+ do { \
+ if (__trace_enabled(irq_enable)) \
+ trace_hardirqs_on(); \
+ raw_safe_halt(); \
} while (0)
-
#else /* !CONFIG_TRACE_IRQFLAGS */
#define local_irq_enable() do { raw_local_irq_enable(); } while (0)
diff --git a/kernel/trace/trace_preemptirq.c b/kernel/trace/trace_preemptirq.c
index 0c42b15c3800..90ee65db4516 100644
--- a/kernel/trace/trace_preemptirq.c
+++ b/kernel/trace/trace_preemptirq.c
@@ -111,6 +111,9 @@ void trace_hardirqs_off(void)
}
EXPORT_SYMBOL(trace_hardirqs_off);
NOKPROBE_SYMBOL(trace_hardirqs_off);
+
+EXPORT_TRACEPOINT_SYMBOL(irq_disable);
+EXPORT_TRACEPOINT_SYMBOL(irq_enable);
#endif /* CONFIG_TRACE_IRQFLAGS */
#ifdef CONFIG_TRACE_PREEMPT_TOGGLE
--
2.50.0
Powered by blists - more mailing lists