Linux Trace Kernel
 help / color / mirror / Atom feed
From: Valentin Schneider <vschneid@redhat.com>
To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org
Cc: Steven Rostedt <rostedt@goodmis.org>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	Tomas Glozar <tglozar@redhat.com>,
	Costa Shulyupin <costa.shul@redhat.com>,
	Crystal Wood <crwood@redhat.com>,
	Ivan Pravdin <ipravdin.official@gmail.com>
Subject: [RFC PATCH 1/2] tracing/osnoise: Sample IPI counts
Date: Wed, 10 Jun 2026 15:04:51 +0200	[thread overview]
Message-ID: <20260610130457.1304245-2-vschneid@redhat.com> (raw)
In-Reply-To: <20260610130457.1304245-1-vschneid@redhat.com>

Osnoise already implictly accounts IPIs via its IRQ tracking, however it
can be interesting to distiguish between the two: undesired IPIs usually
imply a software configuration issue (e.g. wrong/incomplete CPU isolation)
whereas undesired (non-IPI) IRQs usually imply a hardware configuration
issue.

Signed-off-by: Valentin Schneider <vschneid@redhat.com>
---
Note that this is modifying the osnoise:osnoise_entry Ftrace entry; I know
trace events are sort of supposed to be stable, but I'm not sure about
ftrace entries.

Alternatively I can have this be purely supported in userspace osnoise by
hooking into the IPI events and counting IPIs separately from the osnoise
events.
---
 include/trace/events/osnoise.h |  1 +
 kernel/trace/trace_entries.h   |  6 ++-
 kernel/trace/trace_osnoise.c   | 80 ++++++++++++++++++++++++++++++++--
 3 files changed, 81 insertions(+), 6 deletions(-)

diff --git a/include/trace/events/osnoise.h b/include/trace/events/osnoise.h
index 3f42736238014..58442e58fe652 100644
--- a/include/trace/events/osnoise.h
+++ b/include/trace/events/osnoise.h
@@ -19,6 +19,7 @@ struct osnoise_sample {
 	int			irq_count;	/* # IRQs during this sample */
 	int			softirq_count;	/* # softirqs during this sample */
 	int			thread_count;	/* # threads during this sample */
+	int                     ipi_count;       /* # IPIs during this sample */
 };
 
 #ifdef CONFIG_TIMERLAT_TRACER
diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h
index 54417468fdeb1..aed778d859d37 100644
--- a/kernel/trace/trace_entries.h
+++ b/kernel/trace/trace_entries.h
@@ -430,16 +430,18 @@ FTRACE_ENTRY(osnoise, osnoise_entry,
 		__field(	unsigned int,		irq_count	)
 		__field(	unsigned int,		softirq_count	)
 		__field(	unsigned int,		thread_count	)
+		__field(	unsigned int,		ipi_count	)
 	),
 
-	F_printk("noise:%llu\tmax_sample:%llu\thw:%u\tnmi:%u\tirq:%u\tsoftirq:%u\tthread:%u\n",
+	F_printk("noise:%llu\tmax_sample:%llu\thw:%u\tnmi:%u\tirq:%u\tsoftirq:%u\tthread:%u\tipi:%u\n",
 		 __entry->noise,
 		 __entry->max_sample,
 		 __entry->hw_count,
 		 __entry->nmi_count,
 		 __entry->irq_count,
 		 __entry->softirq_count,
-		 __entry->thread_count)
+		 __entry->thread_count,
+		 __entry->ipi_count)
 );
 
 FTRACE_ENTRY(timerlat, timerlat_entry,
diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c
index 75678053b21c5..574629a6b22b3 100644
--- a/kernel/trace/trace_osnoise.c
+++ b/kernel/trace/trace_osnoise.c
@@ -35,6 +35,7 @@
 
 #include <trace/events/irq.h>
 #include <trace/events/sched.h>
+#include <trace/events/ipi.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/osnoise.h>
@@ -83,6 +84,10 @@ struct osnoise_instance {
 
 static struct list_head osnoise_instances;
 
+static struct cpumask osnoise_cpumask;
+static struct cpumask save_cpumask;
+static struct cpumask kthread_cpumask;
+
 static bool osnoise_has_registered_instances(void)
 {
 	return !!list_first_or_null_rcu(&osnoise_instances,
@@ -203,6 +208,11 @@ struct osn_thread {
 	u64	delta_start;
 };
 
+/* IPI runtime info */
+struct osn_ipi {
+	u64 count;
+};
+
 /*
  * Runtime information: this structure saves the runtime information used by
  * one sampling thread.
@@ -215,6 +225,7 @@ struct osnoise_variables {
 	struct osn_irq		irq;
 	struct osn_softirq	softirq;
 	struct osn_thread	thread;
+	struct osn_ipi          ipi;
 	local_t			int_counter;
 };
 
@@ -505,6 +516,7 @@ __record_osnoise_sample(struct osnoise_sample *sample, struct trace_buffer *buff
 	entry->irq_count	= sample->irq_count;
 	entry->softirq_count	= sample->softirq_count;
 	entry->thread_count	= sample->thread_count;
+	entry->ipi_count	= sample->ipi_count;
 
 	trace_buffer_unlock_commit_nostack(buffer, event);
 }
@@ -1288,6 +1300,7 @@ trace_sched_switch_callback(void *data, bool preempt,
  * Hook the osnoise tracer callbacks to handle the noise from other
  * threads on the necessary kernel events.
  */
+
 static int hook_thread_events(void)
 {
 	int ret;
@@ -1319,6 +1332,60 @@ static void unhook_thread_events(void)
 	unregister_migration_monitor();
 }
 
+static void ipi_emission(struct osnoise_variables *osn_var, unsigned int dst_cpu)
+{
+	if (!osn_var->sampling)
+		return;
+
+	osn_var->ipi.count++;
+}
+
+static void trace_ipi_send_cpu_callback(void *data, unsigned int cpu,
+					unsigned long callsite, void *callback)
+{
+	struct osnoise_variables *osn_var;
+
+	osn_var = per_cpu_ptr(&per_cpu_osnoise_var, cpu);
+	ipi_emission(osn_var, cpu);
+}
+
+static void trace_ipi_send_cpumask_callback(void *data, const struct cpumask *cpumask,
+					    unsigned long callsite, void *callback)
+{
+	struct osnoise_variables *osn_var;
+	int cpu;
+
+	for_each_cpu_and(cpu, cpumask, &osnoise_cpumask) {
+		osn_var = per_cpu_ptr(&per_cpu_osnoise_var, cpu);
+		ipi_emission(osn_var, cpu);
+	}
+}
+
+static int hook_ipi_events(void)
+{
+	int ret;
+
+	ret = register_trace_ipi_send_cpu(trace_ipi_send_cpu_callback, NULL);
+	if (ret)
+		return -EINVAL;
+
+	ret = register_trace_ipi_send_cpumask(trace_ipi_send_cpumask_callback, NULL);
+	if (ret)
+		goto out_unreg;
+
+	return 0;
+
+out_unreg:
+	unregister_trace_ipi_send_cpu(trace_ipi_send_cpu_callback, NULL);
+	return -EINVAL;
+}
+
+static void unhook_ipi_events(void)
+{
+	unregister_trace_ipi_send_cpu(trace_ipi_send_cpu_callback, NULL);
+	unregister_trace_ipi_send_cpumask(trace_ipi_send_cpumask_callback, NULL);
+}
+
 /*
  * save_osn_sample_stats - Save the osnoise_sample statistics
  *
@@ -1333,6 +1400,7 @@ save_osn_sample_stats(struct osnoise_variables *osn_var, struct osnoise_sample *
 	s->irq_count = osn_var->irq.count;
 	s->softirq_count = osn_var->softirq.count;
 	s->thread_count = osn_var->thread.count;
+	s->ipi_count = osn_var->ipi.count;
 }
 
 /*
@@ -1349,6 +1417,7 @@ diff_osn_sample_stats(struct osnoise_variables *osn_var, struct osnoise_sample *
 	s->irq_count = osn_var->irq.count - s->irq_count;
 	s->softirq_count = osn_var->softirq.count - s->softirq_count;
 	s->thread_count = osn_var->thread.count - s->thread_count;
+	s->ipi_count = osn_var->ipi.count - s->ipi_count;
 }
 
 /*
@@ -1613,10 +1682,6 @@ static int run_osnoise(void)
 	return ret;
 }
 
-static struct cpumask osnoise_cpumask;
-static struct cpumask save_cpumask;
-static struct cpumask kthread_cpumask;
-
 /*
  * osnoise_sleep - sleep until the next period
  */
@@ -2892,12 +2957,18 @@ static int osnoise_hook_events(void)
 		goto out_unhook_irq;
 
 	retval = hook_thread_events();
+	if (retval)
+		goto out_unhook_softirq;
+
+	retval = hook_ipi_events();
 	/*
 	 * All fine!
 	 */
 	if (!retval)
 		return 0;
 
+	unhook_thread_events();
+out_unhook_softirq:
 	unhook_softirq_events();
 out_unhook_irq:
 	unhook_irq_events();
@@ -2906,6 +2977,7 @@ static int osnoise_hook_events(void)
 
 static void osnoise_unhook_events(void)
 {
+	unhook_ipi_events();
 	unhook_thread_events();
 	unhook_softirq_events();
 	unhook_irq_events();
-- 
2.54.0


  reply	other threads:[~2026-06-10 13:05 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-10 13:04 [RFC PATCH 0/2] tracing/osnoise: Track IPIs Valentin Schneider
2026-06-10 13:04 ` Valentin Schneider [this message]
2026-06-10 19:51   ` [RFC PATCH 1/2] tracing/osnoise: Sample IPI counts Crystal Wood
2026-06-11  8:59     ` Tomas Glozar
2026-06-11 10:30       ` Valentin Schneider
2026-06-11 11:55         ` Tomas Glozar
2026-06-12  8:53           ` Valentin Schneider
2026-06-11 20:49         ` Crystal Wood
2026-06-11 10:21     ` Valentin Schneider
2026-06-10 13:04 ` [RFC PATCH 2/2] rtla/osnoise: Report IPI count in osnoise top Valentin Schneider

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260610130457.1304245-2-vschneid@redhat.com \
    --to=vschneid@redhat.com \
    --cc=costa.shul@redhat.com \
    --cc=crwood@redhat.com \
    --cc=ipravdin.official@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=mhiramat@kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=tglozar@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox