Linux Trace Kernel
 help / color / mirror / Atom feed
* [PATCH] trace: fix UBSAN warning in __remove_instance
From: Darrick J. Wong @ 2025-12-16 17:49 UTC (permalink / raw)
  To: rostedt, mhiramat; +Cc: mathieu.desnoyers, linux-trace-kernel

From: Darrick J. Wong <djwong@kernel.org>

xfs/558 triggers the following UBSAN warning:

 ------------[ cut here ]------------
 UBSAN: shift-out-of-bounds in /storage/home/djwong/cdev/work/linux-xfs/kernel/trace/trace.c:10510:10
 shift exponent 32 is too large for 32-bit type 'int'
 CPU: 1 UID: 0 PID: 888674 Comm: rmdir Not tainted 6.19.0-rc1-xfsx #rc1 PREEMPT(lazy)  dbf607ef4c142c563f76d706e71af9731d7b9c90
 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-4.module+el8.8.0+21164+ed375313 04/01/2014
 Call Trace:
  <TASK>
  dump_stack_lvl+0x4a/0x70
  ubsan_epilogue+0x5/0x2b
  __ubsan_handle_shift_out_of_bounds.cold+0x5e/0x113
  __remove_instance.part.0.constprop.0.cold+0x18/0x26f
  instance_rmdir+0xf3/0x110
  tracefs_syscall_rmdir+0x4d/0x90
  vfs_rmdir+0x139/0x230
  do_rmdir+0x143/0x230
  __x64_sys_rmdir+0x1d/0x20
  do_syscall_64+0x44/0x230
  entry_SYSCALL_64_after_hwframe+0x4b/0x53
 RIP: 0033:0x7f7ae8e51f17
 Code: f0 ff ff 73 01 c3 48 8b 0d de 2e 0e 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 b8 54 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 01 c3 48 8b 15 b1 2e 0e 00 f7 d8 64 89 02 b8
 RSP: 002b:00007ffd90743f08 EFLAGS: 00000246 ORIG_RAX: 0000000000000054
 RAX: ffffffffffffffda RBX: 00007ffd907440f8 RCX: 00007f7ae8e51f17
 RDX: 00007f7ae8f3c5c0 RSI: 00007ffd90744a21 RDI: 00007ffd90744a21
 RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000
 R10: 00007f7ae8f35ac0 R11: 0000000000000246 R12: 00007ffd90744a21
 R13: 0000000000000001 R14: 00007f7ae8f8b000 R15: 000055e5283e6a98
  </TASK>
 ---[ end trace ]---

whilst tearing down an ftrace instance.  TRACE_FLAGS_MAX_SIZE is now 64,
so the mask comparison expression must be typecast to a u64 value to
avoid an overflow.  AFAICT, ZEROED_TRACE_FLAGS is already cast to ULL
so this is ok.

Fixes: bbec8e28cac592 ("tracing: Allow tracer to add more than 32 options")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
 kernel/trace/trace.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e575956ef9b5a2..6f2148df14d966 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -10507,7 +10507,7 @@ static int __remove_instance(struct trace_array *tr)
 
 	/* Disable all the flags that were enabled coming in */
 	for (i = 0; i < TRACE_FLAGS_MAX_SIZE; i++) {
-		if ((1 << i) & ZEROED_TRACE_FLAGS)
+		if ((1ULL << i) & ZEROED_TRACE_FLAGS)
 			set_tracer_flag(tr, 1ULL << i, 0);
 	}
 

^ permalink raw reply related

* [PATCH v4] tracing: Guard __DECLARE_TRACE() use of __DO_TRACE_CALL() with SRCU-fast
From: Steven Rostedt @ 2025-12-16 17:08 UTC (permalink / raw)
  To: LKML, Linux Trace Kernel
  Cc: Masami Hiramatsu, Mathieu Desnoyers, Paul E. McKenney,
	Sebastian Andrzej Siewior, bpf

From: "Paul E. McKenney" <paulmck@kernel.org>

The current use of guard(preempt_notrace)() within __DECLARE_TRACE()
to protect invocation of __DO_TRACE_CALL() means that BPF programs
attached to tracepoints are non-preemptible.  This is unhelpful in
real-time systems, whose users apparently wish to use BPF while also
achieving low latencies.  (Who knew?)

One option would be to use preemptible RCU, but this introduces
many opportunities for infinite recursion, which many consider to
be counterproductive, especially given the relatively small stacks
provided by the Linux kernel.  These opportunities could be shut down
by sufficiently energetic duplication of code, but this sort of thing
is considered impolite in some circles.

Therefore, use the shiny new SRCU-fast API, which provides somewhat faster
readers than those of preemptible RCU, at least on Paul E. McKenney's
laptop, where task_struct access is more expensive than access to per-CPU
variables.  And SRCU-fast provides way faster readers than does SRCU,
courtesy of being able to avoid the read-side use of smp_mb().  Also,
it is quite straightforward to create srcu_read_{,un}lock_fast_notrace()
functions.

While in the area, SRCU now supports early boot call_srcu().  Therefore,
remove the checks that used to avoid such use from rcu_free_old_probes()
before this commit was applied:

e53244e2c893 ("tracepoint: Remove SRCU protection")

The current commit can be thought of as an approximate revert of that
commit, with some compensating additions of preemption disabling.
This preemption disabling uses guard(preempt_notrace)().

However, Yonghong Song points out that BPF assumes that non-sleepable
BPF programs will remain on the same CPU, which means that migration
must be disabled whenever preemption remains enabled.  In addition,
non-RT kernels have performance expectations that would be violated by
allowing the BPF programs to be preempted.

Therefore, continue to disable preemption in non-RT kernels, and protect
the BPF program with both SRCU and migration disabling for RT kernels,
and even then only if preemption is not already disabled.

Link: https://lore.kernel.org/all/20250613152218.1924093-1-bigeasy@linutronix.de/
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: <bpf@vger.kernel.org>
Signed-off-by: Steve Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
Changes since v3: https://patch.msgid.link/e2fe3162-4b7b-44d6-91ff-f439b3dce706@paulmck-laptop

- Added a trace_event_buffer_reserve_syscall() interface for system call
  events to use. This will not need to mess with the migrate disable
  counter. It just expects preemption to be disabled.

 include/linux/trace_events.h  | 24 ++++++++++++++++++++++++
 include/linux/tracepoint.h    | 25 ++++++++++++++++++++++---
 include/trace/perf.h          |  4 ++--
 include/trace/trace_events.h  | 21 +++++++++++++++++++--
 kernel/trace/trace_events.c   | 30 ++++++++++++++++++++----------
 kernel/trace/trace_syscalls.c |  4 ++--
 kernel/tracepoint.c           | 33 +++++++++++++++++++++++++++++++++
 7 files changed, 122 insertions(+), 19 deletions(-)

diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 3690221ba3d8..a2704c35eda8 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -222,6 +222,26 @@ static inline unsigned int tracing_gen_ctx_dec(void)
 	return trace_ctx;
 }
 
+/*
+ * When PREEMPT_RT is enabled, trace events are called with disabled
+ * migration. The trace events need to know if the tracepoint disabled
+ * migration or not so that what is recorded to the ring buffer shows
+ * the state of when the trace event triggered, and not the state caused
+ * by the trace event.
+ */
+#ifdef CONFIG_PREEMPT_RT
+static inline unsigned int tracing_gen_ctx_dec_cond(void)
+{
+	unsigned int trace_ctx;
+
+	trace_ctx = tracing_gen_ctx_dec();
+	/* The migration counter starts at bit 4 */
+	return trace_ctx - (1 << 4);
+}
+#else
+# define tracing_gen_ctx_dec_cond() tracing_gen_ctx_dec()
+#endif
+
 struct trace_event_file;
 
 struct ring_buffer_event *
@@ -313,6 +333,10 @@ void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
 				  struct trace_event_file *trace_file,
 				  unsigned long len);
 
+void *trace_event_buffer_reserve_syscall(struct trace_event_buffer *fbuffer,
+					 struct trace_event_file *trace_file,
+					 unsigned long len);
+
 void trace_event_buffer_commit(struct trace_event_buffer *fbuffer);
 
 enum {
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 8a56f3278b1b..0563c7d9fcb2 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -100,6 +100,25 @@ void for_each_tracepoint_in_module(struct module *mod,
 }
 #endif /* CONFIG_MODULES */
 
+/*
+ * BPF programs can attach to the tracepoint callbacks. But if the
+ * callbacks are called with preemption disabled, the BPF programs
+ * can cause quite a bit of latency. When PREEMPT_RT is enabled,
+ * instead of disabling preemption, use srcu_fast_notrace() for
+ * synchronization. As BPF programs that are attached to tracepoints
+ * expect to stay on the same CPU, also disable migration.
+ */
+#ifdef CONFIG_PREEMPT_RT
+extern struct srcu_struct tracepoint_srcu;
+# define tracepoint_sync() synchronize_srcu(&tracepoint_srcu);
+# define tracepoint_guard()				\
+	guard(srcu_fast_notrace)(&tracepoint_srcu);	\
+	guard(migrate)()
+#else
+# define tracepoint_sync() synchronize_rcu();
+# define tracepoint_guard() guard(preempt_notrace)()
+#endif
+
 /*
  * tracepoint_synchronize_unregister must be called between the last tracepoint
  * probe unregistration and the end of module exit to make sure there is no
@@ -115,7 +134,7 @@ void for_each_tracepoint_in_module(struct module *mod,
 static inline void tracepoint_synchronize_unregister(void)
 {
 	synchronize_rcu_tasks_trace();
-	synchronize_rcu();
+	tracepoint_sync();
 }
 static inline bool tracepoint_is_faultable(struct tracepoint *tp)
 {
@@ -275,13 +294,13 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
 		return static_branch_unlikely(&__tracepoint_##name.key);\
 	}
 
-#define __DECLARE_TRACE(name, proto, args, cond, data_proto)		\
+#define __DECLARE_TRACE(name, proto, args, cond, data_proto)			\
 	__DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto)) \
 	static inline void __do_trace_##name(proto)			\
 	{								\
 		TRACEPOINT_CHECK(name)					\
 		if (cond) {						\
-			guard(preempt_notrace)();			\
+			tracepoint_guard();				\
 			__DO_TRACE_CALL(name, TP_ARGS(args));		\
 		}							\
 	}								\
diff --git a/include/trace/perf.h b/include/trace/perf.h
index a1754b73a8f5..348ad1d9b556 100644
--- a/include/trace/perf.h
+++ b/include/trace/perf.h
@@ -71,6 +71,7 @@ perf_trace_##call(void *__data, proto)					\
 	u64 __count __attribute__((unused));				\
 	struct task_struct *__task __attribute__((unused));		\
 									\
+	guard(preempt_notrace)();					\
 	do_perf_trace_##call(__data, args);				\
 }
 
@@ -85,9 +86,8 @@ perf_trace_##call(void *__data, proto)					\
 	struct task_struct *__task __attribute__((unused));		\
 									\
 	might_fault();							\
-	preempt_disable_notrace();					\
+	guard(preempt_notrace)();					\
 	do_perf_trace_##call(__data, args);				\
-	preempt_enable_notrace();					\
 }
 
 /*
diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h
index 4f22136fd465..6fb58387e9f1 100644
--- a/include/trace/trace_events.h
+++ b/include/trace/trace_events.h
@@ -429,6 +429,22 @@ do_trace_event_raw_event_##call(void *__data, proto)			\
 	trace_event_buffer_commit(&fbuffer);				\
 }
 
+/*
+ * When PREEMPT_RT is enabled, the tracepoint does not disable preemption
+ * but instead disables migration. The callbacks for the trace events
+ * need to have a consistent state so that it can reflect the proper
+ * preempt_disabled counter.
+ */
+#ifdef CONFIG_PREEMPT_RT
+/* disable preemption for RT so that the counters still match */
+# define trace_event_guard() guard(preempt_notrace)()
+/* Have syscalls up the migrate disable counter to emulate non-syscalls */
+# define trace_syscall_event_guard() guard(migrate)()
+#else
+# define trace_event_guard()
+# define trace_syscall_event_guard()
+#endif
+
 #undef DECLARE_EVENT_CLASS
 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
 __DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), PARAMS(tstruct), \
@@ -436,6 +452,7 @@ __DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), PARAMS(tstruct), \
 static notrace void							\
 trace_event_raw_event_##call(void *__data, proto)			\
 {									\
+	trace_event_guard();						\
 	do_trace_event_raw_event_##call(__data, args);			\
 }
 
@@ -447,9 +464,9 @@ static notrace void							\
 trace_event_raw_event_##call(void *__data, proto)			\
 {									\
 	might_fault();							\
-	preempt_disable_notrace();					\
+	trace_syscall_event_guard();					\
+	guard(preempt_notrace)();					\
 	do_trace_event_raw_event_##call(__data, args);			\
-	preempt_enable_notrace();					\
 }
 
 /*
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index b16a5a158040..a5a93d243047 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -649,9 +649,9 @@ bool trace_event_ignore_this_pid(struct trace_event_file *trace_file)
 }
 EXPORT_SYMBOL_GPL(trace_event_ignore_this_pid);
 
-void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
-				 struct trace_event_file *trace_file,
-				 unsigned long len)
+static __always_inline void *buffer_reserve(struct trace_event_buffer *fbuffer,
+					    struct trace_event_file *trace_file,
+					    unsigned long len)
 {
 	struct trace_event_call *event_call = trace_file->event_call;
 
@@ -659,13 +659,6 @@ void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
 	    trace_event_ignore_this_pid(trace_file))
 		return NULL;
 
-	/*
-	 * If CONFIG_PREEMPTION is enabled, then the tracepoint itself disables
-	 * preemption (adding one to the preempt_count). Since we are
-	 * interested in the preempt_count at the time the tracepoint was
-	 * hit, we need to subtract one to offset the increment.
-	 */
-	fbuffer->trace_ctx = tracing_gen_ctx_dec();
 	fbuffer->trace_file = trace_file;
 
 	fbuffer->event =
@@ -679,8 +672,25 @@ void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
 	fbuffer->entry = ring_buffer_event_data(fbuffer->event);
 	return fbuffer->entry;
 }
+
+void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
+				 struct trace_event_file *trace_file,
+				 unsigned long len)
+{
+	fbuffer->trace_ctx = tracing_gen_ctx_dec_cond();
+	return buffer_reserve(fbuffer, trace_file, len);
+}
 EXPORT_SYMBOL_GPL(trace_event_buffer_reserve);
 
