From nobody Mon Dec 1 21:31:22 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5D9511713 for ; Fri, 28 Nov 2025 01:23:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293001; cv=none; b=GjOOTWveT6r6i0vcEPK7BV1Ydfr7SMZWTp0mMETbnh+ItgEs6UVM14opke3TlsPoLh8ogdNj4UE1jb+V+AAbRlSDdXhxR0lYb+5RkTrNSCDryn01VkSAi4qt7iF4gDGmBs2OKNi33eq6qnjo5CrqUToZ1hKuIMzP+3T3rm6F6/w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293001; c=relaxed/simple; bh=/x/FszfOq3lcLNrmXXc3bHvYgFMAygzmK9V0fMZH1I4=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=YbhRqT/yrALOEjpDwKzhERRKlAwxETcqcwLBYusVIaqgYkX8NbX7XYonf55YoOOtmxECjpt4eRBjaubZpfqE3+FN83gZUSpKHDfDDQ9JgovjiCyYjxfKti7WTzPuPG64BgxRbL310QJ57DneQXmuHxIwvccSgEaphLbIZuStq3A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=j39Cuvbr; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="j39Cuvbr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 75E21C4CEF8; Fri, 28 Nov 2025 01:23:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764293001; bh=/x/FszfOq3lcLNrmXXc3bHvYgFMAygzmK9V0fMZH1I4=; h=Date:From:To:Cc:Subject:References:From; b=j39CuvbrMqamh7I6NHyjdH86XlTxqlw+1CxXOKfpnuhJR3HOXFWC86OOkwfMMGap6 eEF6lLW/pGQyf+gzTozYpbqpBHGc0xDC4h6MRf3gmz5YjJHoWEJRGiKTaOn7R6nh4o I7d5+Hlo7qU8z7oV05KtWImDACMZ+tDcy6oILgUGMAtVF6wvnMKFwhJgjlzdgX+Olv J6r2wSgsFgY/nBOr0JHCTuoJpt4tkCXiEB6AtKogiguEjld9wOvU29SC+6QdJjBBqd Hw4p4LP4ncW4jMpK4eWkwL4fmIlunHfdRWDl1Nwvw+qUTE2tkMLeYj5utzYs4gh7G3 a+YnLd1AOhRTQ== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vOnDX-00000006gdo-0Wrg; Thu, 27 Nov 2025 20:24:11 -0500 Message-ID: <20251128012410.977157422@kernel.org> User-Agent: quilt/0.68 Date: Thu, 27 Nov 2025 20:23:32 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Dan Carpenter Subject: [for-next][PATCH 01/13] fgraph: Make fgraph_no_sleep_time signed References: <20251128012331.307010654@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt The variable fgraph_no_sleep_time changed from being a boolean to being a counter. A check is made to make sure that it never goes below zero. But the variable being unsigned makes the check always fail even if it does go below zero. Make the variable a signed int so that checking it going below zero still works. Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Link: https://patch.msgid.link/20251125104751.4c9c7f28@gandalf.local.home Fixes: 5abb6ccb58f0 ("tracing: Have function graph tracer option sleep-time= be per instance") Reported-by: Dan Carpenter Closes: https://lore.kernel.org/all/aR1yRQxDmlfLZzoo@stanley.mountain/ Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.h | 2 +- kernel/trace/trace_functions_graph.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 58be6d741d72..da5d9527ebd6 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -1113,7 +1113,7 @@ static inline void ftrace_graph_addr_finish(struct fg= raph_ops *gops, struct ftra #endif /* CONFIG_DYNAMIC_FTRACE */ =20 extern unsigned int fgraph_max_depth; -extern unsigned int fgraph_no_sleep_time; +extern int fgraph_no_sleep_time; extern bool fprofile_no_sleep_time; =20 static inline bool diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_func= tions_graph.c index 44d5dc5031e2..d0513cfcd936 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -20,7 +20,7 @@ static int ftrace_graph_skip_irqs; =20 /* Do not record function time when task is sleeping */ -unsigned int fgraph_no_sleep_time; +int fgraph_no_sleep_time; =20 struct fgraph_cpu_data { pid_t last_pid; --=20 2.51.0 From nobody Mon Dec 1 21:31:22 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0546521CC5C for ; Fri, 28 Nov 2025 01:23:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; cv=none; b=CH7Sv/QavQpUhhKnZRE7VuqF45fLmeQCSNkCZAoc2v2PWYli0XPOB9A6Sm3n9vQzaQ7nM7qK1vM4RTK98kXviSANRapaRMssRrEtBFysPdwMhTNX2OoGwuN9hHXm3r8GyVEYO2O7re8GJ5KdGowdN8h537LcMRmltE4tR0dityc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; c=relaxed/simple; bh=S+MskiV/zrS55QB/Edarm+k8j9TT1qdsef/gvvfP9do=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=NvMTRyJI3Qy57pmpyT0nluhVAjepeiY3Sb/ev4ZO6ZVfCv3Uzb+LuJ/hDx2beOZxsqsIZiEsaov724s9ysI9Dupl6UrcF91vc62xKWBgsSTYfOGxKOM0dGFLpLfvOkz6qERy4QHpWUhaCTmFiytnM/aAWJQF0YPn9dgR/9NTS3Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DTJMj8ro; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="DTJMj8ro" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 93F3AC16AAE; Fri, 28 Nov 2025 01:23:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764293001; bh=S+MskiV/zrS55QB/Edarm+k8j9TT1qdsef/gvvfP9do=; h=Date:From:To:Cc:Subject:References:From; b=DTJMj8rooUo42O8nXxQQ0B7cZpjHcqrYhGVHvFi8yzcH4QI/7r01rxLu707+xo74F +T4cp/5lG1jqW8bI42fmf/za54CAgCVsfdEk8tDPfON+ZLMXaz198fIB8oH0Hlzglm kHDOgU5F9RP/5zfwazTuvbs+GaNXLm0l7MLIxJ967Orz4zfyHKqhG0hBMLrmLmCgJd 2iWGqK5FyYtrnRIE+IYEGaepwJtYndSEkd1hledch0bLVj/k9Z8i75R9Kvc0hT66qN 2iq6GSpBk8bZ19uwbkh+Rsl1RWH78k1BktWWooSGJkEx8qwK9SWiX1R7qTXJHxdfQS z2QrDjpkk+WSA== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vOnDX-00000006geJ-1Dly; Thu, 27 Nov 2025 20:24:11 -0500 Message-ID: <20251128012411.146707328@kernel.org> User-Agent: quilt/0.68 Date: Thu, 27 Nov 2025 20:23:33 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Andy Shevchenko Subject: [for-next][PATCH 02/13] tracing: Remove unused variable in tracing_trace_options_show() References: <20251128012331.307010654@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt The flags and opts used in tracing_trace_options_show() now come directly from the trace array "current_trace_flags" and not the current_trace. The variable "trace" was still being assigned to tr->current_trace but never used. This caused a warning in clang. Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Link: https://patch.msgid.link/20251117120637.43ef995d@gandalf.local.home Reported-by: Andy Shevchenko Tested-by: Andy Shevchenko Closes: https://lore.kernel.org/all/aRtHWXzYa8ijUIDa@black.igk.intel.com/ Fixes: 428add559b692 ("tracing: Have tracer option be instance specific") Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8ae95800592d..59cd4ed8af6d 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -5167,7 +5167,6 @@ static int tracing_trace_options_show(struct seq_file= *m, void *v) struct tracer_opt *trace_opts; struct trace_array *tr =3D m->private; struct tracer_flags *flags; - struct tracer *trace; u32 tracer_flags; int i; =20 @@ -5184,8 +5183,6 @@ static int tracing_trace_options_show(struct seq_file= *m, void *v) if (!flags || !flags->opts) return 0; =20 - trace =3D tr->current_trace; - tracer_flags =3D flags->val; trace_opts =3D flags->opts; =20 --=20 2.51.0 From nobody Mon Dec 1 21:31:22 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5492822AE7F for ; Fri, 28 Nov 2025 01:23:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; cv=none; b=fTRaLkF91rps2R2/x3uBvMf0i++HymcjTTbNEUM1uY88slslFerFiqmgfpQGCGpxi2C4hvUXwXTpw1IhBwiydvAlhjixH520cEmjTZNXGoxMZEC95OPhw1JD50Krx3e+VJDhiNDOpkTUF4esVrhN3h/SvLZ5CNyLJ2glcTym3iQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; c=relaxed/simple; bh=UFg2vug9M6PbAK7p/8FdDMf/swBXRxNVHznnM+n6jjo=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=FYbCLi14e2pxOSjFroDO5hqI4bFdTIDB+OkVfKP17YltXHBOmzhMgvpy2xrIQvkVQL9LBSmjK7Jzwq+94CWaBoEuHTcwxAKWp3oU/HqNyY8zA6saHjV/002mSVEwUdJCJnHKjQCwRHWHwM+ZCoLG5YZipAvUWcKAH1YXw1A61yI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qwEvc3cs; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qwEvc3cs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E5AD0C19422; Fri, 28 Nov 2025 01:23:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764293002; bh=UFg2vug9M6PbAK7p/8FdDMf/swBXRxNVHznnM+n6jjo=; h=Date:From:To:Cc:Subject:References:From; b=qwEvc3csVn5yBdWfs7fsmcheGUQI5lJj7JYk7yaghFFvlbcF1HC4LtpUV6zkFSrP9 psmhSB4BdbmwoIjDPW7nGm6uzOZueCWMgy/KRrDlXlYLM139+EvlbyVxB3Z7JSg98i L+zDct/8JWnwEwhvkObepMDNV6siPFXt5fmaBtSNcq+kvBJ/oxCOf09ZXVySSSRCq2 fCDxaabd/6cZ6MyLlzznd3nZtDEksADGmjc9Qn1HZjSrbh75NX50gVqJnDHj0H27wW tEOXKMLyI9MYkWegQ4aPWVQnRcw7WQmiHxYqOYCKl2ZprVOx/re5TvNRZIogjEWPpo UW1grHu0xQIvg== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vOnDX-00000006gen-1tZB; Thu, 27 Nov 2025 20:24:11 -0500 Message-ID: <20251128012411.311698005@kernel.org> User-Agent: quilt/0.68 Date: Thu, 27 Nov 2025 20:23:34 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Jiri Olsa , Menglong Dong Subject: [for-next][PATCH 03/13] ftrace: Avoid redundant initialization in register_ftrace_direct References: <20251128012331.307010654@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Menglong Dong The FTRACE_OPS_FL_INITIALIZED flag is cleared in register_ftrace_direct, which can make it initialized by ftrace_ops_init() even if it is already initialized. It seems that there is no big deal here, but let's still fix it. Link: https://patch.msgid.link/20251110121808.1559240-1-dongml2@chinateleco= m.cn Fixes: f64dd4627ec6 ("ftrace: Add multi direct register/unregister interfac= e") Acked-by: Jiri Olsa Signed-off-by: Menglong Dong Signed-off-by: Steven Rostedt (Google) --- kernel/trace/ftrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 7c3bbebeec7a..b4510a6dbf42 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -6069,7 +6069,7 @@ int register_ftrace_direct(struct ftrace_ops *ops, un= signed long addr) new_hash =3D NULL; =20 ops->func =3D call_direct_funcs; - ops->flags =3D MULTI_FLAGS; + ops->flags |=3D MULTI_FLAGS; ops->trampoline =3D FTRACE_REGS_ADDR; ops->direct_call =3D addr; =20 --=20 2.51.0 From nobody Mon Dec 1 21:31:22 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 548C822A4F8 for ; Fri, 28 Nov 2025 01:23:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; cv=none; b=NWMrebr5SnXE79x9nrBEZ7X7tF5iDC5DE3D6XBxTJ6HZCu35kt0bY+v20LkxnptA743eks+YuXip3TwrnLjeQVU2EQX23FcOt5usyZcu0/urbzgbSTZW7tzC+owOaLUUNWolRatUQtBiarHAwcNvyqWrhH6yw0eOS5JePr3n9nU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; c=relaxed/simple; bh=V9z5cSiv89vmqvw/MPmNmoWfCWGSzhq6WDjN5J0X5wc=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=muPf/UoAvJRz6fY0oFmIC66xUGvXM1RO2QfugMNw5v0nPeKl2JsgXESJQcwVCZsQNbRUqIvWC9h/uMQUaYdn/NTK61NipWG0RpYNh4v02I+X1JlHECbDTpSEqnEV7H5gG3vY7jHBCQoK/VYHMF9AH4iPCqjhooab6k9VOVU7tgQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MgB8smyB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MgB8smyB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DF293C113D0; Fri, 28 Nov 2025 01:23:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764293001; bh=V9z5cSiv89vmqvw/MPmNmoWfCWGSzhq6WDjN5J0X5wc=; h=Date:From:To:Cc:Subject:References:From; b=MgB8smyBcvVg+XK8UjfiVzUhyjavvGZmTpS5MHWevIuaWOHlw/vhdc4tZr1aX8uLn ZdeysVMlo6ydF02MZCeL8nUYyv7JEaTgYskX2cgM8r01YNBzP6UecRuZ8kZAooVJBW a15Jeb3CXskI8mR2AYc+WMeYztpM80VEboBH+clTrk4SDV2K2jMBaXkefDoyfTH19X cT/4wyM+F2kvEp0NWzzGo5LzN7FR4kMUuYJkibvKgunKDLjmYnRtkhcYe487+F8LOT qMQ0oEgs4c2+WAMWM48/vWFirRai/xnj0YprtpYLbpaQWRckgmXrthQKSbIcMXYcu0 elNEQ39pn9sjQ== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vOnDX-00000006gfH-2c6D; Thu, 27 Nov 2025 20:24:11 -0500 Message-ID: <20251128012411.471594850@kernel.org> User-Agent: quilt/0.68 Date: Thu, 27 Nov 2025 20:23:35 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton Subject: [for-next][PATCH 04/13] tracing: Show the tracer options in boot-time created instance References: <20251128012331.307010654@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Masami Hiramatsu (Google)" Since tracer_init_tracefs_work_func() only updates the tracer options for the global_trace, the instances created by the kernel cmdline do not have those options. Fix to update tracer options for those boot-time created instances to show those options. Cc: Mark Rutland Cc: Mathieu Desnoyers Cc: Andrew Morton Link: https://patch.msgid.link/176354112555.2356172.3989277078358802353.stg= it@mhiramat.tok.corp.google.com Fixes: 428add559b69 ("tracing: Have tracer option be instance specific") Signed-off-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 59cd4ed8af6d..032bdedca5d9 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -10228,11 +10228,14 @@ static __init int __update_tracer_options(struct = trace_array *tr) return ret; } =20 -static __init void update_tracer_options(struct trace_array *tr) +static __init void update_tracer_options(void) { + struct trace_array *tr; + guard(mutex)(&trace_types_lock); tracer_options_updated =3D true; - __update_tracer_options(tr); + list_for_each_entry(tr, &ftrace_trace_arrays, list) + __update_tracer_options(tr); } =20 /* Must have trace_types_lock held */ @@ -10934,7 +10937,7 @@ static __init void tracer_init_tracefs_work_func(st= ruct work_struct *work) =20 create_trace_instances(NULL); =20 - update_tracer_options(&global_trace); + update_tracer_options(); } =20 static __init int tracer_init_tracefs(void) --=20 2.51.0 From nobody Mon Dec 1 21:31:22 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8069722FDEA for ; Fri, 28 Nov 2025 01:23:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; cv=none; b=Att7TmBY+Dz41mYEAiNNd1vwP3ITlHAsV4R/VztC8bSPYAbSXl8ejlvogd5i8/YpCN73FsKes4u6oX9rHhKA9+Freg0xuiNub+Q5uW4ZqiWwJpVAv6pQ3pM+nOSbRb6X+N3IFC2OuEjvE7IbT73yveEiCT6XPSmdf006Kc1GaGs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; c=relaxed/simple; bh=Jm5RCOozgAQ+Rgd3IkB7A93KXTr2wZVW6QBNThRNNR0=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=G3cJBBb2ew0bZDMpojWlRuBMRE0PbnnrnELJ6rWZ3bRelrpQID5ZD2FPlJAEwnGlN16AMFtag7rgzfXKO5OKfPXNCl5zzUEPVYjAjJ6ITEd1u6E012gtwo22E+tWQzhu/5sVoeDsC+Fmq/CQTdD7fpeCCZJbDCjYdPlB0qRQAdg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UEnsiCGA; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UEnsiCGA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 35317C116C6; Fri, 28 Nov 2025 01:23:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764293002; bh=Jm5RCOozgAQ+Rgd3IkB7A93KXTr2wZVW6QBNThRNNR0=; h=Date:From:To:Cc:Subject:References:From; b=UEnsiCGA6oUatfukuyGV6qjC69tzp4nip1EoAa3grrLNivtgLNXO1A/pNrRiGrCF6 WX3Fa/b3lH2BJRhFEZRW5fcBz3SSgCIHHz9Mj8PI4gmrHAV1O3RAuXyOT9ZHxrqjQu YVDx67x4rDN6IISuQYU0XTEpivrd0/dc6nSjF6EPGA3vOmJcZ9wBAE2xQMKc1Mg4vD JH9W5/IltT9/lkHWCIBEXJDxlgfu9x0JyxVanEctiy4c8RUj8H9m73WBHlCn53DiGk TR73iEtahf/euGGSCndw3GZkQcsyvQ4TFz6SXpvf6aRg26fDaCkq6yHjXQ4KPUDa4v o7SJfNgVW+goA== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vOnDX-00000006gfl-3LCw; Thu, 27 Nov 2025 20:24:11 -0500 Message-ID: <20251128012411.644283122@kernel.org> User-Agent: quilt/0.68 Date: Thu, 27 Nov 2025 20:23:36 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Tom Zanussi Subject: [for-next][PATCH 05/13] tracing: Remove get_trigger_ops() and add count_func() from trigger ops References: <20251128012331.307010654@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt The struct event_command has a callback function called get_trigger_ops(). This callback returns the "trigger_ops" to use for the trigger. These ops define the trigger function, how to init the trigger, how to print the trigger and how to free it. The only reason there's a callback function to get these ops is because some triggers have two types of operations. One is an "always on" operation, and the other is a "count down" operation. If a user passes in a parameter to say how many times the trigger should execute. For example: echo stacktrace:5 > events/kmem/kmem_cache_alloc/trigger It will trigger the stacktrace for the first 5 times the kmem_cache_alloc event is hit. Instead of having two different trigger_ops since the only difference between them is the tigger itself (the print, init and free functions are all the same), just use a single ops that the event_command points to and add a function field to the trigger_ops to have a count_func. When a trigger is added to an event, if there's a count attached to it and the trigger ops has the count_func field, the data allocated to represent this trigger will have a new flag set called COUNT. Then when the trigger executes, it will check if the COUNT data flag is set, and if so, it will call the ops count_func(). If that returns false, it returns without executing the trigger. This removes the need for duplicate event_trigger_ops structures. Cc: Masami Hiramatsu Cc: Mark Rutland Cc: Mathieu Desnoyers Cc: Andrew Morton Link: https://patch.msgid.link/20251125200932.274566147@kernel.org Reviewed-by: Tom Zanussi Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.h | 26 ++- kernel/trace/trace_eprobe.c | 8 +- kernel/trace/trace_events_hist.c | 60 +------ kernel/trace/trace_events_trigger.c | 257 ++++++++++------------------ 4 files changed, 116 insertions(+), 235 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index da5d9527ebd6..b9c59d9f9a0c 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -1791,6 +1791,7 @@ extern void clear_event_triggers(struct trace_array *= tr); =20 enum { EVENT_TRIGGER_FL_PROBE =3D BIT(0), + EVENT_TRIGGER_FL_COUNT =3D BIT(1), }; =20 struct event_trigger_data { @@ -1822,6 +1823,10 @@ struct enable_trigger_data { bool hist; }; =20 +bool event_trigger_count(struct event_trigger_data *data, + struct trace_buffer *buffer, void *rec, + struct ring_buffer_event *event); + extern int event_enable_trigger_print(struct seq_file *m, struct event_trigger_data *data); extern void event_enable_trigger_free(struct event_trigger_data *data); @@ -1909,6 +1914,11 @@ extern void event_file_put(struct trace_event_file *= file); * registered the trigger (see struct event_command) along with * the trace record, rec. * + * @count_func: If defined and a numeric parameter is passed to the + * trigger, then this function will be called before @trigger + * is called. If this function returns false, then @trigger is not + * executed. + * * @init: An optional initialization function called for the trigger * when the trigger is registered (via the event_command reg() * function). This can be used to perform per-trigger @@ -1936,6 +1946,10 @@ struct event_trigger_ops { struct trace_buffer *buffer, void *rec, struct ring_buffer_event *rbe); + bool (*count_func)(struct event_trigger_data *data, + struct trace_buffer *buffer, + void *rec, + struct ring_buffer_event *rbe); int (*init)(struct event_trigger_data *data); void (*free)(struct event_trigger_data *data); int (*print)(struct seq_file *m, @@ -1962,6 +1976,9 @@ struct event_trigger_ops { * @name: The unique name that identifies the event command. This is * the name used when setting triggers via trigger files. * + * @trigger_ops: The event_trigger_ops implementation associated with + * the command. + * * @trigger_type: A unique id that identifies the event command * 'type'. This value has two purposes, the first to ensure that * only one trigger of the same type can be set at a given time @@ -2013,17 +2030,11 @@ struct event_trigger_ops { * event command, filters set by the user for the command will be * ignored. This is usually implemented by the generic utility * function @set_trigger_filter() (see trace_event_triggers.c). - * - * @get_trigger_ops: The callback function invoked to retrieve the - * event_trigger_ops implementation associated with the command. - * This callback function allows a single event_command to - * support multiple trigger implementations via different sets of - * event_trigger_ops, depending on the value of the @param - * string. */ struct event_command { struct list_head list; char *name; + const struct event_trigger_ops *trigger_ops; enum event_trigger_type trigger_type; int flags; int (*parse)(struct event_command *cmd_ops, @@ -2040,7 +2051,6 @@ struct event_command { int (*set_filter)(char *filter_str, struct event_trigger_data *data, struct trace_event_file *file); - const struct event_trigger_ops *(*get_trigger_ops)(char *cmd, char *param= ); }; =20 /** diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c index a1d402124836..14ae896dbe75 100644 --- a/kernel/trace/trace_eprobe.c +++ b/kernel/trace/trace_eprobe.c @@ -513,21 +513,15 @@ static void eprobe_trigger_unreg_func(char *glob, =20 } =20 -static const struct event_trigger_ops *eprobe_trigger_get_ops(char *cmd, - char *param) -{ - return &eprobe_trigger_ops; -} - static struct event_command event_trigger_cmd =3D { .name =3D "eprobe", .trigger_type =3D ETT_EVENT_EPROBE, .flags =3D EVENT_CMD_FL_NEEDS_REC, + .trigger_ops =3D &eprobe_trigger_ops, .parse =3D eprobe_trigger_cmd_parse, .reg =3D eprobe_trigger_reg_func, .unreg =3D eprobe_trigger_unreg_func, .unreg_all =3D NULL, - .get_trigger_ops =3D eprobe_trigger_get_ops, .set_filter =3D NULL, }; =20 diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_h= ist.c index 1d536219b624..f9cc8d6a215b 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -6363,12 +6363,6 @@ static const struct event_trigger_ops event_hist_tri= gger_named_ops =3D { .free =3D event_hist_trigger_named_free, }; =20 -static const struct event_trigger_ops *event_hist_get_trigger_ops(char *cm= d, - char *param) -{ - return &event_hist_trigger_ops; -} - static void hist_clear(struct event_trigger_data *data) { struct hist_trigger_data *hist_data =3D data->private_data; @@ -6908,11 +6902,11 @@ static struct event_command trigger_hist_cmd =3D { .name =3D "hist", .trigger_type =3D ETT_EVENT_HIST, .flags =3D EVENT_CMD_FL_NEEDS_REC, + .trigger_ops =3D &event_hist_trigger_ops, .parse =3D event_hist_trigger_parse, .reg =3D hist_register_trigger, .unreg =3D hist_unregister_trigger, .unreg_all =3D hist_unreg_all, - .get_trigger_ops =3D event_hist_get_trigger_ops, .set_filter =3D set_trigger_filter, }; =20 @@ -6945,29 +6939,9 @@ hist_enable_trigger(struct event_trigger_data *data, } } =20 -static void -hist_enable_count_trigger(struct event_trigger_data *data, - struct trace_buffer *buffer, void *rec, - struct ring_buffer_event *event) -{ - if (!data->count) - return; - - if (data->count !=3D -1) - (data->count)--; - - hist_enable_trigger(data, buffer, rec, event); -} - static const struct event_trigger_ops hist_enable_trigger_ops =3D { .trigger =3D hist_enable_trigger, - .print =3D event_enable_trigger_print, - .init =3D event_trigger_init, - .free =3D event_enable_trigger_free, -}; - -static const struct event_trigger_ops hist_enable_count_trigger_ops =3D { - .trigger =3D hist_enable_count_trigger, + .count_func =3D event_trigger_count, .print =3D event_enable_trigger_print, .init =3D event_trigger_init, .free =3D event_enable_trigger_free, @@ -6975,36 +6949,12 @@ static const struct event_trigger_ops hist_enable_c= ount_trigger_ops =3D { =20 static const struct event_trigger_ops hist_disable_trigger_ops =3D { .trigger =3D hist_enable_trigger, + .count_func =3D event_trigger_count, .print =3D event_enable_trigger_print, .init =3D event_trigger_init, .free =3D event_enable_trigger_free, }; =20 -static const struct event_trigger_ops hist_disable_count_trigger_ops =3D { - .trigger =3D hist_enable_count_trigger, - .print =3D event_enable_trigger_print, - .init =3D event_trigger_init, - .free =3D event_enable_trigger_free, -}; - -static const struct event_trigger_ops * -hist_enable_get_trigger_ops(char *cmd, char *param) -{ - const struct event_trigger_ops *ops; - bool enable; - - enable =3D (strcmp(cmd, ENABLE_HIST_STR) =3D=3D 0); - - if (enable) - ops =3D param ? &hist_enable_count_trigger_ops : - &hist_enable_trigger_ops; - else - ops =3D param ? &hist_disable_count_trigger_ops : - &hist_disable_trigger_ops; - - return ops; -} - static void hist_enable_unreg_all(struct trace_event_file *file) { struct event_trigger_data *test, *n; @@ -7023,22 +6973,22 @@ static void hist_enable_unreg_all(struct trace_even= t_file *file) static struct event_command trigger_hist_enable_cmd =3D { .name =3D ENABLE_HIST_STR, .trigger_type =3D ETT_HIST_ENABLE, + .trigger_ops =3D &hist_enable_trigger_ops, .parse =3D event_enable_trigger_parse, .reg =3D event_enable_register_trigger, .unreg =3D event_enable_unregister_trigger, .unreg_all =3D hist_enable_unreg_all, - .get_trigger_ops =3D hist_enable_get_trigger_ops, .set_filter =3D set_trigger_filter, }; =20 static struct event_command trigger_hist_disable_cmd =3D { .name =3D DISABLE_HIST_STR, .trigger_type =3D ETT_HIST_ENABLE, + .trigger_ops =3D &hist_disable_trigger_ops, .parse =3D event_enable_trigger_parse, .reg =3D event_enable_register_trigger, .unreg =3D event_enable_unregister_trigger, .unreg_all =3D hist_enable_unreg_all, - .get_trigger_ops =3D hist_enable_get_trigger_ops, .set_filter =3D set_trigger_filter, }; =20 diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_event= s_trigger.c index cbfc306c0159..576bad18bcdb 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -28,6 +28,20 @@ void trigger_data_free(struct event_trigger_data *data) kfree(data); } =20 +static inline void data_ops_trigger(struct event_trigger_data *data, + struct trace_buffer *buffer, void *rec, + struct ring_buffer_event *event) +{ + const struct event_trigger_ops *ops =3D data->ops; + + if (data->flags & EVENT_TRIGGER_FL_COUNT) { + if (!ops->count_func(data, buffer, rec, event)) + return; + } + + ops->trigger(data, buffer, rec, event); +} + /** * event_triggers_call - Call triggers associated with a trace event * @file: The trace_event_file associated with the event @@ -70,7 +84,7 @@ event_triggers_call(struct trace_event_file *file, if (data->paused) continue; if (!rec) { - data->ops->trigger(data, buffer, rec, event); + data_ops_trigger(data, buffer, rec, event); continue; } filter =3D rcu_dereference_sched(data->filter); @@ -80,7 +94,7 @@ event_triggers_call(struct trace_event_file *file, tt |=3D data->cmd_ops->trigger_type; continue; } - data->ops->trigger(data, buffer, rec, event); + data_ops_trigger(data, buffer, rec, event); } return tt; } @@ -122,7 +136,7 @@ event_triggers_post_call(struct trace_event_file *file, if (data->paused) continue; if (data->cmd_ops->trigger_type & tt) - data->ops->trigger(data, NULL, NULL, NULL); + data_ops_trigger(data, NULL, NULL, NULL); } } EXPORT_SYMBOL_GPL(event_triggers_post_call); @@ -377,6 +391,36 @@ __init int unregister_event_command(struct event_comma= nd *cmd) return -ENODEV; } =20 +/** + * event_trigger_count - Optional count function for event triggers + * @data: Trigger-specific data + * @buffer: The ring buffer that the event is being written to + * @rec: The trace entry for the event, NULL for unconditional invocation + * @event: The event meta data in the ring buffer + * + * For triggers that can take a count parameter that doesn't do anything + * special, they can use this function to assign to their .count_func + * field. + * + * This simply does a count down of the @data->count field. + * + * If the @data->count is greater than zero, it will decrement it. + * + * Returns false if @data->count is zero, otherwise true. + */ +bool event_trigger_count(struct event_trigger_data *data, + struct trace_buffer *buffer, void *rec, + struct ring_buffer_event *event) +{ + if (!data->count) + return false; + + if (data->count !=3D -1) + (data->count)--; + + return true; +} + /** * event_trigger_print - Generic event_trigger_ops @print implementation * @name: The name of the event trigger @@ -807,9 +851,13 @@ int event_trigger_separate_filter(char *param_and_filt= er, char **param, * @private_data: User data to associate with the event trigger * * Allocate an event_trigger_data instance and initialize it. The - * @cmd_ops are used along with the @cmd and @param to get the - * trigger_ops to assign to the event_trigger_data. @private_data can - * also be passed in and associated with the event_trigger_data. + * @cmd_ops defines how the trigger will operate. If @param is set, + * and @cmd_ops->trigger_ops->count_func is non NULL, then the + * data->count is set to @param and before the trigger is executed, the + * @cmd_ops->trigger_ops->count_func() is called. If that function returns + * false, the @cmd_ops->trigger_ops->trigger() function will not be called. + * @private_data can also be passed in and associated with the + * event_trigger_data. * * Use trigger_data_free() to free an event_trigger_data object. * @@ -821,18 +869,17 @@ struct event_trigger_data *trigger_data_alloc(struct = event_command *cmd_ops, void *private_data) { struct event_trigger_data *trigger_data; - const struct event_trigger_ops *trigger_ops; - - trigger_ops =3D cmd_ops->get_trigger_ops(cmd, param); =20 trigger_data =3D kzalloc(sizeof(*trigger_data), GFP_KERNEL); if (!trigger_data) return NULL; =20 trigger_data->count =3D -1; - trigger_data->ops =3D trigger_ops; + trigger_data->ops =3D cmd_ops->trigger_ops; trigger_data->cmd_ops =3D cmd_ops; trigger_data->private_data =3D private_data; + if (param && cmd_ops->trigger_ops->count_func) + trigger_data->flags |=3D EVENT_TRIGGER_FL_COUNT; =20 INIT_LIST_HEAD(&trigger_data->list); INIT_LIST_HEAD(&trigger_data->named_list); @@ -1271,31 +1318,28 @@ traceon_trigger(struct event_trigger_data *data, tracing_on(); } =20 -static void -traceon_count_trigger(struct event_trigger_data *data, - struct trace_buffer *buffer, void *rec, - struct ring_buffer_event *event) +static bool +traceon_count_func(struct event_trigger_data *data, + struct trace_buffer *buffer, void *rec, + struct ring_buffer_event *event) { struct trace_event_file *file =3D data->private_data; =20 if (file) { if (tracer_tracing_is_on(file->tr)) - return; + return false; } else { if (tracing_is_on()) - return; + return false; } =20 if (!data->count) - return; + return false; =20 if (data->count !=3D -1) (data->count)--; =20 - if (file) - tracer_tracing_on(file->tr); - else - tracing_on(); + return true; } =20 static void @@ -1319,31 +1363,28 @@ traceoff_trigger(struct event_trigger_data *data, tracing_off(); } =20 -static void -traceoff_count_trigger(struct event_trigger_data *data, - struct trace_buffer *buffer, void *rec, - struct ring_buffer_event *event) +static bool +traceoff_count_func(struct event_trigger_data *data, + struct trace_buffer *buffer, void *rec, + struct ring_buffer_event *event) { struct trace_event_file *file =3D data->private_data; =20 if (file) { if (!tracer_tracing_is_on(file->tr)) - return; + return false; } else { if (!tracing_is_on()) - return; + return false; } =20 if (!data->count) - return; + return false; =20 if (data->count !=3D -1) (data->count)--; =20 - if (file) - tracer_tracing_off(file->tr); - else - tracing_off(); + return true; } =20 static int @@ -1362,13 +1403,7 @@ traceoff_trigger_print(struct seq_file *m, struct ev= ent_trigger_data *data) =20 static const struct event_trigger_ops traceon_trigger_ops =3D { .trigger =3D traceon_trigger, - .print =3D traceon_trigger_print, - .init =3D event_trigger_init, - .free =3D event_trigger_free, -}; - -static const struct event_trigger_ops traceon_count_trigger_ops =3D { - .trigger =3D traceon_count_trigger, + .count_func =3D traceon_count_func, .print =3D traceon_trigger_print, .init =3D event_trigger_init, .free =3D event_trigger_free, @@ -1376,41 +1411,19 @@ static const struct event_trigger_ops traceon_count= _trigger_ops =3D { =20 static const struct event_trigger_ops traceoff_trigger_ops =3D { .trigger =3D traceoff_trigger, + .count_func =3D traceoff_count_func, .print =3D traceoff_trigger_print, .init =3D event_trigger_init, .free =3D event_trigger_free, }; =20 -static const struct event_trigger_ops traceoff_count_trigger_ops =3D { - .trigger =3D traceoff_count_trigger, - .print =3D traceoff_trigger_print, - .init =3D event_trigger_init, - .free =3D event_trigger_free, -}; - -static const struct event_trigger_ops * -onoff_get_trigger_ops(char *cmd, char *param) -{ - const struct event_trigger_ops *ops; - - /* we register both traceon and traceoff to this callback */ - if (strcmp(cmd, "traceon") =3D=3D 0) - ops =3D param ? &traceon_count_trigger_ops : - &traceon_trigger_ops; - else - ops =3D param ? &traceoff_count_trigger_ops : - &traceoff_trigger_ops; - - return ops; -} - static struct event_command trigger_traceon_cmd =3D { .name =3D "traceon", .trigger_type =3D ETT_TRACE_ONOFF, + .trigger_ops =3D &traceon_trigger_ops, .parse =3D event_trigger_parse, .reg =3D register_trigger, .unreg =3D unregister_trigger, - .get_trigger_ops =3D onoff_get_trigger_ops, .set_filter =3D set_trigger_filter, }; =20 @@ -1418,10 +1431,10 @@ static struct event_command trigger_traceoff_cmd = =3D { .name =3D "traceoff", .trigger_type =3D ETT_TRACE_ONOFF, .flags =3D EVENT_CMD_FL_POST_TRIGGER, + .trigger_ops =3D &traceoff_trigger_ops, .parse =3D event_trigger_parse, .reg =3D register_trigger, .unreg =3D unregister_trigger, - .get_trigger_ops =3D onoff_get_trigger_ops, .set_filter =3D set_trigger_filter, }; =20 @@ -1439,20 +1452,6 @@ snapshot_trigger(struct event_trigger_data *data, tracing_snapshot(); } =20 -static void -snapshot_count_trigger(struct event_trigger_data *data, - struct trace_buffer *buffer, void *rec, - struct ring_buffer_event *event) -{ - if (!data->count) - return; - - if (data->count !=3D -1) - (data->count)--; - - snapshot_trigger(data, buffer, rec, event); -} - static int register_snapshot_trigger(char *glob, struct event_trigger_data *data, @@ -1486,31 +1485,19 @@ snapshot_trigger_print(struct seq_file *m, struct e= vent_trigger_data *data) =20 static const struct event_trigger_ops snapshot_trigger_ops =3D { .trigger =3D snapshot_trigger, + .count_func =3D event_trigger_count, .print =3D snapshot_trigger_print, .init =3D event_trigger_init, .free =3D event_trigger_free, }; =20 -static const struct event_trigger_ops snapshot_count_trigger_ops =3D { - .trigger =3D snapshot_count_trigger, - .print =3D snapshot_trigger_print, - .init =3D event_trigger_init, - .free =3D event_trigger_free, -}; - -static const struct event_trigger_ops * -snapshot_get_trigger_ops(char *cmd, char *param) -{ - return param ? &snapshot_count_trigger_ops : &snapshot_trigger_ops; -} - static struct event_command trigger_snapshot_cmd =3D { .name =3D "snapshot", .trigger_type =3D ETT_SNAPSHOT, + .trigger_ops =3D &snapshot_trigger_ops, .parse =3D event_trigger_parse, .reg =3D register_snapshot_trigger, .unreg =3D unregister_snapshot_trigger, - .get_trigger_ops =3D snapshot_get_trigger_ops, .set_filter =3D set_trigger_filter, }; =20 @@ -1558,20 +1545,6 @@ stacktrace_trigger(struct event_trigger_data *data, trace_dump_stack(STACK_SKIP); } =20 -static void -stacktrace_count_trigger(struct event_trigger_data *data, - struct trace_buffer *buffer, void *rec, - struct ring_buffer_event *event) -{ - if (!data->count) - return; - - if (data->count !=3D -1) - (data->count)--; - - stacktrace_trigger(data, buffer, rec, event); -} - static int stacktrace_trigger_print(struct seq_file *m, struct event_trigger_data *da= ta) { @@ -1581,32 +1554,20 @@ stacktrace_trigger_print(struct seq_file *m, struct= event_trigger_data *data) =20 static const struct event_trigger_ops stacktrace_trigger_ops =3D { .trigger =3D stacktrace_trigger, + .count_func =3D event_trigger_count, .print =3D stacktrace_trigger_print, .init =3D event_trigger_init, .free =3D event_trigger_free, }; =20 -static const struct event_trigger_ops stacktrace_count_trigger_ops =3D { - .trigger =3D stacktrace_count_trigger, - .print =3D stacktrace_trigger_print, - .init =3D event_trigger_init, - .free =3D event_trigger_free, -}; - -static const struct event_trigger_ops * -stacktrace_get_trigger_ops(char *cmd, char *param) -{ - return param ? &stacktrace_count_trigger_ops : &stacktrace_trigger_ops; -} - static struct event_command trigger_stacktrace_cmd =3D { .name =3D "stacktrace", .trigger_type =3D ETT_STACKTRACE, + .trigger_ops =3D &stacktrace_trigger_ops, .flags =3D EVENT_CMD_FL_POST_TRIGGER, .parse =3D event_trigger_parse, .reg =3D register_trigger, .unreg =3D unregister_trigger, - .get_trigger_ops =3D stacktrace_get_trigger_ops, .set_filter =3D set_trigger_filter, }; =20 @@ -1642,24 +1603,24 @@ event_enable_trigger(struct event_trigger_data *dat= a, set_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, &enable_data->file->flags); } =20 -static void -event_enable_count_trigger(struct event_trigger_data *data, - struct trace_buffer *buffer, void *rec, - struct ring_buffer_event *event) +static bool +event_enable_count_func(struct event_trigger_data *data, + struct trace_buffer *buffer, void *rec, + struct ring_buffer_event *event) { struct enable_trigger_data *enable_data =3D data->private_data; =20 if (!data->count) - return; + return false; =20 /* Skip if the event is in a state we want to switch to */ if (enable_data->enable =3D=3D !(enable_data->file->flags & EVENT_FILE_FL= _SOFT_DISABLED)) - return; + return false; =20 if (data->count !=3D -1) (data->count)--; =20 - event_enable_trigger(data, buffer, rec, event); + return true; } =20 int event_enable_trigger_print(struct seq_file *m, @@ -1706,13 +1667,7 @@ void event_enable_trigger_free(struct event_trigger_= data *data) =20 static const struct event_trigger_ops event_enable_trigger_ops =3D { .trigger =3D event_enable_trigger, - .print =3D event_enable_trigger_print, - .init =3D event_trigger_init, - .free =3D event_enable_trigger_free, -}; - -static const struct event_trigger_ops event_enable_count_trigger_ops =3D { - .trigger =3D event_enable_count_trigger, + .count_func =3D event_enable_count_func, .print =3D event_enable_trigger_print, .init =3D event_trigger_init, .free =3D event_enable_trigger_free, @@ -1720,13 +1675,7 @@ static const struct event_trigger_ops event_enable_c= ount_trigger_ops =3D { =20 static const struct event_trigger_ops event_disable_trigger_ops =3D { .trigger =3D event_enable_trigger, - .print =3D event_enable_trigger_print, - .init =3D event_trigger_init, - .free =3D event_enable_trigger_free, -}; - -static const struct event_trigger_ops event_disable_count_trigger_ops =3D { - .trigger =3D event_enable_count_trigger, + .count_func =3D event_enable_count_func, .print =3D event_enable_trigger_print, .init =3D event_trigger_init, .free =3D event_enable_trigger_free, @@ -1906,45 +1855,23 @@ void event_enable_unregister_trigger(char *glob, data->ops->free(data); } =20 -static const struct event_trigger_ops * -event_enable_get_trigger_ops(char *cmd, char *param) -{ - const struct event_trigger_ops *ops; - bool enable; - -#ifdef CONFIG_HIST_TRIGGERS - enable =3D ((strcmp(cmd, ENABLE_EVENT_STR) =3D=3D 0) || - (strcmp(cmd, ENABLE_HIST_STR) =3D=3D 0)); -#else - enable =3D strcmp(cmd, ENABLE_EVENT_STR) =3D=3D 0; -#endif - if (enable) - ops =3D param ? &event_enable_count_trigger_ops : - &event_enable_trigger_ops; - else - ops =3D param ? &event_disable_count_trigger_ops : - &event_disable_trigger_ops; - - return ops; -} - static struct event_command trigger_enable_cmd =3D { .name =3D ENABLE_EVENT_STR, .trigger_type =3D ETT_EVENT_ENABLE, + .trigger_ops =3D &event_enable_trigger_ops, .parse =3D event_enable_trigger_parse, .reg =3D event_enable_register_trigger, .unreg =3D event_enable_unregister_trigger, - .get_trigger_ops =3D event_enable_get_trigger_ops, .set_filter =3D set_trigger_filter, }; =20 static struct event_command trigger_disable_cmd =3D { .name =3D DISABLE_EVENT_STR, .trigger_type =3D ETT_EVENT_ENABLE, + .trigger_ops =3D &event_disable_trigger_ops, .parse =3D event_enable_trigger_parse, .reg =3D event_enable_register_trigger, .unreg =3D event_enable_unregister_trigger, - .get_trigger_ops =3D event_enable_get_trigger_ops, .set_filter =3D set_trigger_filter, }; =20 --=20 2.51.0 From nobody Mon Dec 1 21:31:22 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8BC00230274 for ; Fri, 28 Nov 2025 01:23:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; cv=none; b=tLJATwCzDPw8r+WvEtgqv8Yw5TGM+89zomFX4kceS2UVHY3dtIaa9y3apvp7s9tGyH2NCUa6Cg08iqE6lvSex8qGMytpKCI0fFL+tjEAPq0wgPx7D4Rqfq6VaT+CQRCNcrPHmGyu9y/6ldujPkrgrg/hsURrDf1uu2I67p5vK6M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; c=relaxed/simple; bh=dj8CIf3lE9w1L/ozxTiTPU5WhLcqbqF/Vvx8it9JaEA=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=AgmioKjuGM044pOnErLfRd3GAAhjXHLWVuTrsAhbyCsd10BShYG9ZjtdyScwx6GyOvolftUGP0SyH0JLmGCXwRN4twv44JeaBl+Vawz9tYxjVpR7dP3Wlqh+fEsLDE45oXoHDMYgrBI7pPUkPwpE86zJXecTpn2T3dnKwccL4zk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eWUbf1fH; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eWUbf1fH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 484D7C19424; Fri, 28 Nov 2025 01:23:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764293002; bh=dj8CIf3lE9w1L/ozxTiTPU5WhLcqbqF/Vvx8it9JaEA=; h=Date:From:To:Cc:Subject:References:From; b=eWUbf1fHeFqTMx3Vr+fRnBItpyh6wRXL70MaaZK1JdHzym+XD+ai/NT37MY0U5iv2 ueFechIV+cWqznYnzSHG8sXMW65mEj3qNUFA411H9zl3X/H9bVxRkpsKD9hROg1PB9 iGMb2HZYRrejVtqn9Ii6e3z7LIDZApAII2ZwMXoliLpyTpbjCtExHrZjXGMLDavVKW 4y4wLNc7EKs0AqE9n0r3JyjrRFvw5crz23P7K4xBpsW6G668w+QWe6IfeSO7HSAQxO tVqKwucH40C5gjRfXKYCgLfQFVCMG8TPpLVOTd3/KOXnyGzZjjMunaWW6CJyUkNUnX WqCR+H7Zzaf/A== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vOnDX-00000006ggF-43rK; Thu, 27 Nov 2025 20:24:11 -0500 Message-ID: <20251128012411.817800726@kernel.org> User-Agent: quilt/0.68 Date: Thu, 27 Nov 2025 20:23:37 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Tom Zanussi Subject: [for-next][PATCH 06/13] tracing: Merge struct event_trigger_ops into struct event_command References: <20251128012331.307010654@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt Now that there's pretty much a one to one mapping between the struct event_trigger_ops and struct event_command, there's no reason to have two different structures. Merge the function pointers of event_trigger_ops into event_command. There's one exception in trace_events_hist.c for the event_hist_trigger_named_ops. This has special logic for the init and free function pointers for "named histograms". In this case, allocate the cmd_ops of the event_trigger_data and set it to the proper init and free functions, which are used to initialize and free the event_trigger_data respectively. Have the free function and the init function (on failure) free the cmd_ops of the data element. Cc: Masami Hiramatsu Cc: Mark Rutland Cc: Mathieu Desnoyers Cc: Andrew Morton Link: https://patch.msgid.link/20251125200932.446322765@kernel.org Reviewed-by: Tom Zanussi Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.h | 126 +++++++++++----------------- kernel/trace/trace_eprobe.c | 13 +-- kernel/trace/trace_events_hist.c | 93 ++++++++++---------- kernel/trace/trace_events_trigger.c | 121 +++++++++++--------------- 4 files changed, 151 insertions(+), 202 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index b9c59d9f9a0c..901aad30099b 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -1798,7 +1798,6 @@ struct event_trigger_data { unsigned long count; int ref; int flags; - const struct event_trigger_ops *ops; struct event_command *cmd_ops; struct event_filter __rcu *filter; char *filter_str; @@ -1889,73 +1888,6 @@ extern void event_trigger_unregister(struct event_co= mmand *cmd_ops, extern void event_file_get(struct trace_event_file *file); extern void event_file_put(struct trace_event_file *file); =20 -/** - * struct event_trigger_ops - callbacks for trace event triggers - * - * The methods in this structure provide per-event trigger hooks for - * various trigger operations. - * - * The @init and @free methods are used during trigger setup and - * teardown, typically called from an event_command's @parse() - * function implementation. - * - * The @print method is used to print the trigger spec. - * - * The @trigger method is the function that actually implements the - * trigger and is called in the context of the triggering event - * whenever that event occurs. - * - * All the methods below, except for @init() and @free(), must be - * implemented. - * - * @trigger: The trigger 'probe' function called when the triggering - * event occurs. The data passed into this callback is the data - * that was supplied to the event_command @reg() function that - * registered the trigger (see struct event_command) along with - * the trace record, rec. - * - * @count_func: If defined and a numeric parameter is passed to the - * trigger, then this function will be called before @trigger - * is called. If this function returns false, then @trigger is not - * executed. - * - * @init: An optional initialization function called for the trigger - * when the trigger is registered (via the event_command reg() - * function). This can be used to perform per-trigger - * initialization such as incrementing a per-trigger reference - * count, for instance. This is usually implemented by the - * generic utility function @event_trigger_init() (see - * trace_event_triggers.c). - * - * @free: An optional de-initialization function called for the - * trigger when the trigger is unregistered (via the - * event_command @reg() function). This can be used to perform - * per-trigger de-initialization such as decrementing a - * per-trigger reference count and freeing corresponding trigger - * data, for instance. This is usually implemented by the - * generic utility function @event_trigger_free() (see - * trace_event_triggers.c). - * - * @print: The callback function invoked to have the trigger print - * itself. This is usually implemented by a wrapper function - * that calls the generic utility function @event_trigger_print() - * (see trace_event_triggers.c). - */ -struct event_trigger_ops { - void (*trigger)(struct event_trigger_data *data, - struct trace_buffer *buffer, - void *rec, - struct ring_buffer_event *rbe); - bool (*count_func)(struct event_trigger_data *data, - struct trace_buffer *buffer, - void *rec, - struct ring_buffer_event *rbe); - int (*init)(struct event_trigger_data *data); - void (*free)(struct event_trigger_data *data); - int (*print)(struct seq_file *m, - struct event_trigger_data *data); -}; - /** * struct event_command - callbacks and data members for event commands * @@ -1976,9 +1908,6 @@ struct event_trigger_ops { * @name: The unique name that identifies the event command. This is * the name used when setting triggers via trigger files. * - * @trigger_ops: The event_trigger_ops implementation associated with - * the command. - * * @trigger_type: A unique id that identifies the event command * 'type'. This value has two purposes, the first to ensure that * only one trigger of the same type can be set at a given time @@ -2008,7 +1937,7 @@ struct event_trigger_ops { * * @reg: Adds the trigger to the list of triggers associated with the * event, and enables the event trigger itself, after - * initializing it (via the event_trigger_ops @init() function). + * initializing it (via the event_command @init() function). * This is also where commands can use the @trigger_type value to * make the decision as to whether or not multiple instances of * the trigger should be allowed. This is usually implemented by @@ -2017,7 +1946,7 @@ struct event_trigger_ops { * * @unreg: Removes the trigger from the list of triggers associated * with the event, and disables the event trigger itself, after - * initializing it (via the event_trigger_ops @free() function). + * initializing it (via the event_command @free() function). * This is usually implemented by the generic utility function * @unregister_trigger() (see trace_event_triggers.c). * @@ -2030,11 +1959,46 @@ struct event_trigger_ops { * event command, filters set by the user for the command will be * ignored. This is usually implemented by the generic utility * function @set_trigger_filter() (see trace_event_triggers.c). + * + * All the methods below, except for @init() and @free(), must be + * implemented. + * + * @trigger: The trigger 'probe' function called when the triggering + * event occurs. The data passed into this callback is the data + * that was supplied to the event_command @reg() function that + * registered the trigger (see struct event_command) along with + * the trace record, rec. + * + * @count_func: If defined and a numeric parameter is passed to the + * trigger, then this function will be called before @trigger + * is called. If this function returns false, then @trigger is not + * executed. + * + * @init: An optional initialization function called for the trigger + * when the trigger is registered (via the event_command reg() + * function). This can be used to perform per-trigger + * initialization such as incrementing a per-trigger reference + * count, for instance. This is usually implemented by the + * generic utility function @event_trigger_init() (see + * trace_event_triggers.c). + * + * @free: An optional de-initialization function called for the + * trigger when the trigger is unregistered (via the + * event_command @reg() function). This can be used to perform + * per-trigger de-initialization such as decrementing a + * per-trigger reference count and freeing corresponding trigger + * data, for instance. This is usually implemented by the + * generic utility function @event_trigger_free() (see + * trace_event_triggers.c). + * + * @print: The callback function invoked to have the trigger print + * itself. This is usually implemented by a wrapper function + * that calls the generic utility function @event_trigger_print() + * (see trace_event_triggers.c). */ struct event_command { struct list_head list; char *name; - const struct event_trigger_ops *trigger_ops; enum event_trigger_type trigger_type; int flags; int (*parse)(struct event_command *cmd_ops, @@ -2051,6 +2015,18 @@ struct event_command { int (*set_filter)(char *filter_str, struct event_trigger_data *data, struct trace_event_file *file); + void (*trigger)(struct event_trigger_data *data, + struct trace_buffer *buffer, + void *rec, + struct ring_buffer_event *rbe); + bool (*count_func)(struct event_trigger_data *data, + struct trace_buffer *buffer, + void *rec, + struct ring_buffer_event *rbe); + int (*init)(struct event_trigger_data *data); + void (*free)(struct event_trigger_data *data); + int (*print)(struct seq_file *m, + struct event_trigger_data *data); }; =20 /** @@ -2071,7 +2047,7 @@ struct event_command { * either committed or discarded. At that point, if any commands * have deferred their triggers, those commands are finally * invoked following the close of the current event. In other - * words, if the event_trigger_ops @func() probe implementation + * words, if the event_command @func() probe implementation * itself logs to the trace buffer, this flag should be set, * otherwise it can be left unspecified. * diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c index 14ae896dbe75..f3e0442c3b96 100644 --- a/kernel/trace/trace_eprobe.c +++ b/kernel/trace/trace_eprobe.c @@ -484,13 +484,6 @@ static void eprobe_trigger_func(struct event_trigger_d= ata *data, __eprobe_trace_func(edata, rec); } =20 -static const struct event_trigger_ops eprobe_trigger_ops =3D { - .trigger =3D eprobe_trigger_func, - .print =3D eprobe_trigger_print, - .init =3D eprobe_trigger_init, - .free =3D eprobe_trigger_free, -}; - static int eprobe_trigger_cmd_parse(struct event_command *cmd_ops, struct trace_event_file *file, char *glob, char *cmd, @@ -517,12 +510,15 @@ static struct event_command event_trigger_cmd =3D { .name =3D "eprobe", .trigger_type =3D ETT_EVENT_EPROBE, .flags =3D EVENT_CMD_FL_NEEDS_REC, - .trigger_ops =3D &eprobe_trigger_ops, .parse =3D eprobe_trigger_cmd_parse, .reg =3D eprobe_trigger_reg_func, .unreg =3D eprobe_trigger_unreg_func, .unreg_all =3D NULL, .set_filter =3D NULL, + .trigger =3D eprobe_trigger_func, + .print =3D eprobe_trigger_print, + .init =3D eprobe_trigger_init, + .free =3D eprobe_trigger_free, }; =20 static struct event_trigger_data * @@ -542,7 +538,6 @@ new_eprobe_trigger(struct trace_eprobe *ep, struct trac= e_event_file *file) =20 trigger->flags =3D EVENT_TRIGGER_FL_PROBE; trigger->count =3D -1; - trigger->ops =3D &eprobe_trigger_ops; =20 /* * EVENT PROBE triggers are not registered as commands with diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_h= ist.c index f9cc8d6a215b..f0dafc1f2787 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -5694,7 +5694,7 @@ static void hist_trigger_show(struct seq_file *m, seq_puts(m, "\n\n"); =20 seq_puts(m, "# event histogram\n#\n# trigger info: "); - data->ops->print(m, data); + data->cmd_ops->print(m, data); seq_puts(m, "#\n\n"); =20 hist_data =3D data->private_data; @@ -6016,7 +6016,7 @@ static void hist_trigger_debug_show(struct seq_file *= m, seq_puts(m, "\n\n"); =20 seq_puts(m, "# event histogram\n#\n# trigger info: "); - data->ops->print(m, data); + data->cmd_ops->print(m, data); seq_puts(m, "#\n\n"); =20 hist_data =3D data->private_data; @@ -6326,20 +6326,21 @@ static void event_hist_trigger_free(struct event_tr= igger_data *data) free_hist_pad(); } =20 -static const struct event_trigger_ops event_hist_trigger_ops =3D { - .trigger =3D event_hist_trigger, - .print =3D event_hist_trigger_print, - .init =3D event_hist_trigger_init, - .free =3D event_hist_trigger_free, -}; - static int event_hist_trigger_named_init(struct event_trigger_data *data) { + int ret; + data->ref++; =20 save_named_trigger(data->named_data->name, data); =20 - return event_hist_trigger_init(data->named_data); + ret =3D event_hist_trigger_init(data->named_data); + if (ret < 0) { + kfree(data->cmd_ops); + data->cmd_ops =3D &trigger_hist_cmd; + } + + return ret; } =20 static void event_hist_trigger_named_free(struct event_trigger_data *data) @@ -6351,18 +6352,14 @@ static void event_hist_trigger_named_free(struct ev= ent_trigger_data *data) =20 data->ref--; if (!data->ref) { + struct event_command *cmd_ops =3D data->cmd_ops; + del_named_trigger(data); trigger_data_free(data); + kfree(cmd_ops); } } =20 -static const struct event_trigger_ops event_hist_trigger_named_ops =3D { - .trigger =3D event_hist_trigger, - .print =3D event_hist_trigger_print, - .init =3D event_hist_trigger_named_init, - .free =3D event_hist_trigger_named_free, -}; - static void hist_clear(struct event_trigger_data *data) { struct hist_trigger_data *hist_data =3D data->private_data; @@ -6556,13 +6553,24 @@ static int hist_register_trigger(char *glob, data->paused =3D true; =20 if (named_data) { + struct event_command *cmd_ops; + data->private_data =3D named_data->private_data; set_named_trigger_data(data, named_data); - data->ops =3D &event_hist_trigger_named_ops; + /* Copy the command ops and update some of the functions */ + cmd_ops =3D kmalloc(sizeof(*cmd_ops), GFP_KERNEL); + if (!cmd_ops) { + ret =3D -ENOMEM; + goto out; + } + *cmd_ops =3D *data->cmd_ops; + cmd_ops->init =3D event_hist_trigger_named_init; + cmd_ops->free =3D event_hist_trigger_named_free; + data->cmd_ops =3D cmd_ops; } =20 - if (data->ops->init) { - ret =3D data->ops->init(data); + if (data->cmd_ops->init) { + ret =3D data->cmd_ops->init(data); if (ret < 0) goto out; } @@ -6676,8 +6684,8 @@ static void hist_unregister_trigger(char *glob, } } =20 - if (test && test->ops->free) - test->ops->free(test); + if (test && test->cmd_ops->free) + test->cmd_ops->free(test); =20 if (hist_data->enable_timestamps) { if (!hist_data->remove || test) @@ -6729,8 +6737,8 @@ static void hist_unreg_all(struct trace_event_file *f= ile) update_cond_flag(file); if (hist_data->enable_timestamps) tracing_set_filter_buffering(file->tr, false); - if (test->ops->free) - test->ops->free(test); + if (test->cmd_ops->free) + test->cmd_ops->free(test); } } } @@ -6902,12 +6910,15 @@ static struct event_command trigger_hist_cmd =3D { .name =3D "hist", .trigger_type =3D ETT_EVENT_HIST, .flags =3D EVENT_CMD_FL_NEEDS_REC, - .trigger_ops =3D &event_hist_trigger_ops, .parse =3D event_hist_trigger_parse, .reg =3D hist_register_trigger, .unreg =3D hist_unregister_trigger, .unreg_all =3D hist_unreg_all, .set_filter =3D set_trigger_filter, + .trigger =3D event_hist_trigger, + .print =3D event_hist_trigger_print, + .init =3D event_hist_trigger_init, + .free =3D event_hist_trigger_free, }; =20 __init int register_trigger_hist_cmd(void) @@ -6939,22 +6950,6 @@ hist_enable_trigger(struct event_trigger_data *data, } } =20 -static const struct event_trigger_ops hist_enable_trigger_ops =3D { - .trigger =3D hist_enable_trigger, - .count_func =3D event_trigger_count, - .print =3D event_enable_trigger_print, - .init =3D event_trigger_init, - .free =3D event_enable_trigger_free, -}; - -static const struct event_trigger_ops hist_disable_trigger_ops =3D { - .trigger =3D hist_enable_trigger, - .count_func =3D event_trigger_count, - .print =3D event_enable_trigger_print, - .init =3D event_trigger_init, - .free =3D event_enable_trigger_free, -}; - static void hist_enable_unreg_all(struct trace_event_file *file) { struct event_trigger_data *test, *n; @@ -6964,8 +6959,8 @@ static void hist_enable_unreg_all(struct trace_event_= file *file) list_del_rcu(&test->list); update_cond_flag(file); trace_event_trigger_enable_disable(file, 0); - if (test->ops->free) - test->ops->free(test); + if (test->cmd_ops->free) + test->cmd_ops->free(test); } } } @@ -6973,23 +6968,31 @@ static void hist_enable_unreg_all(struct trace_even= t_file *file) static struct event_command trigger_hist_enable_cmd =3D { .name =3D ENABLE_HIST_STR, .trigger_type =3D ETT_HIST_ENABLE, - .trigger_ops =3D &hist_enable_trigger_ops, .parse =3D event_enable_trigger_parse, .reg =3D event_enable_register_trigger, .unreg =3D event_enable_unregister_trigger, .unreg_all =3D hist_enable_unreg_all, .set_filter =3D set_trigger_filter, + .trigger =3D hist_enable_trigger, + .count_func =3D event_trigger_count, + .print =3D event_enable_trigger_print, + .init =3D event_trigger_init, + .free =3D event_enable_trigger_free, }; =20 static struct event_command trigger_hist_disable_cmd =3D { .name =3D DISABLE_HIST_STR, .trigger_type =3D ETT_HIST_ENABLE, - .trigger_ops =3D &hist_disable_trigger_ops, .parse =3D event_enable_trigger_parse, .reg =3D event_enable_register_trigger, .unreg =3D event_enable_unregister_trigger, .unreg_all =3D hist_enable_unreg_all, .set_filter =3D set_trigger_filter, + .trigger =3D hist_enable_trigger, + .count_func =3D event_trigger_count, + .print =3D event_enable_trigger_print, + .init =3D event_trigger_init, + .free =3D event_enable_trigger_free, }; =20 static __init void unregister_trigger_hist_enable_disable_cmds(void) diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_event= s_trigger.c index 576bad18bcdb..7795af600466 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -32,14 +32,14 @@ static inline void data_ops_trigger(struct event_trigge= r_data *data, struct trace_buffer *buffer, void *rec, struct ring_buffer_event *event) { - const struct event_trigger_ops *ops =3D data->ops; + const struct event_command *cmd_ops =3D data->cmd_ops; =20 if (data->flags & EVENT_TRIGGER_FL_COUNT) { - if (!ops->count_func(data, buffer, rec, event)) + if (!cmd_ops->count_func(data, buffer, rec, event)) return; } =20 - ops->trigger(data, buffer, rec, event); + cmd_ops->trigger(data, buffer, rec, event); } =20 /** @@ -205,7 +205,7 @@ static int trigger_show(struct seq_file *m, void *v) } =20 data =3D list_entry(v, struct event_trigger_data, list); - data->ops->print(m, data); + data->cmd_ops->print(m, data); =20 return 0; } @@ -422,7 +422,7 @@ bool event_trigger_count(struct event_trigger_data *dat= a, } =20 /** - * event_trigger_print - Generic event_trigger_ops @print implementation + * event_trigger_print - Generic event_command @print implementation * @name: The name of the event trigger * @m: The seq_file being printed to * @data: Trigger-specific data @@ -457,7 +457,7 @@ event_trigger_print(const char *name, struct seq_file *= m, } =20 /** - * event_trigger_init - Generic event_trigger_ops @init implementation + * event_trigger_init - Generic event_command @init implementation * @data: Trigger-specific data * * Common implementation of event trigger initialization. @@ -474,7 +474,7 @@ int event_trigger_init(struct event_trigger_data *data) } =20 /** - * event_trigger_free - Generic event_trigger_ops @free implementation + * event_trigger_free - Generic event_command @free implementation * @data: Trigger-specific data * * Common implementation of event trigger de-initialization. @@ -536,8 +536,8 @@ clear_event_triggers(struct trace_array *tr) list_for_each_entry_safe(data, n, &file->triggers, list) { trace_event_trigger_enable_disable(file, 0); list_del_rcu(&data->list); - if (data->ops->free) - data->ops->free(data); + if (data->cmd_ops->free) + data->cmd_ops->free(data); } } } @@ -600,8 +600,8 @@ static int register_trigger(char *glob, return -EEXIST; } =20 - if (data->ops->init) { - ret =3D data->ops->init(data); + if (data->cmd_ops->init) { + ret =3D data->cmd_ops->init(data); if (ret < 0) return ret; } @@ -639,8 +639,8 @@ static bool try_unregister_trigger(char *glob, } =20 if (data) { - if (data->ops->free) - data->ops->free(data); + if (data->cmd_ops->free) + data->cmd_ops->free(data); =20 return true; } @@ -875,10 +875,9 @@ struct event_trigger_data *trigger_data_alloc(struct e= vent_command *cmd_ops, return NULL; =20 trigger_data->count =3D -1; - trigger_data->ops =3D cmd_ops->trigger_ops; trigger_data->cmd_ops =3D cmd_ops; trigger_data->private_data =3D private_data; - if (param && cmd_ops->trigger_ops->count_func) + if (param && cmd_ops->count_func) trigger_data->flags |=3D EVENT_TRIGGER_FL_COUNT; =20 INIT_LIST_HEAD(&trigger_data->list); @@ -1401,41 +1400,33 @@ traceoff_trigger_print(struct seq_file *m, struct e= vent_trigger_data *data) data->filter_str); } =20 -static const struct event_trigger_ops traceon_trigger_ops =3D { - .trigger =3D traceon_trigger, - .count_func =3D traceon_count_func, - .print =3D traceon_trigger_print, - .init =3D event_trigger_init, - .free =3D event_trigger_free, -}; - -static const struct event_trigger_ops traceoff_trigger_ops =3D { - .trigger =3D traceoff_trigger, - .count_func =3D traceoff_count_func, - .print =3D traceoff_trigger_print, - .init =3D event_trigger_init, - .free =3D event_trigger_free, -}; - static struct event_command trigger_traceon_cmd =3D { .name =3D "traceon", .trigger_type =3D ETT_TRACE_ONOFF, - .trigger_ops =3D &traceon_trigger_ops, .parse =3D event_trigger_parse, .reg =3D register_trigger, .unreg =3D unregister_trigger, .set_filter =3D set_trigger_filter, + .trigger =3D traceon_trigger, + .count_func =3D traceon_count_func, + .print =3D traceon_trigger_print, + .init =3D event_trigger_init, + .free =3D event_trigger_free, }; =20 static struct event_command trigger_traceoff_cmd =3D { .name =3D "traceoff", .trigger_type =3D ETT_TRACE_ONOFF, .flags =3D EVENT_CMD_FL_POST_TRIGGER, - .trigger_ops =3D &traceoff_trigger_ops, .parse =3D event_trigger_parse, .reg =3D register_trigger, .unreg =3D unregister_trigger, .set_filter =3D set_trigger_filter, + .trigger =3D traceoff_trigger, + .count_func =3D traceoff_count_func, + .print =3D traceoff_trigger_print, + .init =3D event_trigger_init, + .free =3D event_trigger_free, }; =20 #ifdef CONFIG_TRACER_SNAPSHOT @@ -1483,22 +1474,18 @@ snapshot_trigger_print(struct seq_file *m, struct e= vent_trigger_data *data) data->filter_str); } =20 -static const struct event_trigger_ops snapshot_trigger_ops =3D { - .trigger =3D snapshot_trigger, - .count_func =3D event_trigger_count, - .print =3D snapshot_trigger_print, - .init =3D event_trigger_init, - .free =3D event_trigger_free, -}; - static struct event_command trigger_snapshot_cmd =3D { .name =3D "snapshot", .trigger_type =3D ETT_SNAPSHOT, - .trigger_ops =3D &snapshot_trigger_ops, .parse =3D event_trigger_parse, .reg =3D register_snapshot_trigger, .unreg =3D unregister_snapshot_trigger, .set_filter =3D set_trigger_filter, + .trigger =3D snapshot_trigger, + .count_func =3D event_trigger_count, + .print =3D snapshot_trigger_print, + .init =3D event_trigger_init, + .free =3D event_trigger_free, }; =20 static __init int register_trigger_snapshot_cmd(void) @@ -1552,23 +1539,19 @@ stacktrace_trigger_print(struct seq_file *m, struct= event_trigger_data *data) data->filter_str); } =20 -static const struct event_trigger_ops stacktrace_trigger_ops =3D { - .trigger =3D stacktrace_trigger, - .count_func =3D event_trigger_count, - .print =3D stacktrace_trigger_print, - .init =3D event_trigger_init, - .free =3D event_trigger_free, -}; - static struct event_command trigger_stacktrace_cmd =3D { .name =3D "stacktrace", .trigger_type =3D ETT_STACKTRACE, - .trigger_ops =3D &stacktrace_trigger_ops, .flags =3D EVENT_CMD_FL_POST_TRIGGER, .parse =3D event_trigger_parse, .reg =3D register_trigger, .unreg =3D unregister_trigger, .set_filter =3D set_trigger_filter, + .trigger =3D stacktrace_trigger, + .count_func =3D event_trigger_count, + .print =3D stacktrace_trigger_print, + .init =3D event_trigger_init, + .free =3D event_trigger_free, }; =20 static __init int register_trigger_stacktrace_cmd(void) @@ -1665,22 +1648,6 @@ void event_enable_trigger_free(struct event_trigger_= data *data) } } =20 -static const struct event_trigger_ops event_enable_trigger_ops =3D { - .trigger =3D event_enable_trigger, - .count_func =3D event_enable_count_func, - .print =3D event_enable_trigger_print, - .init =3D event_trigger_init, - .free =3D event_enable_trigger_free, -}; - -static const struct event_trigger_ops event_disable_trigger_ops =3D { - .trigger =3D event_enable_trigger, - .count_func =3D event_enable_count_func, - .print =3D event_enable_trigger_print, - .init =3D event_trigger_init, - .free =3D event_enable_trigger_free, -}; - int event_enable_trigger_parse(struct event_command *cmd_ops, struct trace_event_file *file, char *glob, char *cmd, char *param_and_filter) @@ -1810,8 +1777,8 @@ int event_enable_register_trigger(char *glob, } } =20 - if (data->ops->init) { - ret =3D data->ops->init(data); + if (data->cmd_ops->init) { + ret =3D data->cmd_ops->init(data); if (ret < 0) return ret; } @@ -1851,28 +1818,36 @@ void event_enable_unregister_trigger(char *glob, } } =20 - if (data && data->ops->free) - data->ops->free(data); + if (data && data->cmd_ops->free) + data->cmd_ops->free(data); } =20 static struct event_command trigger_enable_cmd =3D { .name =3D ENABLE_EVENT_STR, .trigger_type =3D ETT_EVENT_ENABLE, - .trigger_ops =3D &event_enable_trigger_ops, .parse =3D event_enable_trigger_parse, .reg =3D event_enable_register_trigger, .unreg =3D event_enable_unregister_trigger, .set_filter =3D set_trigger_filter, + .trigger =3D event_enable_trigger, + .count_func =3D event_enable_count_func, + .print =3D event_enable_trigger_print, + .init =3D event_trigger_init, + .free =3D event_enable_trigger_free, }; =20 static struct event_command trigger_disable_cmd =3D { .name =3D DISABLE_EVENT_STR, .trigger_type =3D ETT_EVENT_ENABLE, - .trigger_ops =3D &event_disable_trigger_ops, .parse =3D event_enable_trigger_parse, .reg =3D event_enable_register_trigger, .unreg =3D event_enable_unregister_trigger, .set_filter =3D set_trigger_filter, + .trigger =3D event_enable_trigger, + .count_func =3D event_enable_count_func, + .print =3D event_enable_trigger_print, + .init =3D event_trigger_init, + .free =3D event_enable_trigger_free, }; =20 static __init void unregister_trigger_enable_disable_cmds(void) --=20 2.51.0 From nobody Mon Dec 1 21:31:22 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9982B23185D for ; Fri, 28 Nov 2025 01:23:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; cv=none; b=AM5Sqld3fIixx7FDS2QPuDKp4TfANelRwRqLXhwuQkerIPOiwuRlsroulRyBH+h50P5t1YStE/y4JxZKabZryuBU11cYHF3NNqHHHjcKHHHuiOkoWCL2EZ5/Q7sjNaby84Dkbsafs8kv9gc9f1jwbQmW9IyLnC+HtBakFYAvpe0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; c=relaxed/simple; bh=TpSckzcuTVMp77oFii+eero2AXWQR14UYGLmXXKZg1o=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=oBESXWMTzWQ4eJcIIXBJn/y6ZQgU468bdRKcbvX5mS5ma6puhRRDw+apviMesctSBMP9n61w1zmKIy1fqAYpECDeaHhmUPjOaFl/T5a/W2S4g1ABZwVlqksv9bfMAgfrxIeUVB9vp3gkoGkH34gcDonz3Xwong+AQw1z+Hv+nO0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PH/fB1zM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PH/fB1zM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 71D24C4CEF8; Fri, 28 Nov 2025 01:23:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764293002; bh=TpSckzcuTVMp77oFii+eero2AXWQR14UYGLmXXKZg1o=; h=Date:From:To:Cc:Subject:References:From; b=PH/fB1zMobWmN4D1U0slCVknfcjTZLHGmBRPxYOg/dYP+YFuYpRXhP7eNnfWEFKiC iwQUu9jJXF5gzaf1gAyk3mcR7skk1oddNpGRbQhc1xDL+XPvGwl/0T7m1a8REsAYKL +ckmlys2qjBSOA4ynQ8dC6JMGHEHN+TE2Mk6pNJrt15UfKJSRzuDzVFjzjkEbVGNRY c8oHAb8ZrUZxUyTqjCy9Egp0yPiBJrvPFIO7iRglxRnANotso5xby6Y8lFuItIK6Fj iEkPlKBwmLanB+FFYZVvRgMHV//FtPyiPa8jynZXjQ6h7w6wlUpbbfayh5cYcDbWFO E/AMxONExFrJA== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vOnDY-00000006ggj-0ZDM; Thu, 27 Nov 2025 20:24:12 -0500 Message-ID: <20251128012411.987104022@kernel.org> User-Agent: quilt/0.68 Date: Thu, 27 Nov 2025 20:23:38 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Tom Zanussi Subject: [for-next][PATCH 07/13] tracing: Remove unneeded event_mutex lock in event_trigger_regex_release() References: <20251128012331.307010654@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt In event_trigger_regex_release(), the only code is: mutex_lock(&event_mutex); if (file->f_mode & FMODE_READ) seq_release(inode, file); mutex_unlock(&event_mutex); return 0; There's nothing special about the file->f_mode or the seq_release() that requires any locking. Remove the unnecessary locks. Cc: Mark Rutland Cc: Mathieu Desnoyers Cc: Andrew Morton Cc: Tom Zanussi Link: https://patch.msgid.link/20251125214031.975879283@kernel.org Acked-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_events_trigger.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_event= s_trigger.c index 7795af600466..e5dcfcbb2cd5 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -314,13 +314,9 @@ static ssize_t event_trigger_regex_write(struct file *= file, =20 static int event_trigger_regex_release(struct inode *inode, struct file *f= ile) { - mutex_lock(&event_mutex); - if (file->f_mode & FMODE_READ) seq_release(inode, file); =20 - mutex_unlock(&event_mutex); - return 0; } =20 --=20 2.51.0 From nobody Mon Dec 1 21:31:22 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA36A23817E for ; Fri, 28 Nov 2025 01:23:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; cv=none; b=f+np1S40tyJWJ6f9L4iRtnP7exJLdPD1TT4PlUKYP46eDRwZngtjEqdCVT+V3EIXUo3Bu218aMQicgxgs9UJ11Kl4457uGRX6qvKARSlUELt83CGFOp6gaJvWbphq/I3vH58zM4r5T+QEVdPIBLyq/nxBNZNKv/9Gk4XKKxUhCQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293002; c=relaxed/simple; bh=38p3e3WjY5GaqZjp+K1iy1pJnX35CZ1f+nBXLEr1z0o=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=oOhPiuCcYGaS15PEQHF6r94qpcmaaB2Y15Ca245ocTJ6XknMqw5P09YlLiVEHIrdQD0qLUAow00E+almqAp524GDOl8Iso8zHNV8WHX0GOAQhuhaOLl49k28quoobgSl6dQZsxlAbasoWdyfKWA9+rZhlE0HuoNE/H0NtjCbjkk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fjyVRdAJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fjyVRdAJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9DCAEC113D0; Fri, 28 Nov 2025 01:23:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764293002; bh=38p3e3WjY5GaqZjp+K1iy1pJnX35CZ1f+nBXLEr1z0o=; h=Date:From:To:Cc:Subject:References:From; b=fjyVRdAJ/Pj/vAwhkQkLPe54G2jcnwM4OGg5AMQuVWAYw25QBbemMc5Acl+jq1H8Q /hQyi5tng79WCqDMDQ7f3i29gyK7CkBzMYiIB4yvS74Qjem3IeGPRClvLMUNAXYJMc +YwyQrVOJ3yxGxJnyBDE3o1XO3smYqkKUbRoRKjPAyT7O0YFEohPmFk23uOa805C7K 9kfe/O1dVs/x1O2EdTTTz7P/rEbejhjxCKqNVWsO55yxD/xqAd2wqLGlam+ZqYyjJd 0mmC73Ta9JySavPZLyCP5A5siUE6i7F9j0BGyZeRPDEhhtXrTgi8Dq6uAIoafEUyj+ 8yVf7gvNyroeQ== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vOnDY-00000006ghF-1Gru; Thu, 27 Nov 2025 20:24:12 -0500 Message-ID: <20251128012412.155385563@kernel.org> User-Agent: quilt/0.68 Date: Thu, 27 Nov 2025 20:23:39 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Tom Zanussi Subject: [for-next][PATCH 08/13] tracing: Add bulk garbage collection of freeing event_trigger_data References: <20251128012331.307010654@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt The event trigger data requires a full tracepoint_synchronize_unregister() call before freeing. That call can take 100s of milliseconds to complete. In order to allow for bulk freeing of the trigger data, it can not call the tracepoint_synchronize_unregister() for every individual trigger data being free. Create a kthread that gets created the first time a trigger data is freed, and have it use the lockless llist to get the list of data to free, run the tracepoint_synchronize_unregister() then free everything in the list. By freeing hundreds of event_trigger_data elements together, it only requires two runs of the synchronization function, and not hundreds of runs. This speeds up the operation by orders of magnitude (milliseconds instead of several seconds). Cc: Mark Rutland Cc: Mathieu Desnoyers Cc: Andrew Morton Cc: Tom Zanussi Link: https://patch.msgid.link/20251125214032.151674992@kernel.org Acked-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.h | 2 ++ kernel/trace/trace_events_trigger.c | 55 +++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 901aad30099b..a3aa225ed50a 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -22,6 +22,7 @@ #include #include #include +#include =20 #include "pid_list.h" =20 @@ -1808,6 +1809,7 @@ struct event_trigger_data { char *name; struct list_head named_list; struct event_trigger_data *named_data; + struct llist_node llist; }; =20 /* Avoid typos */ diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_event= s_trigger.c index e5dcfcbb2cd5..3b97c242b795 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -6,6 +6,7 @@ */ =20 #include +#include #include #include #include @@ -17,15 +18,63 @@ static LIST_HEAD(trigger_commands); static DEFINE_MUTEX(trigger_cmd_mutex); =20 +static struct task_struct *trigger_kthread; +static struct llist_head trigger_data_free_list; +static DEFINE_MUTEX(trigger_data_kthread_mutex); + +/* Bulk garbage collection of event_trigger_data elements */ +static int trigger_kthread_fn(void *ignore) +{ + struct event_trigger_data *data, *tmp; + struct llist_node *llnodes; + + /* Once this task starts, it lives forever */ + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + if (llist_empty(&trigger_data_free_list)) + schedule(); + + __set_current_state(TASK_RUNNING); + + llnodes =3D llist_del_all(&trigger_data_free_list); + + /* make sure current triggers exit before free */ + tracepoint_synchronize_unregister(); + + llist_for_each_entry_safe(data, tmp, llnodes, llist) + kfree(data); + } + + return 0; +} + void trigger_data_free(struct event_trigger_data *data) { if (data->cmd_ops->set_filter) data->cmd_ops->set_filter(NULL, data, NULL); =20 - /* make sure current triggers exit before free */ - tracepoint_synchronize_unregister(); + if (unlikely(!trigger_kthread)) { + guard(mutex)(&trigger_data_kthread_mutex); + /* Check again after taking mutex */ + if (!trigger_kthread) { + struct task_struct *kthread; + + kthread =3D kthread_create(trigger_kthread_fn, NULL, + "trigger_data_free"); + if (!IS_ERR(kthread)) + WRITE_ONCE(trigger_kthread, kthread); + } + } + + if (!trigger_kthread) { + /* Do it the slow way */ + tracepoint_synchronize_unregister(); + kfree(data); + return; + } =20 - kfree(data); + llist_add(&data->llist, &trigger_data_free_list); + wake_up_process(trigger_kthread); } =20 static inline void data_ops_trigger(struct event_trigger_data *data, --=20 2.51.0 From nobody Mon Dec 1 21:31:22 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4B73C23DEB6 for ; Fri, 28 Nov 2025 01:23:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293003; cv=none; b=rt5LD8QeT7UkHpt94gx1hm9Xpfw1AFPevkrlPJ3DrWUCTWiBQ3q9/mSguVSKRM0H4CPdEY0O5ViQSCDiiIWmfC+oQ9m7OkIsieB7QY8O39afFy+8NGJM1WqYBsrtNJbzEta5dbVxq5/PiAcBs83vkpfS0YiSbxI7CdmhpZqnz88= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293003; c=relaxed/simple; bh=apq05GGh9TDvr8Z54lwXs6RPXreVP+Ey59iwwM/ZS3Q=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=deKqTp3Em+XGqDdm0tppzNH97rLqZU7Pn1PHsax54VifVov5etq1P7Cv4SF/rXa0AYuJaf5CpObd4m/eB2LX8EsJf5qpcfT844T0InSuMCrDwcM6+5v11crpPOoaJNcWXs60YnHVL0LEg9IrtZzYCUxmNJtrhf/7jGfshPmr+mY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SP0dxIuO; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SP0dxIuO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CF424C4CEF8; Fri, 28 Nov 2025 01:23:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764293002; bh=apq05GGh9TDvr8Z54lwXs6RPXreVP+Ey59iwwM/ZS3Q=; h=Date:From:To:Cc:Subject:References:From; b=SP0dxIuOoyIJrYSmB06iUrW8tqgJWsP+A+R4yi18S7KXhbbFZPhQrlsMJRMwCUrMd 0zy8yTDduShOnUe16xyoFNJn05w7Z0yTpGFiiq4zmxOg87dBDaAam8uMrkGnEpGTOx UwikLxjxbQSyR6AVl4IkbRfwa1V5SpPA8JUupNXQv8yhmyN1dwnPeyt7d23px1VulQ FKlR3vT1J13P3gShEP2eQAcSOoOGWjtvFHLJ9CAByirmNdYSt0qsHrB3rB4ksm3Nn5 1ykHPCUODCkaKGMF4Ji6pD8bfBk23DD1sGj83Ubu7Plin2U9UWIFKaghGGyx8fMtYM x64QuWCYwEwkw== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vOnDY-00000006ghk-1xes; Thu, 27 Nov 2025 20:24:12 -0500 Message-ID: <20251128012412.322648554@kernel.org> User-Agent: quilt/0.68 Date: Thu, 27 Nov 2025 20:23:40 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Tom Zanussi Subject: [for-next][PATCH 09/13] tracing: Use strim() in trigger_process_regex() instead of skip_spaces() References: <20251128012331.307010654@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt The function trigger_process_regex() is called by a few functions, where only one calls strim() on the buffer passed to it. That leaves the other functions not trimming the end of the buffer passed in and making it a little inconsistent. Remove the strim() from event_trigger_regex_write() and have trigger_process_regex() use strim() instead of skip_spaces(). The buff variable is not passed in as const, so it can be modified. Cc: Mark Rutland Cc: Mathieu Desnoyers Cc: Andrew Morton Cc: Tom Zanussi Link: https://patch.msgid.link/20251125214032.323747707@kernel.org Acked-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_events_trigger.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_event= s_trigger.c index 3b97c242b795..96aad82b1628 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -308,7 +308,8 @@ int trigger_process_regex(struct trace_event_file *file= , char *buff) char *command, *next; struct event_command *p; =20 - next =3D buff =3D skip_spaces(buff); + next =3D buff =3D strim(buff); + command =3D strsep(&next, ": \t"); if (next) { next =3D skip_spaces(next); @@ -345,8 +346,6 @@ static ssize_t event_trigger_regex_write(struct file *f= ile, if (IS_ERR(buf)) return PTR_ERR(buf); =20 - strim(buf); - guard(mutex)(&event_mutex); =20 event_file =3D event_file_file(file); --=20 2.51.0 From nobody Mon Dec 1 21:31:22 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4CDAC23E34C for ; Fri, 28 Nov 2025 01:23:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293003; cv=none; b=ULA/9HGHJ5PjjYCftORJSVvxC5pT9HsFUNrX9kWWh7uUQ6pHO90jTzx5Rj8t7GS5ojNbzVUg9iT7lovqMg5MrR9P3EVC9V5j55F0UpO/0c1UoLKPsyvz/7w4L/J3WTsWh32Z3xwXi62jIFB2e+z3Gf0c67oCo53ib3Lx/a1ZhQo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293003; c=relaxed/simple; bh=IVdzAxviZeFmt9X8CPvuewU0RyKQAGIWqX3R6hkAdFY=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=jJ1vMswlHSfxWvMgcXi8Up9JIhBsvrpWo3YcAejbH1BNAgINMAxF9z8Su7q9m90eugAL/p11XbWx3eXeg/rQlD+kZQUkHBnuzVBO3AvSl0u31H0pvcl0RGOs3wuaIPbmFXIkfM5NN5Megdg/M/d4CEENq/fY7Y/uUiZvYDqoNOs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HHi3QdG9; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HHi3QdG9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EECBAC19423; Fri, 28 Nov 2025 01:23:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764293003; bh=IVdzAxviZeFmt9X8CPvuewU0RyKQAGIWqX3R6hkAdFY=; h=Date:From:To:Cc:Subject:References:From; b=HHi3QdG96HbllxPMzWrXngfNuiWxrAw8QYnT7AZBWi+UOHXIosSr3tKYyETxEHXOQ Nz+vTFWeT/tfS6uvoEHXxA20hIN6M8hJYG+FjGKuYWGms6DxQECWKIOci54NgWM9wp tB0piFHdt5yJgetlbd13NvI+BQleufZMpO9VPz6tQ/SFJ9i3COJ6KMR1G/JZrlnplv zzWqjVKz+AR/Gw07lrnxM1+rEV9BC6qIzcn5+77O5KVjO55kLtPVzvNPCQvtygNnMG qtSxEDs+z5Me1rLYemfS3QmRNRUulX8wi0MpXg1ex+HxEeNMFQUBMsh2HmnqZaSEAL AfYbi04OCzwjA== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vOnDY-00000006giF-2f5z; Thu, 27 Nov 2025 20:24:12 -0500 Message-ID: <20251128012412.486546486@kernel.org> User-Agent: quilt/0.68 Date: Thu, 27 Nov 2025 20:23:41 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Tom Zanussi Subject: [for-next][PATCH 10/13] ftrace: Allow tracing of some of the tracing code References: <20251128012331.307010654@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt There is times when tracing the tracing infrastructure can be useful for debugging the tracing code. Currently all files in the tracing directory are set to "notrace" the functions. Add a new config option FUNCTION_SELF_TRACING that will allow some of the files in the tracing infrastructure to be traced. It requires a config to enable because it will add noise to the function tracer if events and other tracing features are enabled. Tracing functions and events together is quite common, so not tracing the event code should be the default. Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: Andrew Morton Cc: Mark Rutland Cc: Tom Zanussi Link: https://patch.msgid.link/20251120181514.736f2d5f@gandalf.local.home Signed-off-by: Steven Rostedt (Google) --- kernel/trace/Kconfig | 14 ++++++++++++++ kernel/trace/Makefile | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 99283b2dcfd6..e1214b9dc990 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -330,6 +330,20 @@ config DYNAMIC_FTRACE_WITH_ARGS depends on DYNAMIC_FTRACE depends on HAVE_DYNAMIC_FTRACE_WITH_ARGS =20 +config FUNCTION_SELF_TRACING + bool "Function trace tracing code" + depends on FUNCTION_TRACER + help + Normally all the tracing code is set to notrace, where the function + tracer will ignore all the tracing functions. Sometimes it is useful + for debugging to trace some of the tracing infratructure itself. + Enable this to allow some of the tracing infrastructure to be traced + by the function tracer. Note, this will likely add noise to function + tracing if events and other tracing features are enabled along with + function tracing. + + If unsure, say N. + config FPROBE bool "Kernel Function Probe (fprobe)" depends on HAVE_FUNCTION_GRAPH_FREGS && HAVE_FTRACE_GRAPH_FUNC diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index dcb4e02afc5f..fc5dcc888e13 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -16,6 +16,23 @@ obj-y +=3D trace_selftest_dynamic.o endif endif =20 +# Allow some files to be function traced +ifdef CONFIG_FUNCTION_SELF_TRACING +CFLAGS_trace_output.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_trace_seq.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_trace_stat.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_tracing_map.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_synth_event_gen_test.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_trace_events.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_trace_syscalls.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_trace_events_filter.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_trace_events_trigger.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_trace_events_synth.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_trace_events_hist.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_trace_events_user.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_trace_dynevent.o =3D $(CC_FLAGS_FTRACE) +endif + ifdef CONFIG_FTRACE_STARTUP_TEST CFLAGS_trace_kprobe_selftest.o =3D $(CC_FLAGS_FTRACE) obj-$(CONFIG_KPROBE_EVENTS) +=3D trace_kprobe_selftest.o --=20 2.51.0 From nobody Mon Dec 1 21:31:22 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4E43123E35B for ; Fri, 28 Nov 2025 01:23:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293003; cv=none; b=tVr6iNpodi6V28PHmYTEnEVN0xfpJFw4qaka0UglwQEt6sf2AJw8tXwAqHIxM8dlCt6jmWRqVkOjLPfTVyui5LGL0DaXtb7wQb8+1UpUI66RzrMU5DyiOjOKav3UINNEkLghKEAE+BAvvIB0u0pgs7uAfTtPvUTZJnorFCkO0A8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293003; c=relaxed/simple; bh=np0eLDp8SYvSYO771ibfOvtV9+LDDr8rGaeHXffJO9c=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=MFlEktk8g7neoXzgn00geVORd6eLGIyeIJhZpAt2ucgYvc+fcs5a5kDC2CuVJizYOMfAtLEmpcjqHAWVvpSJNKu7FkRxyTRDqpdFE3m1hoPkM4PSGia5NGE9bmyXTh2I2HVPjUd/z7KllzQ54Kxao4RyXbREHn/RSTAi1bSvVTQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WO3rzRrx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="WO3rzRrx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 108F4C19422; Fri, 28 Nov 2025 01:23:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764293003; bh=np0eLDp8SYvSYO771ibfOvtV9+LDDr8rGaeHXffJO9c=; h=Date:From:To:Cc:Subject:References:From; b=WO3rzRrx6qJFaiRgqTywRDZZQjt4gX611NwdGwYbFx0NQNCQzTWxEWIi7k7xUhktn 9IEACFAQhzG75kDloLucVsLeLD3xmA9nNZxTw2EzfoVdTP4sVqAeAoSJz6vSOIdIxG 1UptElf/yqewC1G3MKpTDc5qe4zEN6pxS0d1W8gPSeTnbXDtOtaI+QQbNQuM2i7538 X6JqEn5Ja977mZDn2ZXCQCMyYi8P8qpw4Z0uxZnGVq1sfJm+apuJ6P3jNAYV4JfKFV 4HJE4/DtmgOSfv06+EYpjFer4q3f7KyZCf/fXKbrLrJj3fA3J0R2ne9yNHtccsDELg W+d7XyM4iRXaQ== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vOnDY-00000006gik-3MMJ; Thu, 27 Nov 2025 20:24:12 -0500 Message-ID: <20251128012412.654828389@kernel.org> User-Agent: quilt/0.68 Date: Thu, 27 Nov 2025 20:23:42 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton Subject: [for-next][PATCH 11/13] tracing: Add boot-time backup of persistent ring buffer References: <20251128012331.307010654@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Masami Hiramatsu (Google)" Currently, the persistent ring buffer instance needs to be read before using it. This means we have to wait for boot up user space and dump the persistent ring buffer. However, in that case we can not start tracing on it from the kernel cmdline. To solve this limitation, this adds an option which allows to create a trace instance as a backup of the persistent ring buffer at boot. If user specifies trace_instance=3D=3D then the instance is made as a copy of the instance. For example, the below kernel cmdline records all syscalls, scheduler and interrupt events on the persistent ring buffer `boot_map` but before starting the tracing, it makes a `backup` instance from the `boot_map`. Thus, the `backup` instance has the previous boot events. 'reserve_mem=3D12M:4M:trace trace_instance=3Dboot_map@trace,syscalls:*,sche= d:*,irq:* trace_instance=3Dbackup=3Dboot_map' As you can see, this just make a copy of entire reserved area and make a backup instance on it. So you can release (or shrink) the backup instance after use it to save the memory usage. /sys/kernel/tracing/instances # free total used free shared buff/cache ava= ilable Mem: 1999284 55704 1930520 10132 13060 1= 914628 Swap: 0 0 0 /sys/kernel/tracing/instances # rmdir backup/ /sys/kernel/tracing/instances # free total used free shared buff/cache ava= ilable Mem: 1999284 40640 1945584 10132 13060 1= 929692 Swap: 0 0 0 Note: since there is no reason to make a copy of empty buffer, this backup only accepts a persistent ring buffer as the original instance. Also, since this backup is based on vmalloc(), it does not support user-space mmap(). Cc: Mathieu Desnoyers Link: https://patch.msgid.link/176377150002.219692.9425536150438129267.stgi= t@devnote2 Signed-off-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.c | 63 +++++++++++++++++++++++++++++++++++++++----- kernel/trace/trace.h | 1 + 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 032bdedca5d9..73f8b79f1b0c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -9004,8 +9004,8 @@ static int tracing_buffers_mmap(struct file *filp, st= ruct vm_area_struct *vma) struct trace_iterator *iter =3D &info->iter; int ret =3D 0; =20 - /* A memmap'ed buffer is not supported for user space mmap */ - if (iter->tr->flags & TRACE_ARRAY_FL_MEMMAP) + /* A memmap'ed and backup buffers are not supported for user space mmap */ + if (iter->tr->flags & (TRACE_ARRAY_FL_MEMMAP | TRACE_ARRAY_FL_VMALLOC)) return -ENODEV; =20 ret =3D get_snapshot_map(iter->tr); @@ -10520,6 +10520,8 @@ static int __remove_instance(struct trace_array *tr) reserve_mem_release_by_name(tr->range_name); kfree(tr->range_name); } + if (tr->flags & TRACE_ARRAY_FL_VMALLOC) + vfree((void *)tr->range_addr_start); =20 for (i =3D 0; i < tr->nr_topts; i++) { kfree(tr->topts[i].topts); @@ -11325,6 +11327,42 @@ __init static void do_allocate_snapshot(const char= *name) static inline void do_allocate_snapshot(const char *name) { } #endif =20 +__init static int backup_instance_area(const char *backup, + unsigned long *addr, phys_addr_t *size) +{ + struct trace_array *backup_tr; + void *allocated_vaddr =3D NULL; + + backup_tr =3D trace_array_get_by_name(backup, NULL); + if (!backup_tr) { + pr_warn("Tracing: Instance %s is not found.\n", backup); + return -ENOENT; + } + + if (!(backup_tr->flags & TRACE_ARRAY_FL_BOOT)) { + pr_warn("Tracing: Instance %s is not boot mapped.\n", backup); + trace_array_put(backup_tr); + return -EINVAL; + } + + *size =3D backup_tr->range_addr_size; + + allocated_vaddr =3D vzalloc(*size); + if (!allocated_vaddr) { + pr_warn("Tracing: Failed to allocate memory for copying instance %s (siz= e 0x%lx)\n", + backup, (unsigned long)*size); + trace_array_put(backup_tr); + return -ENOMEM; + } + + memcpy(allocated_vaddr, + (void *)backup_tr->range_addr_start, (size_t)*size); + *addr =3D (unsigned long)allocated_vaddr; + + trace_array_put(backup_tr); + return 0; +} + __init static void enable_instances(void) { struct trace_array *tr; @@ -11347,11 +11385,15 @@ __init static void enable_instances(void) char *flag_delim; char *addr_delim; char *rname __free(kfree) =3D NULL; + char *backup; =20 tok =3D strsep(&curr_str, ","); =20 - flag_delim =3D strchr(tok, '^'); - addr_delim =3D strchr(tok, '@'); + name =3D strsep(&tok, "=3D"); + backup =3D tok; + + flag_delim =3D strchr(name, '^'); + addr_delim =3D strchr(name, '@'); =20 if (addr_delim) *addr_delim++ =3D '\0'; @@ -11359,7 +11401,10 @@ __init static void enable_instances(void) if (flag_delim) *flag_delim++ =3D '\0'; =20 - name =3D tok; + if (backup) { + if (backup_instance_area(backup, &addr, &size) < 0) + continue; + } =20 if (flag_delim) { char *flag; @@ -11455,7 +11500,13 @@ __init static void enable_instances(void) tr->ref++; } =20 - if (start) { + /* + * Backup buffers can be freed but need vfree(). + */ + if (backup) + tr->flags |=3D TRACE_ARRAY_FL_VMALLOC; + + if (start || backup) { tr->flags |=3D TRACE_ARRAY_FL_BOOT | TRACE_ARRAY_FL_LAST_BOOT; tr->range_name =3D no_free_ptr(rname); } diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index a3aa225ed50a..666f9a2c189d 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -454,6 +454,7 @@ enum { TRACE_ARRAY_FL_LAST_BOOT =3D BIT(2), TRACE_ARRAY_FL_MOD_INIT =3D BIT(3), TRACE_ARRAY_FL_MEMMAP =3D BIT(4), + TRACE_ARRAY_FL_VMALLOC =3D BIT(5), }; =20 #ifdef CONFIG_MODULES --=20 2.51.0 From nobody Mon Dec 1 21:31:22 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A1297242925 for ; Fri, 28 Nov 2025 01:23:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293003; cv=none; b=q0BAISIiLVb0ueljmk5IM1fDkE2J+J09VpKEmuR3VkHYt3DAdvQrTSKfZTo7hpznYb4b4lLNCYiOASdnza4C4PWqGCSJmrCl9Bg0wXl75gOTi6eXfuqezhpRc4AbDXH8KoyWwUWHu668CD3sZkS+D3JZI8NiYYgd8QWmcu3XP70= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293003; c=relaxed/simple; bh=TLUuOqXnGushf0Jr/FSRy1s538WFZYim+igWXuzHBWI=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=Duy3pCOrwGPBYp1HrKNl7HTj/VhSj8X4LVrloEPWr6i/IA9hVJfeVo7G8BTPwGUUBk4Kz/xE86DKyoS6og10ppKrR/8p4WImZNf5mVnedJ6kO3D3FxS+YSOkpgbA+W0bPXPR0IcsDJiiiWVZvqSau+wMaIr3StxdsR/8DQTK21A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PG63tLJ3; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PG63tLJ3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 38462C113D0; Fri, 28 Nov 2025 01:23:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764293003; bh=TLUuOqXnGushf0Jr/FSRy1s538WFZYim+igWXuzHBWI=; h=Date:From:To:Cc:Subject:References:From; b=PG63tLJ34Rk2HaXpANyEYd6zjDttahbinKXOESZZkB84PTOBAi47jcWdrUMVwT5tm MHQNxWeQQHAqrlV11vVt2FUQstZEzE0JSgbmxk13cp9w1jyElSi/Hng5sQ2D+vLmoW NamyNuJyrvwZv8LuH6w8WYouyxDKqSp1CPGjouxHO/j4ETY/ZC82TQJQXNsKmVv/mX 4jNSiFtYfk8WesKEquh0NCiWxlBXMhGVtihQD5mK2G3mVLmSCQJZtHjRGEA9bKwuEG o7c6tWBLjeMQoITAMUjrjju44XdoDfBimC9VZUTVENkOpCPnTCMf5KrR/7QmVhf2N+ 2WcvUK08iqifw== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vOnDY-00000006gjE-484d; Thu, 27 Nov 2025 20:24:12 -0500 Message-ID: <20251128012412.821986731@kernel.org> User-Agent: quilt/0.68 Date: Thu, 27 Nov 2025 20:23:43 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Sven Schnelle , Xiaoqin Zhang , pengdonglin Subject: [for-next][PATCH 12/13] function_graph: Enable funcgraph-args and funcgraph-retaddr to work simultaneously References: <20251128012331.307010654@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: pengdonglin Currently, the funcgraph-args and funcgraph-retaddr features are mutually exclusive. This patch resolves this limitation by allowing funcgraph-retaddr to have an args array. To verify the change, use perf to trace vfs_write with both options enabled: Before: # perf ftrace -G vfs_write --graph-opts args,retaddr ...... down_read() { /* <-n_tty_write+0xa3/0x540 */ __cond_resched(); /* <-down_read+0x12/0x160 */ preempt_count_add(); /* <-down_read+0x3b/0x160 */ preempt_count_sub(); /* <-down_read+0x8b/0x160 */ } After: # perf ftrace -G vfs_write --graph-opts args,retaddr ...... down_read(sem=3D0xffff8880100bea78) { /* <-n_tty_write+0xa3/0x540 */ __cond_resched(); /* <-down_read+0x12/0x160 */ preempt_count_add(val=3D1); /* <-down_read+0x3b/0x160 */ preempt_count_sub(val=3D1); /* <-down_read+0x8b/0x160 */ } Cc: Steven Rostedt (Google) Cc: Sven Schnelle Cc: Masami Hiramatsu Cc: Xiaoqin Zhang Link: https://patch.msgid.link/20251125093425.2563849-1-dolinux.peng@gmail.= com Signed-off-by: pengdonglin Signed-off-by: Steven Rostedt (Google) --- include/linux/ftrace.h | 7 +-- kernel/trace/trace.h | 24 +++++++++- kernel/trace/trace_entries.h | 15 +++--- kernel/trace/trace_functions_graph.c | 71 ++++++++++++++++++---------- 4 files changed, 80 insertions(+), 37 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 7ded7df6e9b5..6ca9c6229d93 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -1126,17 +1126,14 @@ static inline void ftrace_init(void) { } */ struct ftrace_graph_ent { unsigned long func; /* Current function */ - int depth; + unsigned long depth; } __packed; =20 /* * Structure that defines an entry function trace with retaddr. - * It's already packed but the attribute "packed" is needed - * to remove extra padding at the end. */ struct fgraph_retaddr_ent { - unsigned long func; /* Current function */ - int depth; + struct ftrace_graph_ent ent; unsigned long retaddr; /* Return address */ } __packed; =20 diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 666f9a2c189d..c2b61bcd912f 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -964,7 +964,8 @@ extern int __trace_graph_entry(struct trace_array *tr, extern int __trace_graph_retaddr_entry(struct trace_array *tr, struct ftrace_graph_ent *trace, unsigned int trace_ctx, - unsigned long retaddr); + unsigned long retaddr, + struct ftrace_regs *fregs); extern void __trace_graph_return(struct trace_array *tr, struct ftrace_graph_ret *trace, unsigned int trace_ctx, @@ -2276,4 +2277,25 @@ static inline int rv_init_interface(void) */ #define FTRACE_TRAMPOLINE_MARKER ((unsigned long) INT_MAX) =20 +/* + * This is used to get the address of the args array based on + * the type of the entry. + */ +#define FGRAPH_ENTRY_ARGS(e) \ + ({ \ + unsigned long *_args; \ + struct ftrace_graph_ent_entry *_e =3D e; \ + \ + if (IS_ENABLED(CONFIG_FUNCTION_GRAPH_RETADDR) && \ + e->ent.type =3D=3D TRACE_GRAPH_RETADDR_ENT) { \ + struct fgraph_retaddr_ent_entry *_re; \ + \ + _re =3D (typeof(_re))_e; \ + _args =3D _re->args; \ + } else { \ + _args =3D _e->args; \ + } \ + _args; \ + }) + #endif /* _LINUX_KERNEL_TRACE_H */ diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h index de294ae2c5c5..f6a8d29c0d76 100644 --- a/kernel/trace/trace_entries.h +++ b/kernel/trace/trace_entries.h @@ -80,11 +80,11 @@ FTRACE_ENTRY(funcgraph_entry, ftrace_graph_ent_entry, F_STRUCT( __field_struct( struct ftrace_graph_ent, graph_ent ) __field_packed( unsigned long, graph_ent, func ) - __field_packed( unsigned int, graph_ent, depth ) + __field_packed( unsigned long, graph_ent, depth ) __dynamic_array(unsigned long, args ) ), =20 - F_printk("--> %ps (%u)", (void *)__entry->func, __entry->depth) + F_printk("--> %ps (%lu)", (void *)__entry->func, __entry->depth) ); =20 #ifdef CONFIG_FUNCTION_GRAPH_RETADDR @@ -95,13 +95,14 @@ FTRACE_ENTRY_PACKED(fgraph_retaddr_entry, fgraph_retadd= r_ent_entry, TRACE_GRAPH_RETADDR_ENT, =20 F_STRUCT( - __field_struct( struct fgraph_retaddr_ent, graph_ent ) - __field_packed( unsigned long, graph_ent, func ) - __field_packed( unsigned int, graph_ent, depth ) - __field_packed( unsigned long, graph_ent, retaddr ) + __field_struct( struct fgraph_retaddr_ent, graph_rent ) + __field_packed( unsigned long, graph_rent.ent, func ) + __field_packed( unsigned long, graph_rent.ent, depth ) + __field_packed( unsigned long, graph_rent, retaddr ) + __dynamic_array(unsigned long, args ) ), =20 - F_printk("--> %ps (%u) <- %ps", (void *)__entry->func, __entry->depth, + F_printk("--> %ps (%lu) <- %ps", (void *)__entry->func, __entry->depth, (void *)__entry->retaddr) ); =20 diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_func= tions_graph.c index d0513cfcd936..17c75cf2348e 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -36,14 +36,19 @@ struct fgraph_ent_args { unsigned long args[FTRACE_REGS_MAX_ARGS]; }; =20 +struct fgraph_retaddr_ent_args { + struct fgraph_retaddr_ent_entry ent; + /* Force the sizeof of args[] to have FTRACE_REGS_MAX_ARGS entries */ + unsigned long args[FTRACE_REGS_MAX_ARGS]; +}; + struct fgraph_data { struct fgraph_cpu_data __percpu *cpu_data; =20 /* Place to preserve last processed entry. */ union { struct fgraph_ent_args ent; - /* TODO allow retaddr to have args */ - struct fgraph_retaddr_ent_entry rent; + struct fgraph_retaddr_ent_args rent; }; struct ftrace_graph_ret_entry ret; int failed; @@ -160,20 +165,32 @@ int __trace_graph_entry(struct trace_array *tr, int __trace_graph_retaddr_entry(struct trace_array *tr, struct ftrace_graph_ent *trace, unsigned int trace_ctx, - unsigned long retaddr) + unsigned long retaddr, + struct ftrace_regs *fregs) { struct ring_buffer_event *event; struct trace_buffer *buffer =3D tr->array_buffer.buffer; struct fgraph_retaddr_ent_entry *entry; + int size; + + /* If fregs is defined, add FTRACE_REGS_MAX_ARGS long size words */ + size =3D sizeof(*entry) + (FTRACE_REGS_MAX_ARGS * !!fregs * sizeof(long)); =20 event =3D trace_buffer_lock_reserve(buffer, TRACE_GRAPH_RETADDR_ENT, - sizeof(*entry), trace_ctx); + size, trace_ctx); if (!event) return 0; entry =3D ring_buffer_event_data(event); - entry->graph_ent.func =3D trace->func; - entry->graph_ent.depth =3D trace->depth; - entry->graph_ent.retaddr =3D retaddr; + entry->graph_rent.ent =3D *trace; + entry->graph_rent.retaddr =3D retaddr; + +#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API + if (fregs) { + for (int i =3D 0; i < FTRACE_REGS_MAX_ARGS; i++) + entry->args[i] =3D ftrace_regs_get_argument(fregs, i); + } +#endif + trace_buffer_unlock_commit_nostack(buffer, event); =20 return 1; @@ -182,7 +199,8 @@ int __trace_graph_retaddr_entry(struct trace_array *tr, int __trace_graph_retaddr_entry(struct trace_array *tr, struct ftrace_graph_ent *trace, unsigned int trace_ctx, - unsigned long retaddr) + unsigned long retaddr, + struct ftrace_regs *fregs) { return 1; } @@ -267,7 +285,8 @@ static int graph_entry(struct ftrace_graph_ent *trace, if (IS_ENABLED(CONFIG_FUNCTION_GRAPH_RETADDR) && tracer_flags_is_set(tr, TRACE_GRAPH_PRINT_RETADDR)) { unsigned long retaddr =3D ftrace_graph_top_ret_addr(current); - ret =3D __trace_graph_retaddr_entry(tr, trace, trace_ctx, retaddr); + ret =3D __trace_graph_retaddr_entry(tr, trace, trace_ctx, + retaddr, fregs); } else { ret =3D __graph_entry(tr, trace, trace_ctx, fregs); } @@ -654,13 +673,9 @@ get_return_for_leaf(struct trace_iterator *iter, * Save current and next entries for later reference * if the output fails. */ - if (unlikely(curr->ent.type =3D=3D TRACE_GRAPH_RETADDR_ENT)) { - data->rent =3D *(struct fgraph_retaddr_ent_entry *)curr; - } else { - int size =3D min((int)sizeof(data->ent), (int)iter->ent_size); + int size =3D min_t(int, sizeof(data->rent), iter->ent_size); =20 - memcpy(&data->ent, curr, size); - } + memcpy(&data->rent, curr, size); /* * If the next event is not a return type, then * we only care about what type it is. Otherwise we can @@ -838,7 +853,7 @@ static void print_graph_retaddr(struct trace_seq *s, st= ruct fgraph_retaddr_ent_e trace_seq_puts(s, " /*"); =20 trace_seq_puts(s, " <-"); - seq_print_ip_sym_offset(s, entry->graph_ent.retaddr, trace_flags); + seq_print_ip_sym_offset(s, entry->graph_rent.retaddr, trace_flags); =20 if (comment) trace_seq_puts(s, " */"); @@ -984,7 +999,7 @@ print_graph_entry_leaf(struct trace_iterator *iter, trace_seq_printf(s, "%ps", (void *)ret_func); =20 if (args_size >=3D FTRACE_REGS_MAX_ARGS * sizeof(long)) { - print_function_args(s, entry->args, ret_func); + print_function_args(s, FGRAPH_ENTRY_ARGS(entry), ret_func); trace_seq_putc(s, ';'); } else trace_seq_puts(s, "();"); @@ -1036,7 +1051,7 @@ print_graph_entry_nested(struct trace_iterator *iter, args_size =3D iter->ent_size - offsetof(struct ftrace_graph_ent_entry, ar= gs); =20 if (args_size >=3D FTRACE_REGS_MAX_ARGS * sizeof(long)) - print_function_args(s, entry->args, func); + print_function_args(s, FGRAPH_ENTRY_ARGS(entry), func); else trace_seq_puts(s, "()"); =20 @@ -1218,11 +1233,14 @@ print_graph_entry(struct ftrace_graph_ent_entry *fi= eld, struct trace_seq *s, /* * print_graph_entry() may consume the current event, * thus @field may become invalid, so we need to save it. - * sizeof(struct ftrace_graph_ent_entry) is very small, - * it can be safely saved at the stack. + * This function is shared by ftrace_graph_ent_entry and + * fgraph_retaddr_ent_entry, the size of the latter one + * is larger, but it is very small and can be safely saved + * at the stack. */ struct ftrace_graph_ent_entry *entry; - u8 save_buf[sizeof(*entry) + FTRACE_REGS_MAX_ARGS * sizeof(long)]; + struct fgraph_retaddr_ent_entry *rentry; + u8 save_buf[sizeof(*rentry) + FTRACE_REGS_MAX_ARGS * sizeof(long)]; =20 /* The ent_size is expected to be as big as the entry */ if (iter->ent_size > sizeof(save_buf)) @@ -1451,12 +1469,17 @@ print_graph_function_flags(struct trace_iterator *i= ter, u32 flags) } #ifdef CONFIG_FUNCTION_GRAPH_RETADDR case TRACE_GRAPH_RETADDR_ENT: { - struct fgraph_retaddr_ent_entry saved; + /* + * ftrace_graph_ent_entry and fgraph_retaddr_ent_entry have + * similar functions and memory layouts. The only difference + * is that the latter one has an extra retaddr member, so + * they can share most of the logic. + */ struct fgraph_retaddr_ent_entry *rfield; =20 trace_assign_type(rfield, entry); - saved =3D *rfield; - return print_graph_entry((struct ftrace_graph_ent_entry *)&saved, s, ite= r, flags); + return print_graph_entry((struct ftrace_graph_ent_entry *)rfield, + s, iter, flags); } #endif case TRACE_GRAPH_RET: { --=20 2.51.0 From nobody Mon Dec 1 21:31:22 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7E24323F41A for ; Fri, 28 Nov 2025 01:23:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293003; cv=none; b=eURWgI/uCXeGfRGs2SqzLItDid6w86S/BmuaInJyG0fysbu14qlTbjuwtj5N1e7QORaXTX4ktOlAKHy3oAmfpgfhDMOOZUHwlEKEV3K6ih+3es0d7KfxYFnEGi8k5laS2rEpLH1H4N3JpHE0Lx/kx0+L+ChFoKzJ20piFGsP7uY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764293003; c=relaxed/simple; bh=Y25yl4jusVZJq50/Sr3d2jWXTo9Xt80Kh5nQnCdqQso=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=RDjjanUIToxyKV6Jyu/pPQL22VjW620VB8o4OcZysswRONWYV2h21uM3jpAbFvUQsjkPph26xiEt88eyLenf58xWvKnD9n8md9RVec5xR6v/0qLJluBwBIs7vdWcfN9myMH5eOEtk1r4VTxwCfgwBMAcWWp3CWTdJY4OSOjBKRc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ck7/XNxL; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ck7/XNxL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5F957C116C6; Fri, 28 Nov 2025 01:23:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764293003; bh=Y25yl4jusVZJq50/Sr3d2jWXTo9Xt80Kh5nQnCdqQso=; h=Date:From:To:Cc:Subject:References:From; b=Ck7/XNxLQ936DOxMIKyrTXQzVysP2jWlGaKIYfT/YF53i7fSYKIVyzJElfJzoqZxL nOa4dgSwVDVzMuDk9rcbvY7S1IwhPcXKVtQDmj7PO//lA53dvVgUmkuxbOO0ulSjbl a6bC9w1DG0dywniFMoYebmgRZd7jv5H6u0ECFUYBQaq5kOEGggVhI8abkYBjZAeLwR ilF0SyHoixKLwpwLq2p4c+4YM3oFS7JvqRvkGbkAzSsmnJb5nj8ExGBU8hPNsKkpf3 84h+zVELBLUckkUwsdgMn6gtZ5/E2M6UeH3165fgx3iZqr1KjlsNy6mevtTraiXcLJ a2gD1lHjD0XjQ== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vOnDZ-00000006gjk-0cxI; Thu, 27 Nov 2025 20:24:13 -0500 Message-ID: <20251128012413.003751279@kernel.org> User-Agent: quilt/0.68 Date: Thu, 27 Nov 2025 20:23:44 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , "Gustavo A. R. Silva" , Linus Torvalds , Kees Cook Subject: [for-next][PATCH 13/13] overflow: Introduce struct_offset() to get offset of member References: <20251128012331.307010654@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt The trace_marker_raw file in tracefs takes a buffer from user space that contains an id as well as a raw data string which is usually a binary structure. The structure used has the following: struct raw_data_entry { struct trace_entry ent; unsigned int id; char buf[]; }; Since the passed in "cnt" variable is both the size of buf as well as the size of id, the code to allocate the location on the ring buffer had: size =3D struct_size(entry, buf, cnt - sizeof(entry->id)); Which is quite ugly and hard to understand. Instead, add a helper macro called struct_offset() which then changes the above to a simple and easy to understand: size =3D struct_offset(entry, id) + cnt; This will likely come in handy for other use cases too. Link: https://lore.kernel.org/all/CAHk-=3DwhYZVoEdfO1PmtbirPdBMTV9Nxt9f09CK= 0k6S+HJD3Zmg@mail.gmail.com/ Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: "Gustavo A. R. Silva" Link: https://patch.msgid.link/20251126145249.05b1770a@gandalf.local.home Suggested-by: Linus Torvalds Reviewed-by: Kees Cook Signed-off-by: Steven Rostedt (Google) --- include/linux/overflow.h | 12 ++++++++++++ kernel/trace/trace.c | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/linux/overflow.h b/include/linux/overflow.h index 725f95f7e416..736f633b2d5f 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -458,6 +458,18 @@ static inline size_t __must_check size_sub(size_t minu= end, size_t subtrahend) #define struct_size_t(type, member, count) \ struct_size((type *)NULL, member, count) =20 +/** + * struct_offset() - Calculate the offset of a member within a struct + * @p: Pointer to the struct + * @member: Name of the member to get the offset of + * + * Calculates the offset of a particular @member of the structure pointed + * to by @p. + * + * Return: number of bytes to the location of @member. + */ +#define struct_offset(p, member) (offsetof(typeof(*(p)), member)) + /** * __DEFINE_FLEX() - helper macro for DEFINE_FLEX() family. * Enables caller macro to pass arbitrary trailing expressions diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 73f8b79f1b0c..3d433a426e5f 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -7642,7 +7642,7 @@ static ssize_t write_raw_marker_to_buffer(struct trac= e_array *tr, size_t size; =20 /* cnt includes both the entry->id and the data behind it. */ - size =3D struct_size(entry, buf, cnt - sizeof(entry->id)); + size =3D struct_offset(entry, id) + cnt; =20 buffer =3D tr->array_buffer.buffer; =20 --=20 2.51.0