+void *trace_event_buffer_reserve_syscall(struct trace_event_buffer *fbuffer,
+					 struct trace_event_file *trace_file,
+					 unsigned long len)
+{
+	fbuffer->trace_ctx = tracing_gen_ctx_dec();
+	return buffer_reserve(fbuffer, trace_file, len);
+}
+
+
 int trace_event_reg(struct trace_event_call *call,
 		    enum trace_reg type, void *data)
 {
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index e96d0063cbcf..f330fd22ea78 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -909,7 +909,7 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
 
 	size += sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args;
 
-	entry = trace_event_buffer_reserve(&fbuffer, trace_file, size);
+	entry = trace_event_buffer_reserve_syscall(&fbuffer, trace_file, size);
 	if (!entry)
 		return;
 
@@ -955,7 +955,7 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
 	if (!sys_data)
 		return;
 
-	entry = trace_event_buffer_reserve(&fbuffer, trace_file, sizeof(*entry));
+	entry = trace_event_buffer_reserve_syscall(&fbuffer, trace_file, sizeof(*entry));
 	if (!entry)
 		return;
 
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index 62719d2941c9..6a6bcf86bfbe 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -25,6 +25,12 @@ enum tp_func_state {
 extern tracepoint_ptr_t __start___tracepoints_ptrs[];
 extern tracepoint_ptr_t __stop___tracepoints_ptrs[];
 
+/* In PREEMPT_RT, SRCU is used to protect the tracepoint callbacks */
+#ifdef CONFIG_PREEMPT_RT
+DEFINE_SRCU_FAST(tracepoint_srcu);
+EXPORT_SYMBOL_GPL(tracepoint_srcu);
+#endif
+
 enum tp_transition_sync {
 	TP_TRANSITION_SYNC_1_0_1,
 	TP_TRANSITION_SYNC_N_2_1,
@@ -34,6 +40,7 @@ enum tp_transition_sync {
 
 struct tp_transition_snapshot {
 	unsigned long rcu;
+	unsigned long srcu_gp;
 	bool ongoing;
 };
 
@@ -46,6 +53,9 @@ static void tp_rcu_get_state(enum tp_transition_sync sync)
 
 	/* Keep the latest get_state snapshot. */
 	snapshot->rcu = get_state_synchronize_rcu();
+#ifdef CONFIG_PREEMPT_RT
+	snapshot->srcu_gp = start_poll_synchronize_srcu(&tracepoint_srcu);
+#endif
 	snapshot->ongoing = true;
 }
 
@@ -56,6 +66,10 @@ static void tp_rcu_cond_sync(enum tp_transition_sync sync)
 	if (!snapshot->ongoing)
 		return;
 	cond_synchronize_rcu(snapshot->rcu);
+#ifdef CONFIG_PREEMPT_RT
+	if (!poll_state_synchronize_srcu(&tracepoint_srcu, snapshot->srcu_gp))
+		synchronize_srcu(&tracepoint_srcu);
+#endif
 	snapshot->ongoing = false;
 }
 
@@ -101,10 +115,22 @@ static inline void *allocate_probes(int count)
 	return p == NULL ? NULL : p->probes;
 }
 
+#ifdef CONFIG_PREEMPT_RT
+static void srcu_free_old_probes(struct rcu_head *head)
+{
+	kfree(container_of(head, struct tp_probes, rcu));
+}
+
+static void rcu_free_old_probes(struct rcu_head *head)
+{
+	call_srcu(&tracepoint_srcu, head, srcu_free_old_probes);
+}
+#else
 static void rcu_free_old_probes(struct rcu_head *head)
 {
 	kfree(container_of(head, struct tp_probes, rcu));
 }
+#endif
 
 static inline void release_probes(struct tracepoint *tp, struct tracepoint_func *old)
 {
@@ -112,6 +138,13 @@ static inline void release_probes(struct tracepoint *tp, struct tracepoint_func
 		struct tp_probes *tp_probes = container_of(old,
 			struct tp_probes, probes[0]);
 
+		/*
+		 * Tracepoint probes are protected by either RCU or
+		 * Tasks Trace RCU and also by SRCU.  By calling the SRCU
+		 * callback in the [Tasks Trace] RCU callback we cover
+		 * both cases. So let us chain the SRCU and [Tasks Trace]
+		 * RCU callbacks to wait for both grace periods.
+		 */
 		if (tracepoint_is_faultable(tp))
 			call_rcu_tasks_trace(&tp_probes->rcu, rcu_free_old_probes);
 		else
-- 
2.51.0


^ permalink raw reply related

* Re: [PATCH v3 4/4] LoongArch: ftrace: Adjust register stack restore order in direct call trampolines
From: Steven Rostedt @ 2025-12-16 17:11 UTC (permalink / raw)
  To: Chenghao Duan
  Cc: yangtiezhu, mhiramat, mark.rutland, hengqi.chen, chenhuacai,
	kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
	youling.tang, jianghaoran, vincent.mc.li, linux-trace-kernel,
	Youling Tang
In-Reply-To: <20251216094753.1317231-5-duanchenghao@kylinos.cn>

On Tue, 16 Dec 2025 17:47:53 +0800
Chenghao Duan <duanchenghao@kylinos.cn> wrote:

> Ensure that in the ftrace direct call logic, the CPU register state
> (with ra = parent return address) is restored to the correct state
> after the execution of the custom trampoline function and before
> returning to the traced function. Additionally, guarantee the
> correctness of the jump logic for jr t0 (traced function address).
> 
> Reported-by: Youling Tang <tangyouling@kylinos.cn>
> Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
> ---
>  samples/ftrace/ftrace-direct-modify.c       | 8 ++++----
>  samples/ftrace/ftrace-direct-multi-modify.c | 8 ++++----
>  samples/ftrace/ftrace-direct-multi.c        | 4 ++--
>  samples/ftrace/ftrace-direct-too.c          | 4 ++--
>  samples/ftrace/ftrace-direct.c              | 4 ++--
>  5 files changed, 14 insertions(+), 14 deletions(-)

This is all LoongArch specific, but in case you need this to go through
your tree:

Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org>

-- Steve

^ permalink raw reply

* [PATCH] tracing: Guard __DECLARE_TRACE() use of __DO_TRACE_CALL() with SRCU-fast
From: Steven Rostedt @ 2025-12-16 17:08 UTC (permalink / raw)
  To: LKML, Linux Trace Kernel
  Cc: Masami Hiramatsu, Mathieu Desnoyers, Paul E. McKenney,
	Sebastian Andrzej Siewior, bpf

From: "Paul E. McKenney" <paulmck@kernel.org>

The current use of guard(preempt_notrace)() within __DECLARE_TRACE()
to protect invocation of __DO_TRACE_CALL() means that BPF programs
attached to tracepoints are non-preemptible.  This is unhelpful in
real-time systems, whose users apparently wish to use BPF while also
achieving low latencies.  (Who knew?)

One option would be to use preemptible RCU, but this introduces
many opportunities for infinite recursion, which many consider to
be counterproductive, especially given the relatively small stacks
provided by the Linux kernel.  These opportunities could be shut down
by sufficiently energetic duplication of code, but this sort of thing
is considered impolite in some circles.

Therefore, use the shiny new SRCU-fast API, which provides somewhat faster
readers than those of preemptible RCU, at least on Paul E. McKenney's
laptop, where task_struct access is more expensive than access to per-CPU
variables.  And SRCU-fast provides way faster readers than does SRCU,
courtesy of being able to avoid the read-side use of smp_mb().  Also,
it is quite straightforward to create srcu_read_{,un}lock_fast_notrace()
functions.

While in the area, SRCU now supports early boot call_srcu().  Therefore,
remove the checks that used to avoid such use from rcu_free_old_probes()
before this commit was applied:

e53244e2c893 ("tracepoint: Remove SRCU protection")

The current commit can be thought of as an approximate revert of that
commit, with some compensating additions of preemption disabling.
This preemption disabling uses guard(preempt_notrace)().

However, Yonghong Song points out that BPF assumes that non-sleepable
BPF programs will remain on the same CPU, which means that migration
must be disabled whenever preemption remains enabled.  In addition,
non-RT kernels have performance expectations that would be violated by
allowing the BPF programs to be preempted.

Therefore, continue to disable preemption in non-RT kernels, and protect
the BPF program with both SRCU and migration disabling for RT kernels,
and even then only if preemption is not already disabled.

Link: https://lore.kernel.org/all/20250613152218.1924093-1-bigeasy@linutronix.de/
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: <bpf@vger.kernel.org>
Signed-off-by: Steve Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
Changes since v3: https://patch.msgid.link/e2fe3162-4b7b-44d6-91ff-f439b3dce706@paulmck-laptop

- Added a trace_event_buffer_reserve_syscall() interface for system call
  events to use. This will not need to mess with the migrate disable
  counter. It just expects preemption to be disabled.

 include/linux/trace_events.h  | 24 ++++++++++++++++++++++++
 include/linux/tracepoint.h    | 25 ++++++++++++++++++++++---
 include/trace/perf.h          |  4 ++--
 include/trace/trace_events.h  | 21 +++++++++++++++++++--
 kernel/trace/trace_events.c   | 30 ++++++++++++++++++++----------
 kernel/trace/trace_syscalls.c |  4 ++--
 kernel/tracepoint.c           | 33 +++++++++++++++++++++++++++++++++
 7 files changed, 122 insertions(+), 19 deletions(-)

diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 3690221ba3d8..a2704c35eda8 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -222,6 +222,26 @@ static inline unsigned int tracing_gen_ctx_dec(void)
 	return trace_ctx;
 }
 
+/*
+ * When PREEMPT_RT is enabled, trace events are called with disabled
+ * migration. The trace events need to know if the tracepoint disabled
+ * migration or not so that what is recorded to the ring buffer shows
+ * the state of when the trace event triggered, and not the state caused
+ * by the trace event.
+ */
+#ifdef CONFIG_PREEMPT_RT
+static inline unsigned int tracing_gen_ctx_dec_cond(void)
+{
+	unsigned int trace_ctx;
+
+	trace_ctx = tracing_gen_ctx_dec();
+	/* The migration counter starts at bit 4 */
+	return trace_ctx - (1 << 4);
+}
+#else
+# define tracing_gen_ctx_dec_cond() tracing_gen_ctx_dec()
+#endif
+
 struct trace_event_file;
 
 struct ring_buffer_event *
@@ -313,6 +333,10 @@ void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
 				  struct trace_event_file *trace_file,
 				  unsigned long len);
 
+void *trace_event_buffer_reserve_syscall(struct trace_event_buffer *fbuffer,
+					 struct trace_event_file *trace_file,
+					 unsigned long len);
+
 void trace_event_buffer_commit(struct trace_event_buffer *fbuffer);
 
 enum {
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 8a56f3278b1b..0563c7d9fcb2 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -100,6 +100,25 @@ void for_each_tracepoint_in_module(struct module *mod,
 }
 #endif /* CONFIG_MODULES */
 
+/*
+ * BPF programs can attach to the tracepoint callbacks. But if the
+ * callbacks are called with preemption disabled, the BPF programs
+ * can cause quite a bit of latency. When PREEMPT_RT is enabled,
+ * instead of disabling preemption, use srcu_fast_notrace() for
+ * synchronization. As BPF programs that are attached to tracepoints
+ * expect to stay on the same CPU, also disable migration.
+ */
+#ifdef CONFIG_PREEMPT_RT
+extern struct srcu_struct tracepoint_srcu;
+# define tracepoint_sync() synchronize_srcu(&tracepoint_srcu);
+# define tracepoint_guard()				\
+	guard(srcu_fast_notrace)(&tracepoint_srcu);	\
+	guard(migrate)()
+#else
+# define tracepoint_sync() synchronize_rcu();
+# define tracepoint_guard() guard(preempt_notrace)()
+#endif
+
 /*
  * tracepoint_synchronize_unregister must be called between the last tracepoint
  * probe unregistration and the end of module exit to make sure there is no
@@ -115,7 +134,7 @@ void for_each_tracepoint_in_module(struct module *mod,
 static inline void tracepoint_synchronize_unregister(void)
 {
 	synchronize_rcu_tasks_trace();
-	synchronize_rcu();
+	tracepoint_sync();
 }
 static inline bool tracepoint_is_faultable(struct tracepoint *tp)
 {
@@ -275,13 +294,13 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
 		return static_branch_unlikely(&__tracepoint_##name.key);\
 	}
 
-#define __DECLARE_TRACE(name, proto, args, cond, data_proto)		\
+#define __DECLARE_TRACE(name, proto, args, cond, data_proto)			\
 	__DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto)) \
 	static inline void __do_trace_##name(proto)			\
 	{								\
 		TRACEPOINT_CHECK(name)					\
 		if (cond) {						\
-			guard(preempt_notrace)();			\
+			tracepoint_guard();				\
 			__DO_TRACE_CALL(name, TP_ARGS(args));		\
 		}							\
 	}								\
diff --git a/include/trace/perf.h b/include/trace/perf.h
index a1754b73a8f5..348ad1d9b556 100644
--- a/include/trace/perf.h
+++ b/include/trace/perf.h
@@ -71,6 +71,7 @@ perf_trace_##call(void *__data, proto)					\
 	u64 __count __attribute__((unused));				\
 	struct task_struct *__task __attribute__((unused));		\
 									\
+	guard(preempt_notrace)();					\
 	do_perf_trace_##call(__data, args);				\
 }
 
@@ -85,9 +86,8 @@ perf_trace_##call(void *__data, proto)					\
 	struct task_struct *__task __attribute__((unused));		\
 									\
 	might_fault();							\
-	preempt_disable_notrace();					\
+	guard(preempt_notrace)();					\
 	do_perf_trace_##call(__data, args);				\
-	preempt_enable_notrace();					\
 }
 
 /*
diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h
index 4f22136fd465..6fb58387e9f1 100644
--- a/include/trace/trace_events.h
+++ b/include/trace/trace_events.h
@@ -429,6 +429,22 @@ do_trace_event_raw_event_##call(void *__data, proto)			\
 	trace_event_buffer_commit(&fbuffer);				\
 }
 
+/*
+ * When PREEMPT_RT is enabled, the tracepoint does not disable preemption
+ * but instead disables migration. The callbacks for the trace events
+ * need to have a consistent state so that it can reflect the proper
+ * preempt_disabled counter.
+ */
+#ifdef CONFIG_PREEMPT_RT
+/* disable preemption for RT so that the counters still match */
+# define trace_event_guard() guard(preempt_notrace)()
+/* Have syscalls up the migrate disable counter to emulate non-syscalls */
+# define trace_syscall_event_guard() guard(migrate)()
+#else
+# define trace_event_guard()
+# define trace_syscall_event_guard()
+#endif
+
 #undef DECLARE_EVENT_CLASS
 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
 __DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), PARAMS(tstruct), \
@@ -436,6 +452,7 @@ __DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), PARAMS(tstruct), \
 static notrace void							\
 trace_event_raw_event_##call(void *__data, proto)			\
 {									\
+	trace_event_guard();						\
 	do_trace_event_raw_event_##call(__data, args);			\
 }
 
@@ -447,9 +464,9 @@ static notrace void							\
 trace_event_raw_event_##call(void *__data, proto)			\
 {									\
 	might_fault();							\
-	preempt_disable_notrace();					\
+	trace_syscall_event_guard();					\
+	guard(preempt_notrace)();					\
 	do_trace_event_raw_event_##call(__data, args);			\
-	preempt_enable_notrace();					\
 }
 
 /*
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index b16a5a158040..a5a93d243047 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -649,9 +649,9 @@ bool trace_event_ignore_this_pid(struct trace_event_file *trace_file)
 }
 EXPORT_SYMBOL_GPL(trace_event_ignore_this_pid);
 
-void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
-				 struct trace_event_file *trace_file,
-				 unsigned long len)
+static __always_inline void *buffer_reserve(struct trace_event_buffer *fbuffer,
+					    struct trace_event_file *trace_file,
+					    unsigned long len)
 {
 	struct trace_event_call *event_call = trace_file->event_call;
 
@@ -659,13 +659,6 @@ void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
 	    trace_event_ignore_this_pid(trace_file))
 		return NULL;
 
-	/*
-	 * If CONFIG_PREEMPTION is enabled, then the tracepoint itself disables
-	 * preemption (adding one to the preempt_count). Since we are
-	 * interested in the preempt_count at the time the tracepoint was
-	 * hit, we need to subtract one to offset the increment.
-	 */
-	fbuffer->trace_ctx = tracing_gen_ctx_dec();
 	fbuffer->trace_file = trace_file;
 
 	fbuffer->event =
@@ -679,8 +672,25 @@ void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
 	fbuffer->entry = ring_buffer_event_data(fbuffer->event);
 	return fbuffer->entry;
 }
+
+void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
+				 struct trace_event_file *trace_file,
+				 unsigned long len)
+{
+	fbuffer->trace_ctx = tracing_gen_ctx_dec_cond();
+	return buffer_reserve(fbuffer, trace_file, len);
+}
 EXPORT_SYMBOL_GPL(trace_event_buffer_reserve);
 
+void *trace_event_buffer_reserve_syscall(struct trace_event_buffer *fbuffer,
+					 struct trace_event_file *trace_file,
+					 unsigned long len)
+{
+	fbuffer->trace_ctx = tracing_gen_ctx_dec();
+	return buffer_reserve(fbuffer, trace_file, len);
+}
+
+
 int trace_event_reg(struct trace_event_call *call,
 		    enum trace_reg type, void *data)
 {
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index e96d0063cbcf..f330fd22ea78 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -909,7 +909,7 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
 
 	size += sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args;
 
-	entry = trace_event_buffer_reserve(&fbuffer, trace_file, size);
+	entry = trace_event_buffer_reserve_syscall(&fbuffer, trace_file, size);
 	if (!entry)
 		return;
 
@@ -955,7 +955,7 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
 	if (!sys_data)
 		return;
 
-	entry = trace_event_buffer_reserve(&fbuffer, trace_file, sizeof(*entry));
+	entry = trace_event_buffer_reserve_syscall(&fbuffer, trace_file, sizeof(*entry));
 	if (!entry)
 		return;
 
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index 62719d2941c9..6a6bcf86bfbe 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -25,6 +25,12 @@ enum tp_func_state {
 extern tracepoint_ptr_t __start___tracepoints_ptrs[];
 extern tracepoint_ptr_t __stop___tracepoints_ptrs[];
 
+/* In PREEMPT_RT, SRCU is used to protect the tracepoint callbacks */
+#ifdef CONFIG_PREEMPT_RT
+DEFINE_SRCU_FAST(tracepoint_srcu);
+EXPORT_SYMBOL_GPL(tracepoint_srcu);
+#endif
+
 enum tp_transition_sync {
 	TP_TRANSITION_SYNC_1_0_1,
 	TP_TRANSITION_SYNC_N_2_1,
@@ -34,6 +40,7 @@ enum tp_transition_sync {
 
 struct tp_transition_snapshot {
 	unsigned long rcu;
+	unsigned long srcu_gp;
 	bool ongoing;
 };
 
@@ -46,6 +53,9 @@ static void tp_rcu_get_state(enum tp_transition_sync sync)
 
 	/* Keep the latest get_state snapshot. */
 	snapshot->rcu = get_state_synchronize_rcu();
+#ifdef CONFIG_PREEMPT_RT
+	snapshot->srcu_gp = start_poll_synchronize_srcu(&tracepoint_srcu);
+#endif
 	snapshot->ongoing = true;
 }
 
@@ -56,6 +66,10 @@ static void tp_rcu_cond_sync(enum tp_transition_sync sync)
 	if (!snapshot->ongoing)
 		return;
 	cond_synchronize_rcu(snapshot->rcu);
+#ifdef CONFIG_PREEMPT_RT
+	if (!poll_state_synchronize_srcu(&tracepoint_srcu, snapshot->srcu_gp))
+		synchronize_srcu(&tracepoint_srcu);
+#endif
 	snapshot->ongoing = false;
 }
 
@@ -101,10 +115,22 @@ static inline void *allocate_probes(int count)
 	return p == NULL ? NULL : p->probes;
 }
 
+#ifdef CONFIG_PREEMPT_RT
+static void srcu_free_old_probes(struct rcu_head *head)
+{
+	kfree(container_of(head, struct tp_probes, rcu));
+}
+
+static void rcu_free_old_probes(struct rcu_head *head)
+{
+	call_srcu(&tracepoint_srcu, head, srcu_free_old_probes);
+}
+#else
 static void rcu_free_old_probes(struct rcu_head *head)
 {
 	kfree(container_of(head, struct tp_probes, rcu));
 }
+#endif
 
 static inline void release_probes(struct tracepoint *tp, struct tracepoint_func *old)
 {
@@ -112,6 +138,13 @@ static inline void release_probes(struct tracepoint *tp, struct tracepoint_func
 		struct tp_probes *tp_probes = container_of(old,
 			struct tp_probes, probes[0]);
 
+		/*
+		 * Tracepoint probes are protected by either RCU or
+		 * Tasks Trace RCU and also by SRCU.  By calling the SRCU
+		 * callback in the [Tasks Trace] RCU callback we cover
+		 * both cases. So let us chain the SRCU and [Tasks Trace]
+		 * RCU callbacks to wait for both grace periods.
+		 */
 		if (tracepoint_is_faultable(tp))
 			call_rcu_tasks_trace(&tp_probes->rcu, rcu_free_old_probes);
 		else
-- 
2.51.0


^ permalink raw reply related

* Re: [PATCH] ftrace: fix address for jmp mode in t_show
From: Steven Rostedt @ 2025-12-16 16:28 UTC (permalink / raw)
  To: Menglong Dong
  Cc: mhiramat, mark.rutland, mathieu.desnoyers, ast, jiang.biao,
	linux-kernel, linux-trace-kernel
In-Reply-To: <20251216034533.111090-1-dongml2@chinatelecom.cn>

On Tue, 16 Dec 2025 11:45:33 +0800
Menglong Dong <menglong8.dong@gmail.com> wrote:

> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index bbb37c0f8c6c..d4c41fb76a25 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -4492,8 +4492,12 @@ static int t_show(struct seq_file *m, void *v)
>  			unsigned long direct;
>  
>  			direct = ftrace_find_rec_direct(rec->ip);
> -			if (direct)
> -				seq_printf(m, "\n\tdirect-->%pS", (void *)direct);
> +			if (direct) {
> +				seq_printf(m, ftrace_is_jmp(direct) ?
> +					      "\n\tdirect(jmp)-->%pS" :
> +					      "\n\tdirect-->%pS",
> +					   (void *)ftrace_jmp_get(direct));

A little cleaner way to do the above:

				seq_printf(m, "\n\tdirect%s-->%pS",
					   ftrace_is_jmp(direct) ? "(jmp)" : "",
					   (void *)ftrace_jmp_get(direct));


-- Steve

> +			}
>  		}
>  	}

^ permalink raw reply

* Re: [PATCH 2/3] mm/khugepaged: use enum scan_result for result variables
From: Garg, Shivank @ 2025-12-16 16:20 UTC (permalink / raw)
  To: Zi Yan
  Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Baolin Wang,
	Liam R . Howlett, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
	Lance Yang, linux-mm, linux-kernel, linux-trace-kernel
In-Reply-To: <D9E6B402-528B-46F2-B4B0-9CD9549A449F@nvidia.com>



On 12/16/2025 9:08 PM, Zi Yan wrote:
> On 16 Dec 2025, at 6:11, Shivank Garg wrote:
> 

>> @@ -547,7 +547,8 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
> 
> The return type could be changed too.
> 
>>  	struct folio *folio = NULL;
>>  	unsigned long addr = start_addr;
>>  	pte_t *_pte;
>> -	int none_or_zero = 0, shared = 0, result = SCAN_FAIL, referenced = 0;
>> +	int none_or_zero = 0, shared = 0, referenced = 0;
>> +	enum scan_result result = SCAN_FAIL;
>>
>>  	for (_pte = pte; _pte < pte + HPAGE_PMD_NR;
>>  	     _pte++, addr += PAGE_SIZE) {
>> @@ -786,7 +787,7 @@ static int __collapse_huge_page_copy(pte_t *pte, struct folio *folio,
> 
> Ditto.
> 
>>  		struct list_head *compound_pagelist)
>>  {

>> -- 
> 
> In addition, the return types of find_pmd_or_thp_or_none(),
> hugepage_vma_revalidate(), alloc_charge_folio(), and check_pmd_state() need to be changed to enum scan_result too.
> 
Hi Zi,

Thanks for the review and suggestions.
I'll update the return types and send V2.

Thanks,
Shivank

^ permalink raw reply

* Re: [PATCH v2 8/8] tools/rtla: Consolidate -H/--house-keeping option parsing
From: Wander Lairson Costa @ 2025-12-16 16:18 UTC (permalink / raw)
  To: Costa Shulyupin
  Cc: Steven Rostedt, Tomas Glozar, Crystal Wood, John Kacur,
	Ivan Pravdin, linux-trace-kernel, linux-kernel
In-Reply-To: <20251209100047.2692515-8-costa.shul@redhat.com>

On Tue, Dec 09, 2025 at 12:00:47PM +0200, Costa Shulyupin wrote:
> Each rtla tool duplicates parsing of -H/--house-keeping.
> 
> Migrate the option parsing from individual tools to the
> common_parse_options().
> 
> Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
> ---
>  tools/tracing/rtla/src/common.c        | 8 +++++++-
>  tools/tracing/rtla/src/osnoise_hist.c  | 9 +--------
>  tools/tracing/rtla/src/osnoise_top.c   | 9 +--------
>  tools/tracing/rtla/src/timerlat_hist.c | 9 +--------
>  tools/tracing/rtla/src/timerlat_top.c  | 9 +--------
>  5 files changed, 11 insertions(+), 33 deletions(-)
> 
> diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c
> index e042b2d9dbf5..8e90bb4a76f9 100644
> --- a/tools/tracing/rtla/src/common.c
> +++ b/tools/tracing/rtla/src/common.c
> @@ -62,12 +62,13 @@ int common_parse_options(int argc, char **argv, struct common_params *common)
>  		{"debug",               no_argument,            0, 'D'},
>  		{"duration",            required_argument,      0, 'd'},
>  		{"event",               required_argument,      0, 'e'},
> +		{"house-keeping",       required_argument,      0, 'H'},
>  		{"priority",            required_argument,      0, 'P'},
>  		{0, 0, 0, 0}
>  	};
>  
>  	opterr = 0;
> -	c = getopt_long(argc, argv, "c:C::Dd:e:P:", long_options, NULL);
> +	c = getopt_long(argc, argv, "c:C::Dd:e:H:P:", long_options, NULL);
>  	opterr = 1;
>  
>  	switch (c) {
> @@ -97,6 +98,11 @@ int common_parse_options(int argc, char **argv, struct common_params *common)
>  			tevent->next = common->events;
>  		common->events = tevent;
>  		break;
> +	case 'H':
> +		common->hk_cpus = 1;
> +		if (parse_cpu_set(optarg, &common->hk_cpu_set))
> +			fatal("Error parsing house keeping CPUs");
> +		break;
>  	case 'P':
>  		if (parse_prio(optarg, &common->sched_param) == -1)
>  			fatal("Invalid -P priority");
> diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
> index 6ed5f5594960..1ebd3b48b2d3 100644
> --- a/tools/tracing/rtla/src/osnoise_hist.c
> +++ b/tools/tracing/rtla/src/osnoise_hist.c
> @@ -490,7 +490,6 @@ static struct common_params
>  			{"auto",		required_argument,	0, 'a'},
>  			{"bucket-size",		required_argument,	0, 'b'},
>  			{"entries",		required_argument,	0, 'E'},
> -			{"house-keeping",	required_argument,		0, 'H'},
>  			{"help",		no_argument,		0, 'h'},
>  			{"period",		required_argument,	0, 'p'},
>  			{"runtime",		required_argument,	0, 'r'},
> @@ -514,7 +513,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:b:E:hH:p:r:s:S:t::T:01234:5:6:7:",
> +		c = getopt_long(argc, argv, "a:b:E:hp:r:s:S:t::T:01234:5:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -550,12 +549,6 @@ static struct common_params
>  		case '?':
>  			osnoise_hist_usage();
>  			break;
> -		case 'H':
> -			params->common.hk_cpus = 1;
> -			retval = parse_cpu_set(optarg, &params->common.hk_cpu_set);
> -			if (retval)
> -				fatal("Error parsing house keeping CPUs");
> -			break;
>  		case 'p':
>  			params->period = get_llong_from_str(optarg);
>  			if (params->period > 10000000)
> diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
> index d2dfad960440..02e5e6e18e8d 100644
> --- a/tools/tracing/rtla/src/osnoise_top.c
> +++ b/tools/tracing/rtla/src/osnoise_top.c
> @@ -345,7 +345,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  	while (1) {
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
> -			{"house-keeping",	required_argument,	0, 'H'},
>  			{"help",		no_argument,		0, 'h'},
>  			{"period",		required_argument,	0, 'p'},
>  			{"quiet",		no_argument,		0, 'q'},
> @@ -366,7 +365,7 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:hH:p:qr:s:S:t::T:0:1:2:3:",
> +		c = getopt_long(argc, argv, "a:hp:qr:s:S:t::T:0:1:2:3:",
>  				 long_options, NULL);
>  
>  		/* Detect the end of the options. */
> @@ -390,12 +389,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  		case '?':
>  			osnoise_top_usage(params);
>  			break;
> -		case 'H':
> -			params->common.hk_cpus = 1;
> -			retval = parse_cpu_set(optarg, &params->common.hk_cpu_set);
> -			if (retval)
> -				fatal("Error parsing house keeping CPUs");
> -			break;
>  		case 'p':
>  			params->period = get_llong_from_str(optarg);
>  			if (params->period > 10000000)
> diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
> index e7ba083b5eb4..d1a6cf0c2e0d 100644
> --- a/tools/tracing/rtla/src/timerlat_hist.c
> +++ b/tools/tracing/rtla/src/timerlat_hist.c
> @@ -797,7 +797,6 @@ static struct common_params
>  			{"auto",		required_argument,	0, 'a'},
>  			{"bucket-size",		required_argument,	0, 'b'},
>  			{"entries",		required_argument,	0, 'E'},
> -			{"house-keeping",	required_argument,	0, 'H'},
>  			{"help",		no_argument,		0, 'h'},
>  			{"irq",			required_argument,	0, 'i'},
>  			{"nano",		no_argument,		0, 'n'},
> @@ -830,7 +829,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:b:E:hH:i:knp:s:t::T:uU0123456:7:8:9\1\2:\3:",
> +		c = getopt_long(argc, argv, "a:b:E:hi:knp:s:t::T:uU0123456:7:8:9\1\2:\3:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -869,12 +868,6 @@ static struct common_params
>  		case '?':
>  			timerlat_hist_usage();
>  			break;
> -		case 'H':
> -			params->common.hk_cpus = 1;
> -			retval = parse_cpu_set(optarg, &params->common.hk_cpu_set);
> -			if (retval)
> -				fatal("Error parsing house keeping CPUs");
> -			break;
>  		case 'i':
>  			params->common.stop_us = get_llong_from_str(optarg);
>  			break;
> diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
> index 8250bea4b2fd..12e3d8c6f850 100644
> --- a/tools/tracing/rtla/src/timerlat_top.c
> +++ b/tools/tracing/rtla/src/timerlat_top.c
> @@ -566,7 +566,6 @@ static struct common_params
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
>  			{"help",		no_argument,		0, 'h'},
> -			{"house-keeping",	required_argument,	0, 'H'},
>  			{"irq",			required_argument,	0, 'i'},
>  			{"nano",		no_argument,		0, 'n'},
>  			{"period",		required_argument,	0, 'p'},
> @@ -594,7 +593,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:hH:i:knp:qs:t::T:uU0:1:2:345:6:7:",
> +		c = getopt_long(argc, argv, "a:hi:knp:qs:t::T:uU0:1:2:345:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -635,12 +634,6 @@ static struct common_params
>  		case '?':
>  			timerlat_top_usage();
>  			break;
> -		case 'H':
> -			params->common.hk_cpus = 1;
> -			retval = parse_cpu_set(optarg, &params->common.hk_cpu_set);
> -			if (retval)
> -				fatal("Error parsing house keeping CPUs");
> -			break;
>  		case 'i':
>  			params->common.stop_us = get_llong_from_str(optarg);
>  			break;
> -- 
> 2.52.0
> 

Reviewed-by: Wander Lairson Costa <wander@redhat.com>


^ permalink raw reply

* Re: [PATCH v2 7/8] tools/rtla: Consolidate -P/--priority option parsing
From: Wander Lairson Costa @ 2025-12-16 16:18 UTC (permalink / raw)
  To: Costa Shulyupin
  Cc: Steven Rostedt, Tomas Glozar, Crystal Wood, John Kacur,
	Ivan Pravdin, linux-trace-kernel, linux-kernel
In-Reply-To: <20251209100047.2692515-7-costa.shul@redhat.com>

On Tue, Dec 09, 2025 at 12:00:46PM +0200, Costa Shulyupin wrote:
> Each rtla tool duplicates parsing of -P/--priority.
> 
> Migrate the option parsing from individual tools to the
> common_parse_options().
> 
> Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
> ---
>  tools/tracing/rtla/src/common.c        | 8 +++++++-
>  tools/tracing/rtla/src/osnoise_hist.c  | 9 +--------
>  tools/tracing/rtla/src/osnoise_top.c   | 9 +--------
>  tools/tracing/rtla/src/timerlat_hist.c | 9 +--------
>  tools/tracing/rtla/src/timerlat_top.c  | 9 +--------
>  5 files changed, 11 insertions(+), 33 deletions(-)
> 
> diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c
> index 684ff49f0a4c..e042b2d9dbf5 100644
> --- a/tools/tracing/rtla/src/common.c
> +++ b/tools/tracing/rtla/src/common.c
> @@ -62,11 +62,12 @@ int common_parse_options(int argc, char **argv, struct common_params *common)
>  		{"debug",               no_argument,            0, 'D'},
>  		{"duration",            required_argument,      0, 'd'},
>  		{"event",               required_argument,      0, 'e'},
> +		{"priority",            required_argument,      0, 'P'},
>  		{0, 0, 0, 0}
>  	};
>  
>  	opterr = 0;
> -	c = getopt_long(argc, argv, "c:C::Dd:e:", long_options, NULL);
> +	c = getopt_long(argc, argv, "c:C::Dd:e:P:", long_options, NULL);
>  	opterr = 1;
>  
>  	switch (c) {
> @@ -96,6 +97,11 @@ int common_parse_options(int argc, char **argv, struct common_params *common)
>  			tevent->next = common->events;
>  		common->events = tevent;
>  		break;
> +	case 'P':
> +		if (parse_prio(optarg, &common->sched_param) == -1)
> +			fatal("Invalid -P priority");
> +		common->set_sched = 1;
> +		break;
>  	default:
>  		optind = saved_state;
>  		return 0;
> diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
> index c4013f50e803..6ed5f5594960 100644
> --- a/tools/tracing/rtla/src/osnoise_hist.c
> +++ b/tools/tracing/rtla/src/osnoise_hist.c
> @@ -493,7 +493,6 @@ static struct common_params
>  			{"house-keeping",	required_argument,		0, 'H'},
>  			{"help",		no_argument,		0, 'h'},
>  			{"period",		required_argument,	0, 'p'},
> -			{"priority",		required_argument,	0, 'P'},
>  			{"runtime",		required_argument,	0, 'r'},
>  			{"stop",		required_argument,	0, 's'},
>  			{"stop-total",		required_argument,	0, 'S'},
> @@ -515,7 +514,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:b:E:hH:p:P:r:s:S:t::T:01234:5:6:7:",
> +		c = getopt_long(argc, argv, "a:b:E:hH:p:r:s:S:t::T:01234:5:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -562,12 +561,6 @@ static struct common_params
>  			if (params->period > 10000000)
>  				fatal("Period longer than 10 s");
>  			break;
> -		case 'P':
> -			retval = parse_prio(optarg, &params->common.sched_param);
> -			if (retval == -1)
> -				fatal("Invalid -P priority");
> -			params->common.set_sched = 1;
> -			break;
>  		case 'r':
>  			params->runtime = get_llong_from_str(optarg);
>  			if (params->runtime < 100)
> diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
> index 846d25ee4885..d2dfad960440 100644
> --- a/tools/tracing/rtla/src/osnoise_top.c
> +++ b/tools/tracing/rtla/src/osnoise_top.c
> @@ -348,7 +348,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  			{"house-keeping",	required_argument,	0, 'H'},
>  			{"help",		no_argument,		0, 'h'},
>  			{"period",		required_argument,	0, 'p'},
> -			{"priority",		required_argument,	0, 'P'},
>  			{"quiet",		no_argument,		0, 'q'},
>  			{"runtime",		required_argument,	0, 'r'},
>  			{"stop",		required_argument,	0, 's'},
> @@ -367,7 +366,7 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:hH:p:P:qr:s:S:t::T:0:1:2:3:",
> +		c = getopt_long(argc, argv, "a:hH:p:qr:s:S:t::T:0:1:2:3:",
>  				 long_options, NULL);
>  
>  		/* Detect the end of the options. */
> @@ -402,12 +401,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  			if (params->period > 10000000)
>  				fatal("Period longer than 10 s");
>  			break;
> -		case 'P':
> -			retval = parse_prio(optarg, &params->common.sched_param);
> -			if (retval == -1)
> -				fatal("Invalid -P priority");
> -			params->common.set_sched = 1;
> -			break;
>  		case 'q':
>  			params->common.quiet = 1;
>  			break;
> diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
> index 4744f84a452e..e7ba083b5eb4 100644
> --- a/tools/tracing/rtla/src/timerlat_hist.c
> +++ b/tools/tracing/rtla/src/timerlat_hist.c
> @@ -802,7 +802,6 @@ static struct common_params
>  			{"irq",			required_argument,	0, 'i'},
>  			{"nano",		no_argument,		0, 'n'},
>  			{"period",		required_argument,	0, 'p'},
> -			{"priority",		required_argument,	0, 'P'},
>  			{"stack",		required_argument,	0, 's'},
>  			{"thread",		required_argument,	0, 'T'},
>  			{"trace",		optional_argument,	0, 't'},
> @@ -831,7 +830,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:b:E:hH:i:knp:P:s:t::T:uU0123456:7:8:9\1\2:\3:",
> +		c = getopt_long(argc, argv, "a:b:E:hH:i:knp:s:t::T:uU0123456:7:8:9\1\2:\3:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -890,12 +889,6 @@ static struct common_params
>  			if (params->timerlat_period_us > 1000000)
>  				fatal("Period longer than 1 s");
>  			break;
> -		case 'P':
> -			retval = parse_prio(optarg, &params->common.sched_param);
> -			if (retval == -1)
> -				fatal("Invalid -P priority");
> -			params->common.set_sched = 1;
> -			break;
>  		case 's':
>  			params->print_stack = get_llong_from_str(optarg);
>  			break;
> diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
> index b77e5b6550a1..8250bea4b2fd 100644
> --- a/tools/tracing/rtla/src/timerlat_top.c
> +++ b/tools/tracing/rtla/src/timerlat_top.c
> @@ -570,7 +570,6 @@ static struct common_params
>  			{"irq",			required_argument,	0, 'i'},
>  			{"nano",		no_argument,		0, 'n'},
>  			{"period",		required_argument,	0, 'p'},
> -			{"priority",		required_argument,	0, 'P'},
>  			{"quiet",		no_argument,		0, 'q'},
>  			{"stack",		required_argument,	0, 's'},
>  			{"thread",		required_argument,	0, 'T'},
> @@ -595,7 +594,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:hH:i:knp:P:qs:t::T:uU0:1:2:345:6:7:",
> +		c = getopt_long(argc, argv, "a:hH:i:knp:qs:t::T:uU0:1:2:345:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -656,12 +655,6 @@ static struct common_params
>  			if (params->timerlat_period_us > 1000000)
>  				fatal("Period longer than 1 s");
>  			break;
> -		case 'P':
> -			retval = parse_prio(optarg, &params->common.sched_param);
> -			if (retval == -1)
> -				fatal("Invalid -P priority");
> -			params->common.set_sched = 1;
> -			break;
>  		case 'q':
>  			params->common.quiet = 1;
>  			break;
> -- 
> 2.52.0
> 

Reviewed-by: Wander Lairson Costa <wander@redhat.com>


^ permalink raw reply

* Re: [PATCH v2 6/8] tools/rtla: Consolidate -e/--event option parsing
From: Wander Lairson Costa @ 2025-12-16 16:18 UTC (permalink / raw)
  To: Costa Shulyupin
  Cc: Steven Rostedt, Tomas Glozar, Crystal Wood, John Kacur,
	Ivan Pravdin, linux-trace-kernel, linux-kernel
In-Reply-To: <20251209100047.2692515-6-costa.shul@redhat.com>

On Tue, Dec 09, 2025 at 12:00:45PM +0200, Costa Shulyupin wrote:
> Each rtla tool duplicates parsing of -e/--event.
> 
> Migrate the option parsing from individual tools to the
> common_parse_options().
> 
> Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
> ---
>  tools/tracing/rtla/src/common.c        | 13 ++++++++++++-
>  tools/tracing/rtla/src/osnoise_hist.c  | 14 +-------------
>  tools/tracing/rtla/src/osnoise_top.c   | 14 +-------------
>  tools/tracing/rtla/src/timerlat_hist.c | 14 +-------------
>  tools/tracing/rtla/src/timerlat_top.c  | 13 +------------
>  5 files changed, 16 insertions(+), 52 deletions(-)
> 
> diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c
> index e6ff011d2cd2..684ff49f0a4c 100644
> --- a/tools/tracing/rtla/src/common.c
> +++ b/tools/tracing/rtla/src/common.c
> @@ -52,6 +52,7 @@ static void set_signals(struct common_params *params)
>   */
>  int common_parse_options(int argc, char **argv, struct common_params *common)
>  {
> +	struct trace_events *tevent;
>  	int saved_state = optind;
>  	int c;
>  
> @@ -60,11 +61,12 @@ int common_parse_options(int argc, char **argv, struct common_params *common)
>  		{"cgroup",              optional_argument,      0, 'C'},
>  		{"debug",               no_argument,            0, 'D'},
>  		{"duration",            required_argument,      0, 'd'},
> +		{"event",               required_argument,      0, 'e'},
>  		{0, 0, 0, 0}
>  	};
>  
>  	opterr = 0;
> -	c = getopt_long(argc, argv, "c:C::Dd:", long_options, NULL);
> +	c = getopt_long(argc, argv, "c:C::Dd:e:", long_options, NULL);
>  	opterr = 1;
>  
>  	switch (c) {
> @@ -85,6 +87,15 @@ int common_parse_options(int argc, char **argv, struct common_params *common)
>  		if (!common->duration)
>  			fatal("Invalid -d duration");
>  		break;
> +	case 'e':
> +		tevent = trace_event_alloc(optarg);
> +		if (!tevent)
> +			fatal("Error alloc trace event");
> +
> +		if (common->events)
> +			tevent->next = common->events;
> +		common->events = tevent;
> +		break;
>  	default:
>  		optind = saved_state;
>  		return 0;
> diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
> index 1b79bfefc214..c4013f50e803 100644
> --- a/tools/tracing/rtla/src/osnoise_hist.c
> +++ b/tools/tracing/rtla/src/osnoise_hist.c
> @@ -469,7 +469,6 @@ static struct common_params
>  *osnoise_hist_parse_args(int argc, char *argv[])
>  {
>  	struct osnoise_params *params;
> -	struct trace_events *tevent;
>  	int retval;
>  	int c;
>  	char *trace_output = NULL;
> @@ -499,7 +498,6 @@ static struct common_params
>  			{"stop",		required_argument,	0, 's'},
>  			{"stop-total",		required_argument,	0, 'S'},
>  			{"trace",		optional_argument,	0, 't'},
> -			{"event",		required_argument,	0, 'e'},
>  			{"threshold",		required_argument,	0, 'T'},
>  			{"no-header",		no_argument,		0, '0'},
>  			{"no-summary",		no_argument,		0, '1'},
> @@ -517,7 +515,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:b:e:E:hH:p:P:r:s:S:t::T:01234:5:6:7:",
> +		c = getopt_long(argc, argv, "a:b:E:hH:p:P:r:s:S:t::T:01234:5:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -543,16 +541,6 @@ static struct common_params
>  			    params->common.hist.bucket_size >= 1000000)
>  				fatal("Bucket size needs to be > 0 and <= 1000000");
>  			break;
> -		case 'e':
> -			tevent = trace_event_alloc(optarg);
> -			if (!tevent)
> -				fatal("Error alloc trace event");
> -
> -			if (params->common.events)
> -				tevent->next = params->common.events;
> -
> -			params->common.events = tevent;
> -			break;
>  		case 'E':
>  			params->common.hist.entries = get_llong_from_str(optarg);
>  			if (params->common.hist.entries < 10 ||
> diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
> index 619c5bcf8f35..846d25ee4885 100644
> --- a/tools/tracing/rtla/src/osnoise_top.c
> +++ b/tools/tracing/rtla/src/osnoise_top.c
> @@ -322,7 +322,6 @@ static void osnoise_top_usage(struct osnoise_params *params)
>  struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  {
>  	struct osnoise_params *params;
> -	struct trace_events *tevent;
>  	int retval;
>  	int c;
>  	char *trace_output = NULL;
> @@ -346,7 +345,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  	while (1) {
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
> -			{"event",		required_argument,	0, 'e'},
>  			{"house-keeping",	required_argument,	0, 'H'},
>  			{"help",		no_argument,		0, 'h'},
>  			{"period",		required_argument,	0, 'p'},
> @@ -369,7 +367,7 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:e:hH:p:P:qr:s:S:t::T:0:1:2:3:",
> +		c = getopt_long(argc, argv, "a:hH:p:P:qr:s:S:t::T:0:1:2:3:",
>  				 long_options, NULL);
>  
>  		/* Detect the end of the options. */
> @@ -388,16 +386,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  			if (!trace_output)
>  				trace_output = "osnoise_trace.txt";
>  
> -			break;
> -		case 'e':
> -			tevent = trace_event_alloc(optarg);
> -			if (!tevent)
> -				fatal("Error alloc trace event");
> -
> -			if (params->common.events)
> -				tevent->next = params->common.events;
> -			params->common.events = tevent;
> -
>  			break;
>  		case 'h':
>  		case '?':
> diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
> index 0a7e5dcce121..4744f84a452e 100644
> --- a/tools/tracing/rtla/src/timerlat_hist.c
> +++ b/tools/tracing/rtla/src/timerlat_hist.c
> @@ -766,7 +766,6 @@ static struct common_params
>  *timerlat_hist_parse_args(int argc, char *argv[])
>  {
>  	struct timerlat_params *params;
> -	struct trace_events *tevent;
>  	int auto_thresh;
>  	int retval;
>  	int c;
> @@ -810,7 +809,6 @@ static struct common_params
>  			{"user-threads",	no_argument,		0, 'u'},
>  			{"kernel-threads",	no_argument,		0, 'k'},
>  			{"user-load",		no_argument,		0, 'U'},
> -			{"event",		required_argument,	0, 'e'},
>  			{"no-irq",		no_argument,		0, '0'},
>  			{"no-thread",		no_argument,		0, '1'},
>  			{"no-header",		no_argument,		0, '2'},
> @@ -833,7 +831,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:b:e:E:hH:i:knp:P:s:t::T:uU0123456:7:8:9\1\2:\3:",
> +		c = getopt_long(argc, argv, "a:b:E:hH:i:knp:P:s:t::T:uU0123456:7:8:9\1\2:\3:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -862,16 +860,6 @@ static struct common_params
>  			    params->common.hist.bucket_size >= 1000000)
>  				fatal("Bucket size needs to be > 0 and <= 1000000");
>  			break;
> -		case 'e':
> -			tevent = trace_event_alloc(optarg);
> -			if (!tevent)
> -				fatal("Error alloc trace event");
> -
> -			if (params->common.events)
> -				tevent->next = params->common.events;
> -
> -			params->common.events = tevent;
> -			break;
>  		case 'E':
>  			params->common.hist.entries = get_llong_from_str(optarg);
>  			if (params->common.hist.entries < 10 ||
> diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
> index 4340fbf3f879..b77e5b6550a1 100644
> --- a/tools/tracing/rtla/src/timerlat_top.c
> +++ b/tools/tracing/rtla/src/timerlat_top.c
> @@ -538,7 +538,6 @@ static struct common_params
>  *timerlat_top_parse_args(int argc, char **argv)
>  {
>  	struct timerlat_params *params;
> -	struct trace_events *tevent;
>  	long long auto_thresh;
>  	int retval;
>  	int c;
> @@ -566,7 +565,6 @@ static struct common_params
>  	while (1) {
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
> -			{"event",		required_argument,	0, 'e'},
>  			{"help",		no_argument,		0, 'h'},
>  			{"house-keeping",	required_argument,	0, 'H'},
>  			{"irq",			required_argument,	0, 'i'},
> @@ -597,7 +595,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:e:hH:i:knp:P:qs:t::T:uU0:1:2:345:6:7:",
> +		c = getopt_long(argc, argv, "a:hH:i:knp:P:qs:t::T:uU0:1:2:345:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -634,15 +632,6 @@ static struct common_params
>  			/* set aa_only to avoid parsing the trace */
>  			params->common.aa_only = 1;
>  			break;
> -		case 'e':
> -			tevent = trace_event_alloc(optarg);
> -			if (!tevent)
> -				fatal("Error alloc trace event");
> -
> -			if (params->common.events)
> -				tevent->next = params->common.events;
> -			params->common.events = tevent;
> -			break;
>  		case 'h':
>  		case '?':
>  			timerlat_top_usage();
> -- 
> 2.52.0
> 

Reviewed-by: Wander Lairson Costa <wander@redhat.com>


^ permalink raw reply

* Re: [PATCH v2 5/8] tools/rtla: Consolidate -d/--duration option parsing
From: Wander Lairson Costa @ 2025-12-16 16:17 UTC (permalink / raw)
  To: Costa Shulyupin
  Cc: Steven Rostedt, Tomas Glozar, Crystal Wood, John Kacur,
	Ivan Pravdin, linux-trace-kernel, linux-kernel
In-Reply-To: <20251209100047.2692515-5-costa.shul@redhat.com>

On Tue, Dec 09, 2025 at 12:00:44PM +0200, Costa Shulyupin wrote:
> Each rtla tool duplicates parsing of -d/--duration.
> 
> Migrate the option parsing from individual tools to the
> common_parse_options().
> 
> Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
> ---
>  tools/tracing/rtla/src/common.c        | 8 +++++++-
>  tools/tracing/rtla/src/osnoise_hist.c  | 8 +-------
>  tools/tracing/rtla/src/osnoise_top.c   | 8 +-------
>  tools/tracing/rtla/src/timerlat_hist.c | 8 +-------
>  tools/tracing/rtla/src/timerlat_top.c  | 8 +-------
>  5 files changed, 11 insertions(+), 29 deletions(-)
> 
> diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c
> index 5bf79a9bb152..e6ff011d2cd2 100644
> --- a/tools/tracing/rtla/src/common.c
> +++ b/tools/tracing/rtla/src/common.c
> @@ -59,11 +59,12 @@ int common_parse_options(int argc, char **argv, struct common_params *common)
>  		{"cpus",                required_argument,      0, 'c'},
>  		{"cgroup",              optional_argument,      0, 'C'},
>  		{"debug",               no_argument,            0, 'D'},
> +		{"duration",            required_argument,      0, 'd'},
>  		{0, 0, 0, 0}
>  	};
>  
>  	opterr = 0;
> -	c = getopt_long(argc, argv, "c:C::D", long_options, NULL);
> +	c = getopt_long(argc, argv, "c:C::Dd:", long_options, NULL);
>  	opterr = 1;
>  
>  	switch (c) {
> @@ -79,6 +80,11 @@ int common_parse_options(int argc, char **argv, struct common_params *common)
>  	case 'D':
>  		config_debug = 1;
>  		break;
> +	case 'd':
> +		common->duration = parse_seconds_duration(optarg);
> +		if (!common->duration)
> +			fatal("Invalid -d duration");
> +		break;
>  	default:
>  		optind = saved_state;
>  		return 0;
> diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
> index 6902486fb144..1b79bfefc214 100644
> --- a/tools/tracing/rtla/src/osnoise_hist.c
> +++ b/tools/tracing/rtla/src/osnoise_hist.c
> @@ -491,7 +491,6 @@ static struct common_params
>  			{"auto",		required_argument,	0, 'a'},
>  			{"bucket-size",		required_argument,	0, 'b'},
>  			{"entries",		required_argument,	0, 'E'},
> -			{"duration",		required_argument,	0, 'd'},
>  			{"house-keeping",	required_argument,		0, 'H'},
>  			{"help",		no_argument,		0, 'h'},
>  			{"period",		required_argument,	0, 'p'},
> @@ -518,7 +517,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:b:d:e:E:hH:p:P:r:s:S:t::T:01234:5:6:7:",
> +		c = getopt_long(argc, argv, "a:b:e:E:hH:p:P:r:s:S:t::T:01234:5:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -544,11 +543,6 @@ static struct common_params
>  			    params->common.hist.bucket_size >= 1000000)
>  				fatal("Bucket size needs to be > 0 and <= 1000000");
>  			break;
> -		case 'd':
> -			params->common.duration = parse_seconds_duration(optarg);
> -			if (!params->common.duration)
> -				fatal("Invalid -D duration");
> -			break;
>  		case 'e':
>  			tevent = trace_event_alloc(optarg);
>  			if (!tevent)
> diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
> index 4a61fd50b990..619c5bcf8f35 100644
> --- a/tools/tracing/rtla/src/osnoise_top.c
> +++ b/tools/tracing/rtla/src/osnoise_top.c
> @@ -346,7 +346,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  	while (1) {
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
> -			{"duration",		required_argument,	0, 'd'},
>  			{"event",		required_argument,	0, 'e'},
>  			{"house-keeping",	required_argument,	0, 'H'},
>  			{"help",		no_argument,		0, 'h'},
> @@ -370,7 +369,7 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:d:e:hH:p:P:qr:s:S:t::T:0:1:2:3:",
> +		c = getopt_long(argc, argv, "a:e:hH:p:P:qr:s:S:t::T:0:1:2:3:",
>  				 long_options, NULL);
>  
>  		/* Detect the end of the options. */
> @@ -390,11 +389,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  				trace_output = "osnoise_trace.txt";
>  
>  			break;
> -		case 'd':
> -			params->common.duration = parse_seconds_duration(optarg);
> -			if (!params->common.duration)
> -				fatal("Invalid -d duration");
> -			break;
>  		case 'e':
>  			tevent = trace_event_alloc(optarg);
>  			if (!tevent)
> diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
> index 97d20e272583..0a7e5dcce121 100644
> --- a/tools/tracing/rtla/src/timerlat_hist.c
> +++ b/tools/tracing/rtla/src/timerlat_hist.c
> @@ -798,7 +798,6 @@ static struct common_params
>  			{"auto",		required_argument,	0, 'a'},
>  			{"bucket-size",		required_argument,	0, 'b'},
>  			{"entries",		required_argument,	0, 'E'},
> -			{"duration",		required_argument,	0, 'd'},
>  			{"house-keeping",	required_argument,	0, 'H'},
>  			{"help",		no_argument,		0, 'h'},
>  			{"irq",			required_argument,	0, 'i'},
> @@ -834,7 +833,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:b:d:e:E:hH:i:knp:P:s:t::T:uU0123456:7:8:9\1\2:\3:",
> +		c = getopt_long(argc, argv, "a:b:e:E:hH:i:knp:P:s:t::T:uU0123456:7:8:9\1\2:\3:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -863,11 +862,6 @@ static struct common_params
>  			    params->common.hist.bucket_size >= 1000000)
>  				fatal("Bucket size needs to be > 0 and <= 1000000");
>  			break;
> -		case 'd':
> -			params->common.duration = parse_seconds_duration(optarg);
> -			if (!params->common.duration)
> -				fatal("Invalid -D duration");
> -			break;
>  		case 'e':
>  			tevent = trace_event_alloc(optarg);
>  			if (!tevent)
> diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
> index 96bca67d419f..4340fbf3f879 100644
> --- a/tools/tracing/rtla/src/timerlat_top.c
> +++ b/tools/tracing/rtla/src/timerlat_top.c
> @@ -566,7 +566,6 @@ static struct common_params
>  	while (1) {
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
> -			{"duration",		required_argument,	0, 'd'},
>  			{"event",		required_argument,	0, 'e'},
>  			{"help",		no_argument,		0, 'h'},
>  			{"house-keeping",	required_argument,	0, 'H'},
> @@ -598,7 +597,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:d:e:hH:i:knp:P:qs:t::T:uU0:1:2:345:6:7:",
> +		c = getopt_long(argc, argv, "a:e:hH:i:knp:P:qs:t::T:uU0:1:2:345:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -635,11 +634,6 @@ static struct common_params
>  			/* set aa_only to avoid parsing the trace */
>  			params->common.aa_only = 1;
>  			break;
> -		case 'd':
> -			params->common.duration = parse_seconds_duration(optarg);
> -			if (!params->common.duration)
> -				fatal("Invalid -d duration");
> -			break;
>  		case 'e':
>  			tevent = trace_event_alloc(optarg);
>  			if (!tevent)
> -- 
> 2.52.0
> 

Reviewed-by: Wander Lairson Costa <wander@redhat.com>


^ permalink raw reply

* Re: [PATCH v2 4/8] tools/rtla: Consolidate -D/--debug option parsing
From: Wander Lairson Costa @ 2025-12-16 16:17 UTC (permalink / raw)
  To: Costa Shulyupin
  Cc: Steven Rostedt, Tomas Glozar, Crystal Wood, John Kacur,
	Ivan Pravdin, linux-trace-kernel, linux-kernel
In-Reply-To: <20251209100047.2692515-4-costa.shul@redhat.com>

On Tue, Dec 09, 2025 at 12:00:43PM +0200, Costa Shulyupin wrote:
> Each rtla tool duplicates parsing of -D/--debug.
> 
> Migrate the option parsing from individual tools to the
> common_parse_options().
> 
> Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
> ---
>  tools/tracing/rtla/src/common.c        | 6 +++++-
>  tools/tracing/rtla/src/osnoise_hist.c  | 6 +-----
>  tools/tracing/rtla/src/osnoise_top.c   | 6 +-----
>  tools/tracing/rtla/src/timerlat_hist.c | 6 +-----
>  tools/tracing/rtla/src/timerlat_top.c  | 6 +-----
>  5 files changed, 9 insertions(+), 21 deletions(-)
> 
> diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c
> index 33428fa77f9f..5bf79a9bb152 100644
> --- a/tools/tracing/rtla/src/common.c
> +++ b/tools/tracing/rtla/src/common.c
> @@ -58,11 +58,12 @@ int common_parse_options(int argc, char **argv, struct common_params *common)
>  	static struct option long_options[] = {
>  		{"cpus",                required_argument,      0, 'c'},
>  		{"cgroup",              optional_argument,      0, 'C'},
> +		{"debug",               no_argument,            0, 'D'},
>  		{0, 0, 0, 0}
>  	};
>  
>  	opterr = 0;
> -	c = getopt_long(argc, argv, "c:C::", long_options, NULL);
> +	c = getopt_long(argc, argv, "c:C::D", long_options, NULL);
>  	opterr = 1;
>  
>  	switch (c) {
> @@ -75,6 +76,9 @@ int common_parse_options(int argc, char **argv, struct common_params *common)
>  		common->cgroup = 1;
>  		common->cgroup_name = parse_optional_arg(argc, argv);
>  		break;
> +	case 'D':
> +		config_debug = 1;
> +		break;
>  	default:
>  		optind = saved_state;
>  		return 0;
> diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
> index 5cbe5e1f1b07..6902486fb144 100644
> --- a/tools/tracing/rtla/src/osnoise_hist.c
> +++ b/tools/tracing/rtla/src/osnoise_hist.c
> @@ -491,7 +491,6 @@ static struct common_params
>  			{"auto",		required_argument,	0, 'a'},
>  			{"bucket-size",		required_argument,	0, 'b'},
>  			{"entries",		required_argument,	0, 'E'},
> -			{"debug",		no_argument,		0, 'D'},
>  			{"duration",		required_argument,	0, 'd'},
>  			{"house-keeping",	required_argument,		0, 'H'},
>  			{"help",		no_argument,		0, 'h'},
> @@ -519,7 +518,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:b:d:e:E:DhH:p:P:r:s:S:t::T:01234:5:6:7:",
> +		c = getopt_long(argc, argv, "a:b:d:e:E:hH:p:P:r:s:S:t::T:01234:5:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -545,9 +544,6 @@ static struct common_params
>  			    params->common.hist.bucket_size >= 1000000)
>  				fatal("Bucket size needs to be > 0 and <= 1000000");
>  			break;
> -		case 'D':
> -			config_debug = 1;
> -			break;
>  		case 'd':
>  			params->common.duration = parse_seconds_duration(optarg);
>  			if (!params->common.duration)
> diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
> index 35db5b73c0d7..4a61fd50b990 100644
> --- a/tools/tracing/rtla/src/osnoise_top.c
> +++ b/tools/tracing/rtla/src/osnoise_top.c
> @@ -346,7 +346,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  	while (1) {
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
> -			{"debug",		no_argument,		0, 'D'},
>  			{"duration",		required_argument,	0, 'd'},
>  			{"event",		required_argument,	0, 'e'},
>  			{"house-keeping",	required_argument,	0, 'H'},
> @@ -371,7 +370,7 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:d:De:hH:p:P:qr:s:S:t::T:0:1:2:3:",
> +		c = getopt_long(argc, argv, "a:d:e:hH:p:P:qr:s:S:t::T:0:1:2:3:",
>  				 long_options, NULL);
>  
>  		/* Detect the end of the options. */
> @@ -390,9 +389,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  			if (!trace_output)
>  				trace_output = "osnoise_trace.txt";
>  
> -			break;
> -		case 'D':
> -			config_debug = 1;
>  			break;
>  		case 'd':
>  			params->common.duration = parse_seconds_duration(optarg);
> diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
> index 9ecab2bb0f1e..97d20e272583 100644
> --- a/tools/tracing/rtla/src/timerlat_hist.c
> +++ b/tools/tracing/rtla/src/timerlat_hist.c
> @@ -797,7 +797,6 @@ static struct common_params
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
>  			{"bucket-size",		required_argument,	0, 'b'},
> -			{"debug",		no_argument,		0, 'D'},
>  			{"entries",		required_argument,	0, 'E'},
>  			{"duration",		required_argument,	0, 'd'},
>  			{"house-keeping",	required_argument,	0, 'H'},
> @@ -835,7 +834,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:b:d:e:E:DhH:i:knp:P:s:t::T:uU0123456:7:8:9\1\2:\3:",
> +		c = getopt_long(argc, argv, "a:b:d:e:E:hH:i:knp:P:s:t::T:uU0123456:7:8:9\1\2:\3:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -864,9 +863,6 @@ static struct common_params
>  			    params->common.hist.bucket_size >= 1000000)
>  				fatal("Bucket size needs to be > 0 and <= 1000000");
>  			break;
> -		case 'D':
> -			config_debug = 1;
> -			break;
>  		case 'd':
>  			params->common.duration = parse_seconds_duration(optarg);
>  			if (!params->common.duration)
> diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
> index 6329c3a489aa..96bca67d419f 100644
> --- a/tools/tracing/rtla/src/timerlat_top.c
> +++ b/tools/tracing/rtla/src/timerlat_top.c
> @@ -566,7 +566,6 @@ static struct common_params
>  	while (1) {
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
> -			{"debug",		no_argument,		0, 'D'},
>  			{"duration",		required_argument,	0, 'd'},
>  			{"event",		required_argument,	0, 'e'},
>  			{"help",		no_argument,		0, 'h'},
> @@ -599,7 +598,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:d:De:hH:i:knp:P:qs:t::T:uU0:1:2:345:6:7:",
> +		c = getopt_long(argc, argv, "a:d:e:hH:i:knp:P:qs:t::T:uU0:1:2:345:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -636,9 +635,6 @@ static struct common_params
>  			/* set aa_only to avoid parsing the trace */
>  			params->common.aa_only = 1;
>  			break;
> -		case 'D':
> -			config_debug = 1;
> -			break;
>  		case 'd':
>  			params->common.duration = parse_seconds_duration(optarg);
>  			if (!params->common.duration)
> -- 
> 2.52.0
> 

Reviewed-by: Wander Lairson Costa <wander@redhat.com>


^ permalink raw reply

* Re: [PATCH v2 3/8] tools/rtla: Consolidate -C/--cgroup option parsing
From: Wander Lairson Costa @ 2025-12-16 16:17 UTC (permalink / raw)
  To: Costa Shulyupin
  Cc: Steven Rostedt, Tomas Glozar, Crystal Wood, John Kacur,
	Ivan Pravdin, linux-trace-kernel, linux-kernel
In-Reply-To: <20251209100047.2692515-3-costa.shul@redhat.com>

On Tue, Dec 09, 2025 at 12:00:42PM +0200, Costa Shulyupin wrote:
> Each rtla tool duplicates parsing of -C/--cgroup.
> 
> Migrate the option parsing from individual tools to the
> common_parse_options().
> 
> Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
> ---
>  tools/tracing/rtla/src/common.c        | 7 ++++++-
>  tools/tracing/rtla/src/osnoise_hist.c  | 7 +------
>  tools/tracing/rtla/src/osnoise_top.c   | 7 +------
>  tools/tracing/rtla/src/timerlat_hist.c | 7 +------
>  tools/tracing/rtla/src/timerlat_top.c  | 7 +------
>  5 files changed, 10 insertions(+), 25 deletions(-)
> 
> diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c
> index e5aa8c30cd7d..33428fa77f9f 100644
> --- a/tools/tracing/rtla/src/common.c
> +++ b/tools/tracing/rtla/src/common.c
> @@ -57,11 +57,12 @@ int common_parse_options(int argc, char **argv, struct common_params *common)
>  
>  	static struct option long_options[] = {
>  		{"cpus",                required_argument,      0, 'c'},
> +		{"cgroup",              optional_argument,      0, 'C'},
>  		{0, 0, 0, 0}
>  	};
>  
>  	opterr = 0;
> -	c = getopt_long(argc, argv, "c:", long_options, NULL);
> +	c = getopt_long(argc, argv, "c:C::", long_options, NULL);
>  	opterr = 1;
>  
>  	switch (c) {
> @@ -70,6 +71,10 @@ int common_parse_options(int argc, char **argv, struct common_params *common)
>  			fatal("Invalid -c cpu list");
>  		common->cpus = optarg;
>  		break;
> +	case 'C':
> +		common->cgroup = 1;
> +		common->cgroup_name = parse_optional_arg(argc, argv);
> +		break;
>  	default:
>  		optind = saved_state;
>  		return 0;
> diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
> index 9e721362989a..5cbe5e1f1b07 100644
> --- a/tools/tracing/rtla/src/osnoise_hist.c
> +++ b/tools/tracing/rtla/src/osnoise_hist.c
> @@ -491,7 +491,6 @@ static struct common_params
>  			{"auto",		required_argument,	0, 'a'},
>  			{"bucket-size",		required_argument,	0, 'b'},
>  			{"entries",		required_argument,	0, 'E'},
> -			{"cgroup",		optional_argument,	0, 'C'},
>  			{"debug",		no_argument,		0, 'D'},
>  			{"duration",		required_argument,	0, 'd'},
>  			{"house-keeping",	required_argument,		0, 'H'},
> @@ -520,7 +519,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:C::b:d:e:E:DhH:p:P:r:s:S:t::T:01234:5:6:7:",
> +		c = getopt_long(argc, argv, "a:b:d:e:E:DhH:p:P:r:s:S:t::T:01234:5:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -546,10 +545,6 @@ static struct common_params
>  			    params->common.hist.bucket_size >= 1000000)
>  				fatal("Bucket size needs to be > 0 and <= 1000000");
>  			break;
> -		case 'C':
> -			params->common.cgroup = 1;
> -			params->common.cgroup_name = parse_optional_arg(argc, argv);
> -			break;
>  		case 'D':
>  			config_debug = 1;
>  			break;
> diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
> index 73736cefd992..35db5b73c0d7 100644
> --- a/tools/tracing/rtla/src/osnoise_top.c
> +++ b/tools/tracing/rtla/src/osnoise_top.c
> @@ -346,7 +346,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  	while (1) {
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
> -			{"cgroup",		optional_argument,	0, 'C'},
>  			{"debug",		no_argument,		0, 'D'},
>  			{"duration",		required_argument,	0, 'd'},
>  			{"event",		required_argument,	0, 'e'},
> @@ -372,7 +371,7 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:C::d:De:hH:p:P:qr:s:S:t::T:0:1:2:3:",
> +		c = getopt_long(argc, argv, "a:d:De:hH:p:P:qr:s:S:t::T:0:1:2:3:",
>  				 long_options, NULL);
>  
>  		/* Detect the end of the options. */
> @@ -391,10 +390,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  			if (!trace_output)
>  				trace_output = "osnoise_trace.txt";
>  
> -			break;
> -		case 'C':
> -			params->common.cgroup = 1;
> -			params->common.cgroup_name = parse_optional_arg(argc, argv);
>  			break;
>  		case 'D':
>  			config_debug = 1;
> diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
> index 4ae77145adea..9ecab2bb0f1e 100644
> --- a/tools/tracing/rtla/src/timerlat_hist.c
> +++ b/tools/tracing/rtla/src/timerlat_hist.c
> @@ -796,7 +796,6 @@ static struct common_params
>  	while (1) {
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
> -			{"cgroup",		optional_argument,	0, 'C'},
>  			{"bucket-size",		required_argument,	0, 'b'},
>  			{"debug",		no_argument,		0, 'D'},
>  			{"entries",		required_argument,	0, 'E'},
> @@ -836,7 +835,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:C::b:d:e:E:DhH:i:knp:P:s:t::T:uU0123456:7:8:9\1\2:\3:",
> +		c = getopt_long(argc, argv, "a:b:d:e:E:DhH:i:knp:P:s:t::T:uU0123456:7:8:9\1\2:\3:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -858,10 +857,6 @@ static struct common_params
>  			if (!trace_output)
>  				trace_output = "timerlat_trace.txt";
>  
> -			break;
> -		case 'C':
> -			params->common.cgroup = 1;
> -			params->common.cgroup_name = parse_optional_arg(argc, argv);
>  			break;
>  		case 'b':
>  			params->common.hist.bucket_size = get_llong_from_str(optarg);
> diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
> index 9774c26b27ff..6329c3a489aa 100644
> --- a/tools/tracing/rtla/src/timerlat_top.c
> +++ b/tools/tracing/rtla/src/timerlat_top.c
> @@ -566,7 +566,6 @@ static struct common_params
>  	while (1) {
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
> -			{"cgroup",		optional_argument,	0, 'C'},
>  			{"debug",		no_argument,		0, 'D'},
>  			{"duration",		required_argument,	0, 'd'},
>  			{"event",		required_argument,	0, 'e'},
> @@ -600,7 +599,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:C::d:De:hH:i:knp:P:qs:t::T:uU0:1:2:345:6:7:",
> +		c = getopt_long(argc, argv, "a:d:De:hH:i:knp:P:qs:t::T:uU0:1:2:345:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -637,10 +636,6 @@ static struct common_params
>  			/* set aa_only to avoid parsing the trace */
>  			params->common.aa_only = 1;
>  			break;
> -		case 'C':
> -			params->common.cgroup = 1;
> -			params->common.cgroup_name = optarg;
> -			break;
>  		case 'D':
>  			config_debug = 1;
>  			break;
> -- 
> 2.52.0
> 

Reviewed-by: Wander Lairson Costa <wander@redhat.com>


^ permalink raw reply

* Re: [PATCH v2 2/8] tools/rtla: Consolidate -c/--cpus option parsing
From: Wander Lairson Costa @ 2025-12-16 16:16 UTC (permalink / raw)
  To: Costa Shulyupin
  Cc: Steven Rostedt, Tomas Glozar, Crystal Wood, John Kacur,
	Ivan Pravdin, linux-trace-kernel, linux-kernel
In-Reply-To: <20251209100047.2692515-2-costa.shul@redhat.com>

On Tue, Dec 09, 2025 at 12:00:41PM +0200, Costa Shulyupin wrote:
> Each rtla tool duplicates parsing of -c/--cpus.
> 
> Migrate the option parsing from individual tools to the
> common_parse_options().
> 
> Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
> ---
>  tools/tracing/rtla/src/common.c        | 8 +++++++-
>  tools/tracing/rtla/src/osnoise_hist.c  | 9 +--------
>  tools/tracing/rtla/src/osnoise_top.c   | 9 +--------
>  tools/tracing/rtla/src/timerlat_hist.c | 9 +--------
>  tools/tracing/rtla/src/timerlat_top.c  | 9 +--------
>  5 files changed, 11 insertions(+), 33 deletions(-)
> 
> diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c
> index a78f9883521e..e5aa8c30cd7d 100644
> --- a/tools/tracing/rtla/src/common.c
> +++ b/tools/tracing/rtla/src/common.c
> @@ -56,14 +56,20 @@ int common_parse_options(int argc, char **argv, struct common_params *common)
>  	int c;
>  
>  	static struct option long_options[] = {
> +		{"cpus",                required_argument,      0, 'c'},
>  		{0, 0, 0, 0}
>  	};
>  
>  	opterr = 0;
> -	c = getopt_long(argc, argv, "", long_options, NULL);
> +	c = getopt_long(argc, argv, "c:", long_options, NULL);
>  	opterr = 1;
>  
>  	switch (c) {
> +	case 'c':
> +		if (parse_cpu_set(optarg, &common->monitored_cpus))
> +			fatal("Invalid -c cpu list");
> +		common->cpus = optarg;
> +		break;
>  	default:
>  		optind = saved_state;
>  		return 0;
> diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
> index 35f4a068af95..9e721362989a 100644
> --- a/tools/tracing/rtla/src/osnoise_hist.c
> +++ b/tools/tracing/rtla/src/osnoise_hist.c
> @@ -491,7 +491,6 @@ static struct common_params
>  			{"auto",		required_argument,	0, 'a'},
>  			{"bucket-size",		required_argument,	0, 'b'},
>  			{"entries",		required_argument,	0, 'E'},
> -			{"cpus",		required_argument,	0, 'c'},
>  			{"cgroup",		optional_argument,	0, 'C'},
>  			{"debug",		no_argument,		0, 'D'},
>  			{"duration",		required_argument,	0, 'd'},
> @@ -521,7 +520,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:p:P:r:s:S:t::T:01234:5:6:7:",
> +		c = getopt_long(argc, argv, "a:C::b:d:e:E:DhH:p:P:r:s:S:t::T:01234:5:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -547,12 +546,6 @@ static struct common_params
>  			    params->common.hist.bucket_size >= 1000000)
>  				fatal("Bucket size needs to be > 0 and <= 1000000");
>  			break;
> -		case 'c':
> -			retval = parse_cpu_set(optarg, &params->common.monitored_cpus);
> -			if (retval)
> -				fatal("Invalid -c cpu list");
> -			params->common.cpus = optarg;
> -			break;
>  		case 'C':
>  			params->common.cgroup = 1;
>  			params->common.cgroup_name = parse_optional_arg(argc, argv);
> diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
> index 550731c7addd..73736cefd992 100644
> --- a/tools/tracing/rtla/src/osnoise_top.c
> +++ b/tools/tracing/rtla/src/osnoise_top.c
> @@ -346,7 +346,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  	while (1) {
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
> -			{"cpus",		required_argument,	0, 'c'},
>  			{"cgroup",		optional_argument,	0, 'C'},
>  			{"debug",		no_argument,		0, 'D'},
>  			{"duration",		required_argument,	0, 'd'},
> @@ -373,7 +372,7 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:c:C::d:De:hH:p:P:qr:s:S:t::T:0:1:2:3:",
> +		c = getopt_long(argc, argv, "a:C::d:De:hH:p:P:qr:s:S:t::T:0:1:2:3:",
>  				 long_options, NULL);
>  
>  		/* Detect the end of the options. */
> @@ -392,12 +391,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  			if (!trace_output)
>  				trace_output = "osnoise_trace.txt";
>  
> -			break;
> -		case 'c':
> -			retval = parse_cpu_set(optarg, &params->common.monitored_cpus);
> -			if (retval)
> -				fatal("Invalid -c cpu list");
> -			params->common.cpus = optarg;
>  			break;
>  		case 'C':
>  			params->common.cgroup = 1;
> diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
> index ffcfcabb9964..4ae77145adea 100644
> --- a/tools/tracing/rtla/src/timerlat_hist.c
> +++ b/tools/tracing/rtla/src/timerlat_hist.c
> @@ -796,7 +796,6 @@ static struct common_params
>  	while (1) {
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
> -			{"cpus",		required_argument,	0, 'c'},
>  			{"cgroup",		optional_argument,	0, 'C'},
>  			{"bucket-size",		required_argument,	0, 'b'},
>  			{"debug",		no_argument,		0, 'D'},
> @@ -837,7 +836,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:i:knp:P:s:t::T:uU0123456:7:8:9\1\2:\3:",
> +		c = getopt_long(argc, argv, "a:C::b:d:e:E:DhH:i:knp:P:s:t::T:uU0123456:7:8:9\1\2:\3:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -859,12 +858,6 @@ static struct common_params
>  			if (!trace_output)
>  				trace_output = "timerlat_trace.txt";
>  
> -			break;
> -		case 'c':
> -			retval = parse_cpu_set(optarg, &params->common.monitored_cpus);
> -			if (retval)
> -				fatal("Invalid -c cpu list");
> -			params->common.cpus = optarg;
>  			break;
>  		case 'C':
>  			params->common.cgroup = 1;
> diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
> index d18d48671ccd..9774c26b27ff 100644
> --- a/tools/tracing/rtla/src/timerlat_top.c
> +++ b/tools/tracing/rtla/src/timerlat_top.c
> @@ -566,7 +566,6 @@ static struct common_params
>  	while (1) {
>  		static struct option long_options[] = {
>  			{"auto",		required_argument,	0, 'a'},
> -			{"cpus",		required_argument,	0, 'c'},
>  			{"cgroup",		optional_argument,	0, 'C'},
>  			{"debug",		no_argument,		0, 'D'},
>  			{"duration",		required_argument,	0, 'd'},
> @@ -601,7 +600,7 @@ static struct common_params
>  		if (common_parse_options(argc, argv, &params->common))
>  			continue;
>  
> -		c = getopt_long(argc, argv, "a:c:C::d:De:hH:i:knp:P:qs:t::T:uU0:1:2:345:6:7:",
> +		c = getopt_long(argc, argv, "a:C::d:De:hH:i:knp:P:qs:t::T:uU0:1:2:345:6:7:",
>  				 long_options, NULL);
>  
>  		/* detect the end of the options. */
> @@ -638,12 +637,6 @@ static struct common_params
>  			/* set aa_only to avoid parsing the trace */
>  			params->common.aa_only = 1;
>  			break;
> -		case 'c':
> -			retval = parse_cpu_set(optarg, &params->common.monitored_cpus);
> -			if (retval)
> -				fatal("Invalid -c cpu list");
> -			params->common.cpus = optarg;
> -			break;
>  		case 'C':
>  			params->common.cgroup = 1;
>  			params->common.cgroup_name = optarg;
> -- 
> 2.52.0
> 

Reviewed-by: Wander Lairson Costa <wander@redhat.com>


^ permalink raw reply

* Re: [PATCH v2 1/8] tools/rtla: Add common_parse_options()
From: Wander Lairson Costa @ 2025-12-16 16:16 UTC (permalink / raw)
  To: Costa Shulyupin
  Cc: Steven Rostedt, Tomas Glozar, Crystal Wood, John Kacur,
	Ivan Pravdin, linux-trace-kernel, linux-kernel
In-Reply-To: <20251209100047.2692515-1-costa.shul@redhat.com>

On Tue, Dec 09, 2025 at 12:00:40PM +0200, Costa Shulyupin wrote:
> Each rtla tool duplicates parsing of many common options. This creates
> maintenance overhead and risks inconsistencies when updating these
> options.
> 
> Add common_parse_options() to centralize parsing of options used across
> all tools.
> 
> Common options to be migrated in future patches.
> 
> Changes since v1:
> - restore opterr
> 
> Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
> ---
>  tools/tracing/rtla/src/common.c        | 35 ++++++++++++++++++++++++++
>  tools/tracing/rtla/src/common.h        |  1 +
>  tools/tracing/rtla/src/osnoise_hist.c  |  3 +++
>  tools/tracing/rtla/src/osnoise_top.c   |  3 +++
>  tools/tracing/rtla/src/timerlat_hist.c |  3 +++
>  tools/tracing/rtla/src/timerlat_top.c  |  3 +++
>  6 files changed, 48 insertions(+)
> 
> diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c
> index b197037fc58b..a78f9883521e 100644
> --- a/tools/tracing/rtla/src/common.c
> +++ b/tools/tracing/rtla/src/common.c
> @@ -5,6 +5,7 @@
>  #include <signal.h>
>  #include <stdlib.h>
>  #include <unistd.h>
> +#include <getopt.h>
>  #include "common.h"
>  
>  struct trace_instance *trace_inst;
> @@ -37,6 +38,40 @@ static void set_signals(struct common_params *params)
>  	}
>  }
>  
> +/*
> + * common_parse_options - parse common command line options
> + *
> + * @argc: argument count
> + * @argv: argument vector
> + * @common: common parameters structure
> + *
> + * Parse command line options that are common to all rtla tools.
> + *
> + * Returns: non zero if a common option was parsed, or 0
> + * if the option should be handled by tool-specific parsing.
> + */
> +int common_parse_options(int argc, char **argv, struct common_params *common)
> +{
> +	int saved_state = optind;
> +	int c;
> +
> +	static struct option long_options[] = {
> +		{0, 0, 0, 0}
> +	};
> +
> +	opterr = 0;
> +	c = getopt_long(argc, argv, "", long_options, NULL);
> +	opterr = 1;
> +
> +	switch (c) {
> +	default:
> +		optind = saved_state;
> +		return 0;
> +	}
> +
> +	return c;
> +}
> +
>  /*
>   * common_apply_config - apply common configs to the initialized tool
>   */
> diff --git a/tools/tracing/rtla/src/common.h b/tools/tracing/rtla/src/common.h
> index 9ec2b7632c37..1066d777a823 100644
> --- a/tools/tracing/rtla/src/common.h
> +++ b/tools/tracing/rtla/src/common.h
> @@ -153,6 +153,7 @@ struct osnoise_tool *osnoise_init_tool(char *tool_name);
>  struct osnoise_tool *osnoise_init_trace_tool(const char *tracer);
>  bool osnoise_trace_is_off(struct osnoise_tool *tool, struct osnoise_tool *record);
>  
> +int common_parse_options(int argc, char **argv, struct common_params *common);
>  int common_apply_config(struct osnoise_tool *tool, struct common_params *params);
>  int top_main_loop(struct osnoise_tool *tool);
>  int hist_main_loop(struct osnoise_tool *tool);
> diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
> index ff8c231e47c4..35f4a068af95 100644
> --- a/tools/tracing/rtla/src/osnoise_hist.c
> +++ b/tools/tracing/rtla/src/osnoise_hist.c
> @@ -518,6 +518,9 @@ static struct common_params
>  			{0, 0, 0, 0}
>  		};
>  
> +		if (common_parse_options(argc, argv, &params->common))
> +			continue;
> +
>  		c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:p:P:r:s:S:t::T:01234:5:6:7:",
>  				 long_options, NULL);
>  
> diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
> index 04c699bdd736..550731c7addd 100644
> --- a/tools/tracing/rtla/src/osnoise_top.c
> +++ b/tools/tracing/rtla/src/osnoise_top.c
> @@ -370,6 +370,9 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
>  			{0, 0, 0, 0}
>  		};
>  
> +		if (common_parse_options(argc, argv, &params->common))
> +			continue;
> +
>  		c = getopt_long(argc, argv, "a:c:C::d:De:hH:p:P:qr:s:S:t::T:0:1:2:3:",
>  				 long_options, NULL);
>  
> diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
> index 1fb471a787b7..ffcfcabb9964 100644
> --- a/tools/tracing/rtla/src/timerlat_hist.c
> +++ b/tools/tracing/rtla/src/timerlat_hist.c
> @@ -834,6 +834,9 @@ static struct common_params
>  			{0, 0, 0, 0}
>  		};
>  
> +		if (common_parse_options(argc, argv, &params->common))
> +			continue;
> +
>  		c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:i:knp:P:s:t::T:uU0123456:7:8:9\1\2:\3:",
>  				 long_options, NULL);
>  
> diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
> index 29c2c1f717ed..d18d48671ccd 100644
> --- a/tools/tracing/rtla/src/timerlat_top.c
> +++ b/tools/tracing/rtla/src/timerlat_top.c
> @@ -598,6 +598,9 @@ static struct common_params
>  			{0, 0, 0, 0}
>  		};
>  
> +		if (common_parse_options(argc, argv, &params->common))
> +			continue;
> +
>  		c = getopt_long(argc, argv, "a:c:C::d:De:hH:i:knp:P:qs:t::T:uU0:1:2:345:6:7:",
>  				 long_options, NULL);
>  
> -- 
> 2.52.0
> 

Reviewed-by: Wander Lairson Costa <wander@redhat.com>


^ permalink raw reply

* Re: 答复: [External Mail]Re: [PATCH v6] dma-buf: add some tracepoints to debug.
From: Christian König @ 2025-12-16 16:15 UTC (permalink / raw)
  To: 高翔, Xiang Gao, sumit.semwal@linaro.org,
	rostedt@goodmis.org, mhiramat@kernel.org
  Cc: linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org,
	linux-kernel@vger.kernel.org, mathieu.desnoyers@efficios.com,
	dhowells@redhat.com, kuba@kernel.org, brauner@kernel.org,
	akpm@linux-foundation.org, linux-trace-kernel@vger.kernel.org
In-Reply-To: <b0e5daa85079423480fdbb82c09dc707@xiaomi.com>

I have to take that back, the automated checkers have nit picks on this patch:

/home/ckoenig/Downloads/[PATCH v6] dma-buf: add some tracepoints to debug. - Xiang Gao <gxxa03070307@gmail.com> - 2025-12-16 0739.eml:308: trailing whitespace.
/* SPDX-License-Identifier: GPL-2.0 */
/home/ckoenig/Downloads/[PATCH v6] dma-buf: add some tracepoints to debug. - Xiang Gao <gxxa03070307@gmail.com> - 2025-12-16 0739.eml:309: trailing whitespace.
#undef TRACE_SYSTEM
/home/ckoenig/Downloads/[PATCH v6] dma-buf: add some tracepoints to debug. - Xiang Gao <gxxa03070307@gmail.com> - 2025-12-16 0739.eml:310: trailing whitespace.
#define TRACE_SYSTEM dma_buf
/home/ckoenig/Downloads/[PATCH v6] dma-buf: add some tracepoints to debug. - Xiang Gao <gxxa03070307@gmail.com> - 2025-12-16 0739.eml:311: trailing whitespace.

/home/ckoenig/Downloads/[PATCH v6] dma-buf: add some tracepoints to debug. - Xiang Gao <gxxa03070307@gmail.com> - 2025-12-16 0739.eml:312: trailing whitespace.
#if !defined(_TRACE_DMA_BUF_H) || defined(TRACE_HEADER_MULTI_READ)

Additional to that the patch doesn't seems to be based against drm-misc-next:

error: patch failed: drivers/dma-buf/dma-buf.c:35
error: drivers/dma-buf/dma-buf.c: patch does not apply

So please fix the whitespace issues, rebase and send out again. I should be able to apply it tomorrow then.

Regards,
Christian.

On 12/16/25 14:12, 高翔 wrote:
> thanks.
> 
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> *发件人:* Christian König <christian.koenig@amd.com>
> *发送时间:* 2025年12月16日 16:43:26
> *收件人:* Xiang Gao; sumit.semwal@linaro.org; rostedt@goodmis.org; mhiramat@kernel.org
> *抄送:* linux-media@vger.kernel.org; dri-devel@lists.freedesktop.org; linux-kernel@vger.kernel.org; mathieu.desnoyers@efficios.com; dhowells@redhat.com; kuba@kernel.org; brauner@kernel.org; akpm@linux-foundation.org; linux-trace-kernel@vger.kernel.org; 高翔
> *主题:* [External Mail]Re: [PATCH v6] dma-buf: add some tracepoints to debug.
>  
> [外部邮件] 此邮件来源于小米公司外部,请谨慎处理。若对邮件安全性存疑,请将邮件转发给misec@xiaomi.com进行反馈
> 
> On 12/16/25 07:39, Xiang Gao wrote:
>> From: gaoxiang17 <gaoxiang17@xiaomi.com>
>>
>> Since we can only inspect dmabuf by iterating over process FDs or the
>> dmabuf_list, we need to add our own tracepoints to track its status in
>> real time in production.
>>
>> For example:
>>    binder:3016_1-3102    [006] ...1.   255.126521: dma_buf_export: exp_name=qcom,system size=12685312 ino=2738
>>    binder:3016_1-3102    [006] ...1.   255.126528: dma_buf_fd: exp_name=qcom,system size=12685312 ino=2738 fd=8
>>    binder:3016_1-3102    [006] ...1.   255.126642: dma_buf_mmap_internal: exp_name=qcom,system size=28672 ino=2739
>>      kworker/6:1-86      [006] ...1.   255.127194: dma_buf_put: exp_name=qcom,system size=12685312 ino=2738
>>     RenderThread-9293    [006] ...1.   316.618179: dma_buf_get: exp_name=qcom,system size=12771328 ino=2762 fd=176
>>     RenderThread-9293    [006] ...1.   316.618195: dma_buf_dynamic_attach: exp_name=qcom,system size=12771328 ino=2762 attachment:ffffff880a18dd00 is_dynamic=0 dev_name=kgsl-3d0
>>     RenderThread-9293    [006] ...1.   318.878220: dma_buf_detach: exp_name=qcom,system size=12771328 ino=2762 attachment:ffffff880a18dd00 is_dynamic=0 dev_name=kgsl-3d0
>>
>> Signed-off-by: Xiang Gao <gaoxiang17@xiaomi.com>
> 
> Reviewed-by: Christian König <christian.koenig@amd.com>
> 
> Going to push this to drm-misc-next today unless somebody has some last minute objections.
> 
> Regards,
> Christian.
> 
>> ---
>>  drivers/dma-buf/dma-buf.c      |  42 ++++++++-
>>  include/trace/events/dma_buf.h | 154 +++++++++++++++++++++++++++++++++
>>  2 files changed, 195 insertions(+), 1 deletion(-)
>>  create mode 100644 include/trace/events/dma_buf.h
>>
>> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
>> index 2bcf9ceca997..831973de76c4 100644
>> --- a/drivers/dma-buf/dma-buf.c
>> +++ b/drivers/dma-buf/dma-buf.c
>> @@ -35,6 +35,25 @@
>>
>>  #include "dma-buf-sysfs-stats.h"
>>
>> +#define CREATE_TRACE_POINTS
>> +#include <trace/events/dma_buf.h>
>> +
>> +/*
>> + * dmabuf->name must be accessed with holding dmabuf->name_lock.
>> + * we need to take the lock around the tracepoint call itself where
>> + * it is called in the code.
>> + *
>> + * Note: FUNC##_enabled() is a static branch that will only
>> + *       be set when the trace event is enabled.
>> + */
>> +#define DMA_BUF_TRACE(FUNC, ...)                  \
>> +    do {                                          \
>> +        if (FUNC##_enabled()) {                   \
>> +            guard(spinlock)(&dmabuf->name_lock); \
>> +            FUNC(__VA_ARGS__);                    \
>> +        }                                         \
>> +    } while (0)
>> +
>>  static inline int is_dma_buf_file(struct file *);
>>
>>  static DEFINE_MUTEX(dmabuf_list_mutex);
>> @@ -220,6 +239,8 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
>>           dmabuf->size >> PAGE_SHIFT)
>>               return -EINVAL;
>>
>> +     DMA_BUF_TRACE(trace_dma_buf_mmap_internal, dmabuf);
>> +
>>       return dmabuf->ops->mmap(dmabuf, vma);
>>  }
>>
>> @@ -745,6 +766,8 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
>>
>>       __dma_buf_list_add(dmabuf);
>>
>> +     DMA_BUF_TRACE(trace_dma_buf_export, dmabuf);
>> +
>>       return dmabuf;
>>
>>  err_dmabuf:
>> @@ -779,6 +802,8 @@ int dma_buf_fd(struct dma_buf *dmabuf, int flags)
>>
>>       fd_install(fd, dmabuf->file);
>>
>> +     DMA_BUF_TRACE(trace_dma_buf_fd, dmabuf, fd);
>> +
>>       return fd;
>>  }
>>  EXPORT_SYMBOL_NS_GPL(dma_buf_fd, "DMA_BUF");
>> @@ -794,6 +819,7 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_fd, "DMA_BUF");
>>  struct dma_buf *dma_buf_get(int fd)
>>  {
>>       struct file *file;
>> +     struct dma_buf *dmabuf;
>>
>>       file = fget(fd);
>>
>> @@ -805,7 +831,11 @@ struct dma_buf *dma_buf_get(int fd)
>>               return ERR_PTR(-EINVAL);
>>       }
>>
>> -     return file->private_data;
>> +     dmabuf = file->private_data;
>> +
>> +     DMA_BUF_TRACE(trace_dma_buf_get, dmabuf, fd);
>> +
>> +     return dmabuf;
>>  }
>>  EXPORT_SYMBOL_NS_GPL(dma_buf_get, "DMA_BUF");
>>
>> @@ -825,6 +855,8 @@ void dma_buf_put(struct dma_buf *dmabuf)
>>               return;
>>
>>       fput(dmabuf->file);
>> +
>> +     DMA_BUF_TRACE(trace_dma_buf_put, dmabuf);
>>  }
>>  EXPORT_SYMBOL_NS_GPL(dma_buf_put, "DMA_BUF");
>>
>> @@ -979,6 +1011,9 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
>>       list_add(&attach->node, &dmabuf->attachments);
>>       dma_resv_unlock(dmabuf->resv);
>>
>> +     DMA_BUF_TRACE(trace_dma_buf_dynamic_attach, dmabuf, attach,
>> +             dma_buf_attachment_is_dynamic(attach), dev);
>> +
>>       return attach;
>>
>>  err_attach:
>> @@ -1023,6 +1058,9 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
>>       if (dmabuf->ops->detach)
>>               dmabuf->ops->detach(dmabuf, attach);
>>
>> +     DMA_BUF_TRACE(trace_dma_buf_detach, dmabuf, attach,
>> +             dma_buf_attachment_is_dynamic(attach), attach->dev);
>> +
>>       kfree(attach);
>>  }
>>  EXPORT_SYMBOL_NS_GPL(dma_buf_detach, "DMA_BUF");
>> @@ -1488,6 +1526,8 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
>>       vma_set_file(vma, dmabuf->file);
>>       vma->vm_pgoff = pgoff;
>>
>> +     DMA_BUF_TRACE(trace_dma_buf_mmap, dmabuf);
>> +
>>       return dmabuf->ops->mmap(dmabuf, vma);
>>  }
>>  EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, "DMA_BUF");
>> diff --git a/include/trace/events/dma_buf.h b/include/trace/events/dma_buf.h
>> new file mode 100644
>> index 000000000000..81ee4d05979c
>> --- /dev/null
>> +++ b/include/trace/events/dma_buf.h
>> @@ -0,0 +1,154 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +#undef TRACE_SYSTEM
>> +#define TRACE_SYSTEM dma_buf
>> +
>> +#if !defined(_TRACE_DMA_BUF_H) || defined(TRACE_HEADER_MULTI_READ)
>> +#define _TRACE_DMA_BUF_H
>> +
>> +#include <linux/dma-buf.h>
>> +#include <linux/tracepoint.h>
>> +
>> +DECLARE_EVENT_CLASS(dma_buf,
>> +
>> +     TP_PROTO(struct dma_buf *dmabuf),
>> +
>> +     TP_ARGS(dmabuf),
>> +
>> +     TP_STRUCT__entry(
>> +             __string(exp_name, dmabuf->exp_name)
>> +             __field(size_t, size)
>> +             __field(ino_t, ino)
>> +     ),
>> +
>> +     TP_fast_assign(
>> +             __assign_str(exp_name);
>> +             __entry->size = dmabuf->size;
>> +             __entry->ino = dmabuf->file->f_inode->i_ino;
>> +     ),
>> +
>> +     TP_printk("exp_name=%s size=%zu ino=%lu",
>> +               __get_str(exp_name),
>> +               __entry->size,
>> +               __entry->ino)
>> +);
>> +
>> +DECLARE_EVENT_CLASS(dma_buf_attach_dev,
>> +
>> +     TP_PROTO(struct dma_buf *dmabuf, struct dma_buf_attachment *attach, bool is_dynamic, struct device *dev),
>> +
>> +     TP_ARGS(dmabuf, attach, is_dynamic, dev),
>> +
>> +     TP_STRUCT__entry(
>> +             __string(dev_name, dev_name(dev))
>> +             __string(exp_name, dmabuf->exp_name)
>> +             __field(size_t, size)
>> +             __field(ino_t, ino)
>> +             __field(struct dma_buf_attachment *, attach)
>> +             __field(bool, is_dynamic)
>> +     ),
>> +
>> +     TP_fast_assign(
>> +             __assign_str(dev_name);
>> +             __assign_str(exp_name);
>> +             __entry->size = dmabuf->size;
>> +             __entry->ino = dmabuf->file->f_inode->i_ino;
>> +             __entry->is_dynamic = is_dynamic;
>> +             __entry->attach = attach;
>> +     ),
>> +
>> +     TP_printk("exp_name=%s size=%zu ino=%lu attachment:%p is_dynamic=%d dev_name=%s",
>> +               __get_str(exp_name),
>> +               __entry->size,
>> +               __entry->ino,
>> +               __entry->attach,
>> +               __entry->is_dynamic,
>> +               __get_str(dev_name))
>> +);
>> +
>> +DECLARE_EVENT_CLASS(dma_buf_fd,
>> +
>> +     TP_PROTO(struct dma_buf *dmabuf, int fd),
>> +
>> +     TP_ARGS(dmabuf, fd),
>> +
>> +     TP_STRUCT__entry(
>> +             __string(exp_name, dmabuf->exp_name)
>> +             __field(size_t, size)
>> +             __field(ino_t, ino)
>> +             __field(int, fd)
>> +     ),
>> +
>> +     TP_fast_assign(
>> +             __assign_str(exp_name);
>> +             __entry->size = dmabuf->size;
>> +             __entry->ino = dmabuf->file->f_inode->i_ino;
>> +             __entry->fd = fd;
>> +     ),
>> +
>> +     TP_printk("exp_name=%s size=%zu ino=%lu fd=%d",
>> +               __get_str(exp_name),
>> +               __entry->size,
>> +               __entry->ino,
>> +               __entry->fd)
>> +);
>> +
>> +DEFINE_EVENT(dma_buf, dma_buf_export,
>> +
>> +     TP_PROTO(struct dma_buf *dmabuf),
>> +
>> +     TP_ARGS(dmabuf)
>> +);
>> +
>> +DEFINE_EVENT(dma_buf, dma_buf_mmap_internal,
>> +
>> +     TP_PROTO(struct dma_buf *dmabuf),
>> +
>> +     TP_ARGS(dmabuf)
>> +);
>> +
>> +DEFINE_EVENT(dma_buf, dma_buf_mmap,
>> +
>> +     TP_PROTO(struct dma_buf *dmabuf),
>> +
>> +     TP_ARGS(dmabuf)
>> +);
>> +
>> +DEFINE_EVENT(dma_buf, dma_buf_put,
>> +
>> +     TP_PROTO(struct dma_buf *dmabuf),
>> +
>> +     TP_ARGS(dmabuf)
>> +);
>> +
>> +DEFINE_EVENT(dma_buf_attach_dev, dma_buf_dynamic_attach,
>> +
>> +     TP_PROTO(struct dma_buf *dmabuf, struct dma_buf_attachment *attach, bool is_dynamic, struct device *dev),
>> +
>> +     TP_ARGS(dmabuf, attach, is_dynamic, dev)
>> +);
>> +
>> +DEFINE_EVENT(dma_buf_attach_dev, dma_buf_detach,
>> +
>> +     TP_PROTO(struct dma_buf *dmabuf, struct dma_buf_attachment *attach, bool is_dynamic, struct device *dev),
>> +
>> +     TP_ARGS(dmabuf, attach, is_dynamic, dev)
>> +);
>> +
>> +DEFINE_EVENT(dma_buf_fd, dma_buf_fd,
>> +
>> +     TP_PROTO(struct dma_buf *dmabuf, int fd),
>> +
>> +     TP_ARGS(dmabuf, fd)
>> +);
>> +
>> +DEFINE_EVENT(dma_buf_fd, dma_buf_get,
>> +
>> +     TP_PROTO(struct dma_buf *dmabuf, int fd),
>> +
>> +     TP_ARGS(dmabuf, fd)
>> +);
>> +
>> +#endif /* _TRACE_DMA_BUF_H */
>> +
>> +/* This part must be outside protection */
>> +#include <trace/define_trace.h>
> 


^ permalink raw reply

* Re: [PATCH 3/3] mm/khugepaged: make khugepaged_collapse_control static
From: Zi Yan @ 2025-12-16 15:39 UTC (permalink / raw)
  To: Shivank Garg
  Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Baolin Wang,
	Liam R . Howlett, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
	Lance Yang, linux-mm, linux-kernel, linux-trace-kernel
In-Reply-To: <20251216111139.95438-8-shivankg@amd.com>

On 16 Dec 2025, at 6:11, Shivank Garg wrote:

> The global variable 'khugepaged_collapse_control' is not used outside of
> mm/khugepaged.c. Make it static to limit its scope.
>
> Signed-off-by: Shivank Garg <shivankg@amd.com>
> ---
>  mm/khugepaged.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
LGTM. Reviewed-by: Zi Yan <ziy@nvidia.com>

Best Regards,
Yan, Zi

^ permalink raw reply

* Re: [PATCH 2/3] mm/khugepaged: use enum scan_result for result variables
From: Zi Yan @ 2025-12-16 15:38 UTC (permalink / raw)
  To: Shivank Garg
  Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Baolin Wang,
	Liam R . Howlett, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
	Lance Yang, linux-mm, linux-kernel, linux-trace-kernel
In-Reply-To: <20251216111139.95438-6-shivankg@amd.com>

On 16 Dec 2025, at 6:11, Shivank Garg wrote:

> Use enum scan_result for local variables and the result pointer in
> khugepaged_scan_mm_slot(), instead of plain int. This improves code
> readability and clarifies intent,
>
> No functional change.
>
> Signed-off-by: Shivank Garg <shivankg@amd.com>
> ---
>  mm/khugepaged.c | 29 ++++++++++++++++-------------
>  1 file changed, 16 insertions(+), 13 deletions(-)
>
> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> index 107146f012b1..65b1b778378a 100644
> --- a/mm/khugepaged.c
> +++ b/mm/khugepaged.c
> @@ -547,7 +547,8 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,

The return type could be changed too.

>  	struct folio *folio = NULL;
>  	unsigned long addr = start_addr;
>  	pte_t *_pte;
> -	int none_or_zero = 0, shared = 0, result = SCAN_FAIL, referenced = 0;
> +	int none_or_zero = 0, shared = 0, referenced = 0;
> +	enum scan_result result = SCAN_FAIL;
>
>  	for (_pte = pte; _pte < pte + HPAGE_PMD_NR;
>  	     _pte++, addr += PAGE_SIZE) {
> @@ -786,7 +787,7 @@ static int __collapse_huge_page_copy(pte_t *pte, struct folio *folio,

Ditto.

>  		struct list_head *compound_pagelist)
>  {
>  	unsigned int i;
> -	int result = SCAN_SUCCEED;
> +	enum scan_result result = SCAN_SUCCEED;
>
>  	/*
>  	 * Copying pages' contents is subject to memory poison at any iteration.
> @@ -969,7 +970,7 @@ static int check_pmd_still_valid(struct mm_struct *mm,
>  				 pmd_t *pmd)

Ditto.

>  {
>  	pmd_t *new_pmd;
> -	int result = find_pmd_or_thp_or_none(mm, address, &new_pmd);
> +	enum scan_result result = find_pmd_or_thp_or_none(mm, address, &new_pmd);
>
>  	if (result != SCAN_SUCCEED)
>  		return result;
> @@ -993,7 +994,7 @@ static int __collapse_huge_page_swapin(struct mm_struct *mm,

Ditto.

>  	int swapped_in = 0;
>  	vm_fault_t ret = 0;
>  	unsigned long addr, end = start_addr + (HPAGE_PMD_NR * PAGE_SIZE);
> -	int result;
> +	enum scan_result result;
>  	pte_t *pte = NULL;
>  	spinlock_t *ptl;
>
> @@ -1100,7 +1101,7 @@ static int collapse_huge_page(struct mm_struct *mm, unsigned long address,

Ditto.

>  	pgtable_t pgtable;
>  	struct folio *folio;
>  	spinlock_t *pmd_ptl, *pte_ptl;
> -	int result = SCAN_FAIL;
> +	enum scan_result result = SCAN_FAIL;
>  	struct vm_area_struct *vma;
>  	struct mmu_notifier_range range;
>
> @@ -1253,8 +1254,8 @@ static int hpage_collapse_scan_pmd(struct mm_struct *mm,
>  {
Ditto.

>  	pmd_t *pmd;
>  	pte_t *pte, *_pte;
> -	int result = SCAN_FAIL, referenced = 0;
> -	int none_or_zero = 0, shared = 0;
> +	int none_or_zero = 0, shared = 0, referenced = 0;
> +	enum scan_result result = SCAN_FAIL;
>  	struct page *page = NULL;
>  	struct folio *folio = NULL;
>  	unsigned long addr;
> @@ -1492,7 +1493,8 @@ static int set_huge_pmd(struct vm_area_struct *vma, unsigned long addr,

Same here.

>  int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
>  			    bool install_pmd)
>  {

And here.

> -	int nr_mapped_ptes = 0, result = SCAN_FAIL;
> +	enum scan_result result = SCAN_FAIL;
> +	int nr_mapped_ptes = 0;
>  	unsigned int nr_batch_ptes;
>  	struct mmu_notifier_range range;
>  	bool notified = false;
> @@ -1866,7 +1868,8 @@ static int collapse_file(struct mm_struct *mm, unsigned long addr,

Same here.

>  	pgoff_t index = 0, end = start + HPAGE_PMD_NR;
>  	LIST_HEAD(pagelist);
>  	XA_STATE_ORDER(xas, &mapping->i_pages, start, HPAGE_PMD_ORDER);
> -	int nr_none = 0, result = SCAN_SUCCEED;
> +	enum scan_result result = SCAN_SUCCEED;
> +	int nr_none = 0;
>  	bool is_shmem = shmem_file(file);
>
>  	VM_BUG_ON(!IS_ENABLED(CONFIG_READ_ONLY_THP_FOR_FS) && !is_shmem);
> @@ -2296,7 +2299,7 @@ static int hpage_collapse_scan_file(struct mm_struct *mm, unsigned long addr,

Same here.

>  	XA_STATE(xas, &mapping->i_pages, start);
>  	int present, swap;
>  	int node = NUMA_NO_NODE;
> -	int result = SCAN_SUCCEED;
> +	enum scan_result result = SCAN_SUCCEED;
>
>  	present = 0;
>  	swap = 0;
> @@ -2394,7 +2397,7 @@ static int hpage_collapse_scan_file(struct mm_struct *mm, unsigned long addr,
>  	return result;
>  }
>
> -static unsigned int khugepaged_scan_mm_slot(unsigned int pages, int *result,
> +static unsigned int khugepaged_scan_mm_slot(unsigned int pages, enum scan_result *result,
>  					    struct collapse_control *cc)
>  	__releases(&khugepaged_mm_lock)
>  	__acquires(&khugepaged_mm_lock)
> @@ -2555,7 +2558,7 @@ static void khugepaged_do_scan(struct collapse_control *cc)
>  	unsigned int progress = 0, pass_through_head = 0;
>  	unsigned int pages = READ_ONCE(khugepaged_pages_to_scan);
>  	bool wait = true;
> -	int result = SCAN_SUCCEED;
> +	enum scan_result result = SCAN_SUCCEED;
>
>  	lru_add_drain_all();
>
> @@ -2790,7 +2793,7 @@ int madvise_collapse(struct vm_area_struct *vma, unsigned long start,
>
>  	for (addr = hstart; addr < hend; addr += HPAGE_PMD_SIZE) {
>  		bool retried = false;
> -		int result = SCAN_FAIL;
> +		enum scan_result result = SCAN_FAIL;
>
>  		if (!mmap_locked) {
>  retry:
> -- 

In addition, the return types of find_pmd_or_thp_or_none(),
hugepage_vma_revalidate(), alloc_charge_folio(), and check_pmd_state() need to be changed to enum scan_result too.

Best Regards,
Yan, Zi

^ permalink raw reply

* Re: [PATCH v4 3/7] rtla/timerlat: Add example for BPF action program
From: Tomas Glozar @ 2025-12-16 15:28 UTC (permalink / raw)
  To: Wander Lairson Costa
  Cc: Steven Rostedt, LKML, Linux Trace Kernel, John Kacur,
	Luis Goncalves, Costa Shulyupin, Crystal Wood,
	Arnaldo Carvalho de Melo
In-Reply-To: <yha47my7tmcu5yvbwelst32ipectzkhekxdorgpxws463kxsno@fcw5vv674yo6>

út 16. 12. 2025 v 16:22 odesílatel Wander Lairson Costa
<wander@redhat.com> napsal:
>
> I couldn't understand the need for the `filter` function.
>

Oh that is copied from stalld, where the dependency list includes .h
header files. See our discussion from before [1], I promised to remove
it but forgot about it while doing the rebase.

[1] https://lore.kernel.org/linux-trace-kernel/CAP4=nvSJq1kOUvBRwy_5Fh_FX=Qx-=xiRfngSyky1eVdZsGrrg@mail.gmail.com/

Tomas


^ permalink raw reply

* Re: [PATCH 1/3] mm/khugepaged: remove unnecessary goto 'skip' label
From: Zi Yan @ 2025-12-16 15:27 UTC (permalink / raw)
  To: Shivank Garg
  Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Baolin Wang,
	Liam R . Howlett, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
	Lance Yang, linux-mm, linux-kernel, linux-trace-kernel
In-Reply-To: <20251216111139.95438-4-shivankg@amd.com>

On 16 Dec 2025, at 6:11, Shivank Garg wrote:

> Replace 'goto skip' with actual logic for better code readability.
>
> No functional change.
>
> Signed-off-by: Shivank Garg <shivankg@amd.com>
> ---
>  mm/khugepaged.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
LGTM. Reviewed-by: Zi Yan <ziy@nvidia.com>

Best Regards,
Yan, Zi

^ permalink raw reply

* Re: [PATCH v4 3/7] rtla/timerlat: Add example for BPF action program
From: Wander Lairson Costa @ 2025-12-16 15:22 UTC (permalink / raw)
  To: Tomas Glozar
  Cc: Steven Rostedt, LKML, Linux Trace Kernel, John Kacur,
	Luis Goncalves, Costa Shulyupin, Crystal Wood,
	Arnaldo Carvalho de Melo
In-Reply-To: <20251126144205.331954-4-tglozar@redhat.com>

On Wed, Nov 26, 2025 at 03:42:01PM +0100, Tomas Glozar wrote:
> Add an example BPF action program that prints the measured latency to
> the tracefs buffer via bpf_printk().
> 
> A new Makefile target, "examples", is added to build the example. In
> addition, "sample/" subfolder is renamed to "example".
> 
> If BPF skeleton support is unavailable or disabled, a warning will be
> displayed when building the BPF action program example.
> 
> Signed-off-by: Tomas Glozar <tglozar@redhat.com>
> ---
>  tools/tracing/rtla/Makefile                      |  9 ++++++++-
>  tools/tracing/rtla/example/timerlat_bpf_action.c | 16 ++++++++++++++++
>  .../rtla/{sample => example}/timerlat_load.py    |  0
>  3 files changed, 24 insertions(+), 1 deletion(-)
>  create mode 100644 tools/tracing/rtla/example/timerlat_bpf_action.c
>  rename tools/tracing/rtla/{sample => example}/timerlat_load.py (100%)
> 
> diff --git a/tools/tracing/rtla/Makefile b/tools/tracing/rtla/Makefile
> index 746ccf2f5808..5f1529ce3693 100644
> --- a/tools/tracing/rtla/Makefile
> +++ b/tools/tracing/rtla/Makefile
> @@ -73,9 +73,15 @@ src/timerlat.bpf.o: src/timerlat.bpf.c
>  
>  src/timerlat.skel.h: src/timerlat.bpf.o
>  	$(QUIET_GENSKEL)$(SYSTEM_BPFTOOL) gen skeleton $< > $@
> +
> +example/timerlat_bpf_action.o: example/timerlat_bpf_action.c
> +	$(QUIET_CLANG)$(CLANG) -g -O2 -target bpf -c $(filter %.c,$^) -o $@

I couldn't understand the need for the `filter` function.

>  else
>  src/timerlat.skel.h:
>  	$(Q)echo '/* BPF skeleton is disabled */' > src/timerlat.skel.h
> +
> +example/timerlat_bpf_action.o: example/timerlat_bpf_action.c
> +	$(Q)echo "BPF skeleton support is disabled, skipping example/timerlat_bpf_action.o"
>  endif
>  
>  $(RTLA): $(RTLA_IN)
> @@ -96,7 +102,8 @@ clean: doc_clean fixdep-clean
>  	$(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
>  	$(Q)rm -f rtla rtla-static fixdep FEATURE-DUMP rtla-*
>  	$(Q)rm -rf feature
> -	$(Q)rm -f src/timerlat.bpf.o src/timerlat.skel.h
> +	$(Q)rm -f src/timerlat.bpf.o src/timerlat.skel.h example/timerlat_bpf_action.o
>  check: $(RTLA)
>  	RTLA=$(RTLA) prove -o -f tests/
> +examples: example/timerlat_bpf_action.o
>  .PHONY: FORCE clean check
> diff --git a/tools/tracing/rtla/example/timerlat_bpf_action.c b/tools/tracing/rtla/example/timerlat_bpf_action.c
> new file mode 100644
> index 000000000000..ac1be049a848
> --- /dev/null
> +++ b/tools/tracing/rtla/example/timerlat_bpf_action.c
> @@ -0,0 +1,16 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <linux/bpf.h>
> +#include <bpf/bpf_tracing.h>
> +
> +char LICENSE[] SEC("license") = "GPL";
> +
> +struct trace_event_raw_timerlat_sample {
> +	unsigned long long timer_latency;
> +} __attribute__((preserve_access_index));
> +
> +SEC("tp/timerlat_action")
> +int action_handler(struct trace_event_raw_timerlat_sample *tp_args)
> +{
> +	bpf_printk("Latency: %lld\n", tp_args->timer_latency);
> +	return 0;
> +}
> diff --git a/tools/tracing/rtla/sample/timerlat_load.py b/tools/tracing/rtla/example/timerlat_load.py
> similarity index 100%
> rename from tools/tracing/rtla/sample/timerlat_load.py
> rename to tools/tracing/rtla/example/timerlat_load.py
> -- 
> 2.51.1
> 


^ permalink raw reply

* Re: [PATCH v1 1/4] tools/rtla: Consolidate nr_cpus usage across all tools
From: Tomas Glozar @ 2025-12-16 14:41 UTC (permalink / raw)
  To: Costa Shulyupin
  Cc: Steven Rostedt, Crystal Wood, Wander Lairson Costa, Ivan Pravdin,
	John Kacur, Tiezhu Yang, linux-trace-kernel, linux-kernel, bpf
In-Reply-To: <20251205151924.2250142-1-costa.shul@redhat.com>

pá 5. 12. 2025 v 16:19 odesílatel Costa Shulyupin
<costa.shul@redhat.com> napsal:
> diff --git a/tools/tracing/rtla/src/timerlat_u.c b/tools/tracing/rtla/src/timerlat_u.c
> index ce68e39d25fd..a569fe7f93aa 100644
> --- a/tools/tracing/rtla/src/timerlat_u.c
> +++ b/tools/tracing/rtla/src/timerlat_u.c
> @@ -16,7 +16,7 @@
>  #include <sys/wait.h>
>  #include <sys/prctl.h>
>
> -#include "utils.h"
> +#include "common.h"
>  #include "timerlat_u.h"
>

Since commit 2f3172f9dd58c ("tools/rtla: Consolidate code between
osnoise/timerlat and hist/top") that was merged into 6.18, common.h
includes timerlat_u.h. Your change thus causes a double include of
timerlat_u.h, leading to a build error:

In file included from src/timerlat_u.c:20:
src/timerlat_u.h:6:8: error: redefinition of ‘struct timerlat_u_params’
   6 | struct timerlat_u_params {
     |        ^~~~~~~~~~~~~~~~~
In file included from src/common.h:5,
                from src/timerlat_u.c:19:
src/timerlat_u.h:6:8: note: originally defined here
   6 | struct timerlat_u_params {
     |        ^~~~~~~~~~~~~~~~~

Please rebase your patchset and fix this so that timerlat_u.h is only
included once.

Tomas


^ permalink raw reply

* [PATCH v2 2/2] mm: vmscan: add PIDs to vmscan tracepoints
From: Thomas Ballasi @ 2025-12-16 14:02 UTC (permalink / raw)
  To: Steven Rostedt, Masami Hiramatsu, Andrew Morton
  Cc: linux-mm, linux-trace-kernel
In-Reply-To: <20251216140252.11864-1-tballasi@linux.microsoft.com>

The changes aims at adding additionnal tracepoints variables to help
debuggers attribute them to specific processes.

The PID field uses in_task() to reliably detect when we're in process
context and can safely access current->pid.  When not in process
context (such as in interrupt or in an asynchronous RCU context), the
field is set to -1 as a sentinel value.

Signed-off-by: Thomas Ballasi <tballasi@linux.microsoft.com>
---
 include/trace/events/vmscan.h | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h
index afc9f80d03f34..315725f30b504 100644
--- a/include/trace/events/vmscan.h
+++ b/include/trace/events/vmscan.h
@@ -120,19 +120,22 @@ DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template,
 
 	TP_STRUCT__entry(
 		__field(	int,	order		)
+		__field(	int,	pid		)
 		__field(	unsigned long,	gfp_flags	)
 		__field(	unsigned short,	memcg_id	)
 	),
 
 	TP_fast_assign(
 		__entry->order		= order;
+		__entry->pid		= in_task() ? current->pid : -1;
 		__entry->gfp_flags	= (__force unsigned long)gfp_flags;
 		__entry->memcg_id	= memcg_id;
 	),
 
-	TP_printk("order=%d gfp_flags=%s memcg_id=%u",
+	TP_printk("order=%d gfp_flags=%s pid=%d memcg_id=%u",
 		__entry->order,
 		show_gfp_flags(__entry->gfp_flags),
+		__entry->pid,
 		__entry->memcg_id)
 );
 
@@ -167,16 +170,19 @@ DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template,
 
 	TP_STRUCT__entry(
 		__field(	unsigned long,	nr_reclaimed	)
+		__field(	int,	pid		)
 		__field(	unsigned short,	memcg_id	)
 	),
 
 	TP_fast_assign(
 		__entry->nr_reclaimed	= nr_reclaimed;
+		__entry->pid		= in_task() ? current->pid : -1;
 		__entry->memcg_id	= memcg_id;
 	),
 
-	TP_printk("nr_reclaimed=%lu memcg_id=%u",
+	TP_printk("nr_reclaimed=%lu pid=%d memcg_id=%u",
 		__entry->nr_reclaimed,
+		__entry->pid,
 		__entry->memcg_id)
 );
 
@@ -216,6 +222,7 @@ TRACE_EVENT(mm_shrink_slab_start,
 		__field(struct shrinker *, shr)
 		__field(void *, shrink)
 		__field(int, nid)
+		__field(int, pid)
 		__field(unsigned short, memcg_id)
 		__field(long, nr_objects_to_shrink)
 		__field(unsigned long, gfp_flags)
@@ -229,6 +236,7 @@ TRACE_EVENT(mm_shrink_slab_start,
 		__entry->shr = shr;
 		__entry->shrink = shr->scan_objects;
 		__entry->nid = sc->nid;
+		__entry->pid = in_task() ? current->pid : -1;
 		__entry->memcg_id = sc->memcg ? mem_cgroup_id(sc->memcg) : 0;
 		__entry->nr_objects_to_shrink = nr_objects_to_shrink;
 		__entry->gfp_flags = (__force unsigned long)sc->gfp_mask;
@@ -238,10 +246,11 @@ TRACE_EVENT(mm_shrink_slab_start,
 		__entry->priority = priority;
 	),
 
-	TP_printk("%pS %p: nid: %d memcg_id: %u objects to shrink %ld gfp_flags %s cache items %ld delta %lld total_scan %ld priority %d",
+	TP_printk("%pS %p: nid: %d pid: %d memcg_id: %u objects to shrink %ld gfp_flags %s cache items %ld delta %lld total_scan %ld priority %d",
 		__entry->shrink,
 		__entry->shr,
 		__entry->nid,
+		__entry->pid,
 		__entry->memcg_id,
 		__entry->nr_objects_to_shrink,
 		show_gfp_flags(__entry->gfp_flags),
@@ -261,6 +270,7 @@ TRACE_EVENT(mm_shrink_slab_end,
 	TP_STRUCT__entry(
 		__field(struct shrinker *, shr)
 		__field(int, nid)
+		__field(int, pid)
 		__field(unsigned short, memcg_id)
 		__field(void *, shrink)
 		__field(long, unused_scan)
@@ -272,6 +282,7 @@ TRACE_EVENT(mm_shrink_slab_end,
 	TP_fast_assign(
 		__entry->shr = shr;
 		__entry->nid = sc->nid;
+		__entry->pid = in_task() ? current->pid : -1;
 		__entry->memcg_id = sc->memcg ? mem_cgroup_id(sc->memcg) : 0;
 		__entry->shrink = shr->scan_objects;
 		__entry->unused_scan = unused_scan_cnt;
@@ -280,10 +291,11 @@ TRACE_EVENT(mm_shrink_slab_end,
 		__entry->total_scan = total_scan;
 	),
 
-	TP_printk("%pS %p: nid: %d memcg_id: %u unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d",
+	TP_printk("%pS %p: nid: %d pid: %d memcg_id: %u unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d",
 		__entry->shrink,
 		__entry->shr,
 		__entry->nid,
+		__entry->pid,
 		__entry->memcg_id,
 		__entry->unused_scan,
 		__entry->new_scan,
-- 
2.33.8


^ permalink raw reply related

* [PATCH v2 1/2] mm: vmscan: add cgroup IDs to vmscan tracepoints
From: Thomas Ballasi @ 2025-12-16 14:02 UTC (permalink / raw)
  To: Steven Rostedt, Masami Hiramatsu, Andrew Morton
  Cc: linux-mm, linux-trace-kernel
In-Reply-To: <20251216140252.11864-1-tballasi@linux.microsoft.com>

Memory reclaim events are currently difficult to attribute to
specific cgroups, making debugging memory pressure issues
challenging.  This patch adds memory cgroup ID (memcg_id) to key
vmscan tracepoints to enable better correlation and analysis.

For operations not associated with a specific cgroup, the field
is defaulted to 0.

Signed-off-by: Thomas Ballasi <tballasi@linux.microsoft.com>
---
 include/trace/events/vmscan.h | 65 +++++++++++++++++++++--------------
 mm/vmscan.c                   | 17 ++++-----
 2 files changed, 48 insertions(+), 34 deletions(-)

diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h
index d2123dd960d59..afc9f80d03f34 100644
--- a/include/trace/events/vmscan.h
+++ b/include/trace/events/vmscan.h
@@ -114,85 +114,92 @@ TRACE_EVENT(mm_vmscan_wakeup_kswapd,
 
 DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template,
 
-	TP_PROTO(int order, gfp_t gfp_flags),
+	TP_PROTO(int order, gfp_t gfp_flags, unsigned short memcg_id),
 
-	TP_ARGS(order, gfp_flags),
+	TP_ARGS(order, gfp_flags, memcg_id),
 
 	TP_STRUCT__entry(
 		__field(	int,	order		)
 		__field(	unsigned long,	gfp_flags	)
+		__field(	unsigned short,	memcg_id	)
 	),
 
 	TP_fast_assign(
 		__entry->order		= order;
 		__entry->gfp_flags	= (__force unsigned long)gfp_flags;
+		__entry->memcg_id	= memcg_id;
 	),
 
-	TP_printk("order=%d gfp_flags=%s",
+	TP_printk("order=%d gfp_flags=%s memcg_id=%u",
 		__entry->order,
-		show_gfp_flags(__entry->gfp_flags))
+		show_gfp_flags(__entry->gfp_flags),
+		__entry->memcg_id)
 );
 
 DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_direct_reclaim_begin,
 
-	TP_PROTO(int order, gfp_t gfp_flags),
+	TP_PROTO(int order, gfp_t gfp_flags, unsigned short memcg_id),
 
-	TP_ARGS(order, gfp_flags)
+	TP_ARGS(order, gfp_flags, memcg_id)
 );
 
 #ifdef CONFIG_MEMCG
 DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_reclaim_begin,
 
-	TP_PROTO(int order, gfp_t gfp_flags),
+	TP_PROTO(int order, gfp_t gfp_flags, unsigned short memcg_id),
 
-	TP_ARGS(order, gfp_flags)
+	TP_ARGS(order, gfp_flags, memcg_id)
 );
 
 DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_softlimit_reclaim_begin,
 
-	TP_PROTO(int order, gfp_t gfp_flags),
+	TP_PROTO(int order, gfp_t gfp_flags, unsigned short memcg_id),
 
-	TP_ARGS(order, gfp_flags)
+	TP_ARGS(order, gfp_flags, memcg_id)
 );
 #endif /* CONFIG_MEMCG */
 
 DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template,
 
-	TP_PROTO(unsigned long nr_reclaimed),
+	TP_PROTO(unsigned long nr_reclaimed, unsigned short memcg_id),
 
-	TP_ARGS(nr_reclaimed),
+	TP_ARGS(nr_reclaimed, memcg_id),
 
 	TP_STRUCT__entry(
 		__field(	unsigned long,	nr_reclaimed	)
+		__field(	unsigned short,	memcg_id	)
 	),
 
 	TP_fast_assign(
 		__entry->nr_reclaimed	= nr_reclaimed;
+		__entry->memcg_id	= memcg_id;
 	),
 
-	TP_printk("nr_reclaimed=%lu", __entry->nr_reclaimed)
+	TP_printk("nr_reclaimed=%lu memcg_id=%u",
+		__entry->nr_reclaimed,
+		__entry->memcg_id)
 );
 
 DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_direct_reclaim_end,
 
-	TP_PROTO(unsigned long nr_reclaimed),
+	TP_PROTO(unsigned long nr_reclaimed, unsigned short memcg_id),
 
-	TP_ARGS(nr_reclaimed)
+	TP_ARGS(nr_reclaimed, memcg_id)
 );
 
 #ifdef CONFIG_MEMCG
 DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_reclaim_end,
 
-	TP_PROTO(unsigned long nr_reclaimed),
+	TP_PROTO(unsigned long nr_reclaimed, unsigned short memcg_id),
 
-	TP_ARGS(nr_reclaimed)
+	TP_ARGS(nr_reclaimed, memcg_id)
 );
 
 DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_reclaim_end,
 
-	TP_PROTO(unsigned long nr_reclaimed),
+	TP_PROTO(unsigned long nr_reclaimed, unsigned short memcg_id),
 
-	TP_ARGS(nr_reclaimed)
+	TP_ARGS(nr_reclaimed, memcg_id)
 );
 #endif /* CONFIG_MEMCG */
 
@@ -209,6 +216,7 @@ TRACE_EVENT(mm_shrink_slab_start,
 		__field(struct shrinker *, shr)
 		__field(void *, shrink)
 		__field(int, nid)
+		__field(unsigned short, memcg_id)
 		__field(long, nr_objects_to_shrink)
 		__field(unsigned long, gfp_flags)
 		__field(unsigned long, cache_items)
@@ -221,6 +229,7 @@ TRACE_EVENT(mm_shrink_slab_start,
 		__entry->shr = shr;
 		__entry->shrink = shr->scan_objects;
 		__entry->nid = sc->nid;
+		__entry->memcg_id = sc->memcg ? mem_cgroup_id(sc->memcg) : 0;
 		__entry->nr_objects_to_shrink = nr_objects_to_shrink;
 		__entry->gfp_flags = (__force unsigned long)sc->gfp_mask;
 		__entry->cache_items = cache_items;
@@ -229,10 +238,11 @@ TRACE_EVENT(mm_shrink_slab_start,
 		__entry->priority = priority;
 	),
 
-	TP_printk("%pS %p: nid: %d objects to shrink %ld gfp_flags %s cache items %ld delta %lld total_scan %ld priority %d",
+	TP_printk("%pS %p: nid: %d memcg_id: %u objects to shrink %ld gfp_flags %s cache items %ld delta %lld total_scan %ld priority %d",
 		__entry->shrink,
 		__entry->shr,
 		__entry->nid,
+		__entry->memcg_id,
 		__entry->nr_objects_to_shrink,
 		show_gfp_flags(__entry->gfp_flags),
 		__entry->cache_items,
@@ -242,15 +252,16 @@ TRACE_EVENT(mm_shrink_slab_start,
 );
 
 TRACE_EVENT(mm_shrink_slab_end,
-	TP_PROTO(struct shrinker *shr, int nid, int shrinker_retval,
+	TP_PROTO(struct shrinker *shr, struct shrink_control *sc, int shrinker_retval,
 		long unused_scan_cnt, long new_scan_cnt, long total_scan),
 
-	TP_ARGS(shr, nid, shrinker_retval, unused_scan_cnt, new_scan_cnt,
+	TP_ARGS(shr, sc, shrinker_retval, unused_scan_cnt, new_scan_cnt,
 		total_scan),
 
 	TP_STRUCT__entry(
 		__field(struct shrinker *, shr)
 		__field(int, nid)
+		__field(unsigned short, memcg_id)
 		__field(void *, shrink)
 		__field(long, unused_scan)
 		__field(long, new_scan)
@@ -260,7 +271,8 @@ TRACE_EVENT(mm_shrink_slab_end,
 
 	TP_fast_assign(
 		__entry->shr = shr;
-		__entry->nid = nid;
+		__entry->nid = sc->nid;
+		__entry->memcg_id = sc->memcg ? mem_cgroup_id(sc->memcg) : 0;
 		__entry->shrink = shr->scan_objects;
 		__entry->unused_scan = unused_scan_cnt;
 		__entry->new_scan = new_scan_cnt;
@@ -268,10 +280,11 @@ TRACE_EVENT(mm_shrink_slab_end,
 		__entry->total_scan = total_scan;
 	),
 
-	TP_printk("%pS %p: nid: %d unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d",
+	TP_printk("%pS %p: nid: %d memcg_id: %u unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d",
 		__entry->shrink,
 		__entry->shr,
 		__entry->nid,
+		__entry->memcg_id,
 		__entry->unused_scan,
 		__entry->new_scan,
 		__entry->total_scan,
@@ -463,9 +476,9 @@ TRACE_EVENT(mm_vmscan_node_reclaim_begin,
 
 DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_node_reclaim_end,
 
-	TP_PROTO(unsigned long nr_reclaimed),
+	TP_PROTO(unsigned long nr_reclaimed, unsigned short memcg_id),
 
-	TP_ARGS(nr_reclaimed)
+	TP_ARGS(nr_reclaimed, memcg_id)
 );
 
 TRACE_EVENT(mm_vmscan_throttled,
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 258f5472f1e90..0e65ec3a087a5 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -931,7 +931,7 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
 	 */
 	new_nr = add_nr_deferred(next_deferred, shrinker, shrinkctl);
 
-	trace_mm_shrink_slab_end(shrinker, shrinkctl->nid, freed, nr, new_nr, total_scan);
+	trace_mm_shrink_slab_end(shrinker, shrinkctl, freed, nr, new_nr, total_scan);
 	return freed;
 }
 
@@ -7092,11 +7092,11 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
 		return 1;
 
 	set_task_reclaim_state(current, &sc.reclaim_state);
-	trace_mm_vmscan_direct_reclaim_begin(order, sc.gfp_mask);
+	trace_mm_vmscan_direct_reclaim_begin(order, sc.gfp_mask, 0);
 
 	nr_reclaimed = do_try_to_free_pages(zonelist, &sc);
 
-	trace_mm_vmscan_direct_reclaim_end(nr_reclaimed);
+	trace_mm_vmscan_direct_reclaim_end(nr_reclaimed, 0);
 	set_task_reclaim_state(current, NULL);
 
 	return nr_reclaimed;
@@ -7126,7 +7126,8 @@ unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg,
 			(GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK);
 
 	trace_mm_vmscan_memcg_softlimit_reclaim_begin(sc.order,
-						      sc.gfp_mask);
+						      sc.gfp_mask,
+						      mem_cgroup_id(memcg));
 
 	/*
 	 * NOTE: Although we can get the priority field, using it
@@ -7137,7 +7138,7 @@ unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg,
 	 */
 	shrink_lruvec(lruvec, &sc);
 
-	trace_mm_vmscan_memcg_softlimit_reclaim_end(sc.nr_reclaimed);
+	trace_mm_vmscan_memcg_softlimit_reclaim_end(sc.nr_reclaimed, mem_cgroup_id(memcg));
 
 	*nr_scanned = sc.nr_scanned;
 
@@ -7171,13 +7172,13 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
 	struct zonelist *zonelist = node_zonelist(numa_node_id(), sc.gfp_mask);
 
 	set_task_reclaim_state(current, &sc.reclaim_state);
-	trace_mm_vmscan_memcg_reclaim_begin(0, sc.gfp_mask);
+	trace_mm_vmscan_memcg_reclaim_begin(0, sc.gfp_mask, mem_cgroup_id(memcg));
 	noreclaim_flag = memalloc_noreclaim_save();
 
 	nr_reclaimed = do_try_to_free_pages(zonelist, &sc);
 
 	memalloc_noreclaim_restore(noreclaim_flag);
-	trace_mm_vmscan_memcg_reclaim_end(nr_reclaimed);
+	trace_mm_vmscan_memcg_reclaim_end(nr_reclaimed, mem_cgroup_id(memcg));
 	set_task_reclaim_state(current, NULL);
 
 	return nr_reclaimed;
@@ -8072,7 +8073,7 @@ static int __node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned in
 	fs_reclaim_release(sc.gfp_mask);
 	psi_memstall_leave(&pflags);
 
-	trace_mm_vmscan_node_reclaim_end(sc.nr_reclaimed);
+	trace_mm_vmscan_node_reclaim_end(sc.nr_reclaimed, 0);
 
 	return sc.nr_reclaimed >= nr_pages;
 }
-- 
2.33.8


^ permalink raw reply related

* [PATCH v2 0/2] mm: vmscan: add PID and cgroup ID to vmscan tracepoints
From: Thomas Ballasi @ 2025-12-16 14:02 UTC (permalink / raw)
  To: Steven Rostedt, Masami Hiramatsu, Andrew Morton
  Cc: linux-mm, linux-trace-kernel
In-Reply-To: <20251208181413.4722-1-tballasi@linux.microsoft.com>

Changes in v2:
- Swapped field entries to prevent a hole in the ring buffer

Link to v1:
https://lore.kernel.org/linux-trace-kernel/20251208181413.4722-1-tballasi@linux.microsoft.com/

Signed-off-by: Thomas Ballasi <tballasi@linux.microsoft.com>

Thomas Ballasi (2):
  mm: vmscan: add cgroup IDs to vmscan tracepoints
  mm: vmscan: add PIDs to vmscan tracepoints

 include/trace/events/vmscan.h | 77 +++++++++++++++++++++++------------
 mm/vmscan.c                   | 17 ++++----
 2 files changed, 60 insertions(+), 34 deletions(-)

-- 
2.33.8


^ permalink raw reply

* Re: [PATCH v3 0/7] kallsyms: Prevent invalid access when showing module buildid
From: Petr Mladek @ 2025-12-16 14:00 UTC (permalink / raw)
  To: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
	Kees Cook
  Cc: Aaron Tomlin, Daniel Borkmann, John Fastabend, Masami Hiramatsu,
	Mark Rutland, Luis Chamberlain, Daniel Gomez, Sami Tolvanen,
	linux-kernel, bpf, linux-modules, linux-trace-kernel
In-Reply-To: <20251128135920.217303-1-pmladek@suse.com>

Hi,

I wonder who could take this patchset.

IMHO, the failed test report is bogus. The system went out of memory.
Anyway, the info provided by the mail is not enough for debugging.

IMHO. this patchset is ready for linux-next. Unfortunately, kallsyms
do not have any dedicated maintainer. I though about Kees (hardening)
or Andrew (core stuff). Or I could take it via printk tree.

Best Regards,
Petr

On Fri 2025-11-28 14:59:13, Petr Mladek wrote:
> This patchset is cleaning up kallsyms code related to module buildid.
> It is fixing an invalid access when printing backtraces, see [v1] for
> more details:
> 
>   + 1st..4th patches are preparatory.
> 
>   + 5th and 6th patches are fixing bpf and ftrace related APIs.
> 
>   + 7th patch prevents a potential race.
> 
> 
> Changes against [v2]:
> 
>   + Fixed typos in commit message [Alexei]
> 
>   + Added Acks [Alexei]
> 
> 
> Changes against [v1]:
> 
>   + Added existing Reviewed-by tags.
> 
>   + Shuffled patches to update the kallsyms_lookup_buildid() initialization
>     code 1st.
> 
>   + Initialized also *modname and *modbuildid in kallsyms_lookup_buildid().
> 
>   + Renamed __bpf_address_lookup() to bpf_address_lookup() and used it
>     in kallsyms_lookup_buildid(). Did this instead of passing @modbuildid
>     parameter just to clear it.
> 
> 
> [v1] https://lore.kernel.org/r/20251105142319.1139183-1-pmladek@suse.com
> [v2] https://lore.kernel.org/r/20251112142003.182062-1-pmladek@suse.com
> 
> 
> Petr Mladek (7):
>   kallsyms: Clean up @namebuf initialization in
>     kallsyms_lookup_buildid()
>   kallsyms: Clean up modname and modbuildid initialization in
>     kallsyms_lookup_buildid()
>   module: Add helper function for reading module_buildid()
>   kallsyms: Cleanup code for appending the module buildid
>   kallsyms/bpf: Rename __bpf_address_lookup() to bpf_address_lookup()
>   kallsyms/ftrace: Set module buildid in ftrace_mod_address_lookup()
>   kallsyms: Prevent module removal when printing module name and buildid
> 
>  arch/arm64/net/bpf_jit_comp.c   |  2 +-
>  arch/powerpc/net/bpf_jit_comp.c |  2 +-
>  include/linux/filter.h          | 26 ++----------
>  include/linux/ftrace.h          |  6 ++-
>  include/linux/module.h          |  9 ++++
>  kernel/bpf/core.c               |  4 +-
>  kernel/kallsyms.c               | 73 ++++++++++++++++++++++++---------
>  kernel/module/kallsyms.c        |  9 +---
>  kernel/trace/ftrace.c           |  5 ++-
>  9 files changed, 81 insertions(+), 55 deletions(-)
> 
> -- 
> 2.52.0

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox