From nobody Wed Feb 11 03:42:05 2026 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 062E633F8D8; Wed, 5 Nov 2025 16:19:26 +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=1762359567; cv=none; b=a9NOAQBC3EsSLo/6krjkupBIfNrZK7+neMxrwMQDo/JPrUxcSAL6Ju0PnE6wqbFTmq93NtV6554Fayux0VjiUyFoUQK6Q8xWSe8+IZ5EB7kMObRp37Ajrs7Mz320lbzdJCajB9r9x0sZXEa5c2rgNhZIGFRcvwPjtu8CbTHszXM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762359567; c=relaxed/simple; bh=WfSC/Rse3xLN3P8zBrBMqCofdKiaSzH8oUlpMDX+Ilk=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=mGkMQ4AsiNKvourVhWOX6+Y+rZE0J3sVzsyO3wOeSpHgpIEokxjftzYmT5NCQIMHDX59gTg6Hz+PUpL2z/Jrf6Xp35Huz4poQ0Lx/Gvaw6p6S1u4HOZ9PAcbH0y3pATV340mWBcIs3ypqe+i18CAuo/x9fp8yMFa6aE5hLXwgBw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tCFNm+NW; 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="tCFNm+NW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B0721C4AF0D; Wed, 5 Nov 2025 16:19:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762359566; bh=WfSC/Rse3xLN3P8zBrBMqCofdKiaSzH8oUlpMDX+Ilk=; h=Date:From:To:Cc:Subject:References:From; b=tCFNm+NWfbH5E1N+AAmEqcnUb1ysz+4A32SJcmfMshu10NONhC/Fw3svYSyamFze5 TuLN9uLEHehZGLO5jHdbIfpdUDDErlCF7jhAqMXanVSprx0tN8eFjvYtWJUzY08Alc 5IXBz6WoSjS0hpUG56bllNZp07GZswXe6vr21k8+QEX1VpXXWlADQZB2jGivbmHK+C Kzsp6KxWHwrKnF/y06It5IcOk7w9MHFdyzWXqpboR6A67OqVedyKf0fA1BjzC5Hxqa lBLEYPVO2bv+T8cWW8mc9ETy8RVZv5hO0L1EZ0THdO22L3gef+S5K+pW0o4eGT0AWb lT+bdEMMVJz1w== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vGgER-00000000pVD-1UGa; Wed, 05 Nov 2025 11:19:35 -0500 Message-ID: <20251105161935.206093132@kernel.org> User-Agent: quilt/0.68 Date: Wed, 05 Nov 2025 11:19:10 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton Subject: [PATCH 1/5] tracing: Remove dummy options and flags References: <20251105161909.590008129@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 When a tracer does not define their own flags, dummy options and flags are used so that the values are always valid. There's not that many locations that reference these values so having dummy versions just complicates the code. Remove the dummy values and just check for NULL when appropriate. Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.c | 48 +++++++++++++++----------------------------- 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0e822db5d9e4..afeaa9a164e9 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -94,17 +94,6 @@ static bool tracepoint_printk_stop_on_boot __initdata; static bool traceoff_after_boot __initdata; static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key); =20 -/* For tracers that don't implement custom flags */ -static struct tracer_opt dummy_tracer_opt[] =3D { - { } -}; - -static int -dummy_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set) -{ - return 0; -} - /* * To prevent the comm cache from being overwritten when no * tracing is active, only save the comm when a trace event @@ -2356,23 +2345,9 @@ int __init register_tracer(struct tracer *type) } } =20 - if (!type->set_flag) - type->set_flag =3D &dummy_set_flag; - if (!type->flags) { - /*allocate a dummy tracer_flags*/ - type->flags =3D kmalloc(sizeof(*type->flags), GFP_KERNEL); - if (!type->flags) { - ret =3D -ENOMEM; - goto out; - } - type->flags->val =3D 0; - type->flags->opts =3D dummy_tracer_opt; - } else - if (!type->flags->opts) - type->flags->opts =3D dummy_tracer_opt; - /* store the tracer for __set_tracer_option */ - type->flags->trace =3D type; + if (type->flags) + type->flags->trace =3D type; =20 ret =3D do_run_tracer_selftest(type); if (ret < 0) @@ -5159,14 +5134,12 @@ static int tracing_trace_options_show(struct seq_fi= le *m, void *v) { struct tracer_opt *trace_opts; struct trace_array *tr =3D m->private; + struct tracer *trace; u32 tracer_flags; int i; =20 guard(mutex)(&trace_types_lock); =20 - tracer_flags =3D tr->current_trace->flags->val; - trace_opts =3D tr->current_trace->flags->opts; - for (i =3D 0; trace_options[i]; i++) { if (tr->trace_flags & (1ULL << i)) seq_printf(m, "%s\n", trace_options[i]); @@ -5174,6 +5147,13 @@ static int tracing_trace_options_show(struct seq_fil= e *m, void *v) seq_printf(m, "no%s\n", trace_options[i]); } =20 + trace =3D tr->current_trace; + if (!trace->flags || !trace->flags->opts) + return 0; + + tracer_flags =3D tr->current_trace->flags->val; + trace_opts =3D tr->current_trace->flags->opts; + for (i =3D 0; trace_opts[i].name; i++) { if (tracer_flags & trace_opts[i].bit) seq_printf(m, "%s\n", trace_opts[i].name); @@ -5189,9 +5169,10 @@ static int __set_tracer_option(struct trace_array *t= r, struct tracer_opt *opts, int neg) { struct tracer *trace =3D tracer_flags->trace; - int ret; + int ret =3D 0; =20 - ret =3D trace->set_flag(tr, tracer_flags->val, opts->bit, !neg); + if (trace->set_flag) + ret =3D trace->set_flag(tr, tracer_flags->val, opts->bit, !neg); if (ret) return ret; =20 @@ -5210,6 +5191,9 @@ static int set_tracer_option(struct trace_array *tr, = char *cmp, int neg) struct tracer_opt *opts =3D NULL; int i; =20 + if (!tracer_flags || !tracer_flags->opts) + return 0; + for (i =3D 0; tracer_flags->opts[i].name; i++) { opts =3D &tracer_flags->opts[i]; =20 --=20 2.51.0 From nobody Wed Feb 11 03:42:05 2026 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 0640A33F8DE; Wed, 5 Nov 2025 16:19:26 +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=1762359567; cv=none; b=Cf6JJ4VWceq3d+LTYs93J8qla+LQEVB1TQcNF86K26pdPsZXg8MCSB2AoRMmE1pskP4cuHpA1JfoeT5voGJlmAPbncZAx7skIaFHDa9R7XNRIFkNpIter+HG4OYg6tYUVxjLGnCowehnT1H1BdUQHwgesnhD1wkcYtTYnwi2uhw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762359567; c=relaxed/simple; bh=UbMMUEEh5kH2fKPUtIHqA54/voWDDknuZccPtnRfSgo=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=IzYd5J/s6jBbgmU38BxIOoUCFd0OaLh4guPvh5K3vKH98TWOG4X1WUYRWBb795KZJ7lz0UvEFqTf+dxhi1gVy/PcI/5S3fA7oUzd2DWwnl+CrRIylr+EuY+Q3dSkxwx+95tIGl/2PcpGEr+F8Ho+oir8CBB/KttqwEwLOxWYKl8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=llTQ7wM3; 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="llTQ7wM3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B01FDC116C6; Wed, 5 Nov 2025 16:19:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762359566; bh=UbMMUEEh5kH2fKPUtIHqA54/voWDDknuZccPtnRfSgo=; h=Date:From:To:Cc:Subject:References:From; b=llTQ7wM3+H/sMor95uEA3xbKtJQJFufno624LJuVs6KGakv3ZiDCKe5K4PrTdMTse /I3Qnyb2IYP4zyG+E+jeHlt6joQpIsHuANO/vDfJaqLDRzIJlM+OAdJuREs3Bauf0t sGMp4cJ+C+/XDWJavjPYXC7GPAtcs9FinBCsvrRT6uxjbsS02YajJZN043Q9gt7mM/ alAl3S9eGqDZarqsdBKrvKHX8a5tW+YykUYR5H7XUSEFYO+/aEr0UkPmUuKxICGWLS g6T9pEqBldUd4kB5UxFsp/oXf61f2qlYwRYpoLQBOlOBollPpRHJwuqNaSyb6gTrum Pth823HmbUCOQ== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vGgER-00000000pVh-2CAr; Wed, 05 Nov 2025 11:19:35 -0500 Message-ID: <20251105161935.375299297@kernel.org> User-Agent: quilt/0.68 Date: Wed, 05 Nov 2025 11:19:11 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton Subject: [PATCH 2/5] tracing: Have add_tracer_options() error pass up to callers References: <20251105161909.590008129@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 add_tracer_options() can fail, but currently it is ignored. Pass the status of add_tracer_options() up to adding a new tracer as well as when an instance is created. Have the instance creation fail if the add_tracer_options() fail. Only print a warning for the top level instance, like it does with other failures. Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.c | 55 +++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index afeaa9a164e9..ed929d331e1d 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2302,7 +2302,7 @@ static inline int do_run_tracer_selftest(struct trace= r *type) } #endif /* CONFIG_FTRACE_STARTUP_TEST */ =20 -static void add_tracer_options(struct trace_array *tr, struct tracer *t); +static int add_tracer_options(struct trace_array *tr, struct tracer *t); =20 static void __init apply_trace_boot_options(void); =20 @@ -2353,9 +2353,14 @@ int __init register_tracer(struct tracer *type) if (ret < 0) goto out; =20 + ret =3D add_tracer_options(&global_trace, type); + if (ret < 0) { + pr_warn("Failed to create tracer options for %s\n", type->name); + goto out; + } + type->next =3D trace_types; trace_types =3D type; - add_tracer_options(&global_trace, type); =20 out: mutex_unlock(&trace_types_lock); @@ -6221,7 +6226,7 @@ int tracing_update_buffers(struct trace_array *tr) =20 struct trace_option_dentry; =20 -static void +static int create_trace_option_files(struct trace_array *tr, struct tracer *tracer); =20 /* @@ -6243,17 +6248,17 @@ static void tracing_set_nop(struct trace_array *tr) =20 static bool tracer_options_updated; =20 -static void add_tracer_options(struct trace_array *tr, struct tracer *t) +static int add_tracer_options(struct trace_array *tr, struct tracer *t) { /* Only enable if the directory has been created already. */ if (!tr->dir && !(tr->flags & TRACE_ARRAY_FL_GLOBAL)) - return; + return 0; =20 /* Only create trace option files after update_tracer_options finish */ if (!tracer_options_updated) - return; + return 0; =20 - create_trace_option_files(tr, t); + return create_trace_option_files(tr, t); } =20 int tracing_set_tracer(struct trace_array *tr, const char *buf) @@ -9585,7 +9590,7 @@ create_trace_option_file(struct trace_array *tr, =20 } =20 -static void +static int create_trace_option_files(struct trace_array *tr, struct tracer *tracer) { struct trace_option_dentry *topts; @@ -9596,24 +9601,24 @@ create_trace_option_files(struct trace_array *tr, s= truct tracer *tracer) int i; =20 if (!tracer) - return; + return 0; =20 flags =3D tracer->flags; =20 if (!flags || !flags->opts) - return; + return 0; =20 /* * If this is an instance, only create flags for tracers * the instance may have. */ if (!trace_ok_for_array(tracer, tr)) - return; + return 0; =20 for (i =3D 0; i < tr->nr_topts; i++) { /* Make sure there's no duplicate flags. */ if (WARN_ON_ONCE(tr->topts[i].tracer->flags =3D=3D tracer->flags)) - return; + return -EINVAL; } =20 opts =3D flags->opts; @@ -9623,13 +9628,13 @@ create_trace_option_files(struct trace_array *tr, s= truct tracer *tracer) =20 topts =3D kcalloc(cnt + 1, sizeof(*topts), GFP_KERNEL); if (!topts) - return; + return 0; =20 tr_topts =3D krealloc(tr->topts, sizeof(*tr->topts) * (tr->nr_topts + 1), GFP_KERNEL); if (!tr_topts) { kfree(topts); - return; + return -ENOMEM; } =20 tr->topts =3D tr_topts; @@ -9644,6 +9649,7 @@ create_trace_option_files(struct trace_array *tr, str= uct tracer *tracer) "Failed to create trace option: %s", opts[cnt].name); } + return 0; } =20 static struct dentry * @@ -10094,15 +10100,18 @@ static void init_trace_flags_index(struct trace_a= rray *tr) tr->trace_flags_index[i] =3D i; } =20 -static void __update_tracer_options(struct trace_array *tr) +static int __update_tracer_options(struct trace_array *tr) { struct tracer *t; + int ret =3D 0; + + for (t =3D trace_types; t && !ret; t =3D t->next) + ret =3D add_tracer_options(tr, t); =20 - for (t =3D trace_types; t; t =3D t->next) - add_tracer_options(tr, t); + return ret; } =20 -static void update_tracer_options(struct trace_array *tr) +static __init void update_tracer_options(struct trace_array *tr) { guard(mutex)(&trace_types_lock); tracer_options_updated =3D true; @@ -10151,9 +10160,13 @@ static int trace_array_create_dir(struct trace_arr= ay *tr) } =20 init_tracer_tracefs(tr, tr->dir); - __update_tracer_options(tr); - - return ret; + ret =3D __update_tracer_options(tr); + if (ret) { + event_trace_del_tracer(tr); + tracefs_remove(tr->dir); + return ret; + } + return 0; } =20 static struct trace_array * --=20 2.51.0 From nobody Wed Feb 11 03:42:05 2026 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 6A60233FE1A; Wed, 5 Nov 2025 16:19:27 +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=1762359567; cv=none; b=tXJK+c/skpIw+WBP+5LobHUhGBrSI4i/MWBuX7YpGqGR+Kf+vE2UvZPURcW9q+9qaVfXy+prHGp1wjr91XZCL6euDYma0aiB+xPNDNZ0G1xAdjuuwHbkalkUMLpBo5NTqNVShPTYGT5LD5W5UCJXKqtOikIwKoKbD4YsKkoZfBE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762359567; c=relaxed/simple; bh=tdAoGAOAugQGZkzEKOgv1AFk5FGHr2q2L1oGbuCQFAw=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=TLywaIgcQRgujd/NNxrtO24oujMt7oh7+XDcTVEhOlQo+u3aRyw+MF+Hsy/GcX++mnI2xJKjdWeok2jnHjiJoSmJx8ItzaVXscnka+ja2vqDGgXVQ5w3mWQtVyadE1ZC/gIbdo0Y8mIwMmni+x8zjM/jIwSo87cfUIdWq9P6PAc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PGcFqmjG; 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="PGcFqmjG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E53E5C19422; Wed, 5 Nov 2025 16:19:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762359567; bh=tdAoGAOAugQGZkzEKOgv1AFk5FGHr2q2L1oGbuCQFAw=; h=Date:From:To:Cc:Subject:References:From; b=PGcFqmjG46B8QZ+7Hpwb70D5qAiwQXvJj0C6Gk47fNgozp5WHrs6l0F35zDBa1dlC N5HiMrNbCdPQVg+5UyeDQPqbwTarvKmkre2DccjhxtbmEStHHD6jPQiRWEVdTFfhHa YnMxPxrBTr6gxOJeI1cC3931agVgtPzjxw7l6vj+I/AF9wiTQ/THC/SolVmiUmX0RG xhzb4Fqc70roYt9mtwxlU6wQhzxNrZwYxOvM18rs7H4ASXr9sRefAqCi/Ya/deZYLL 4woSkh2noPHhwJP0an5xKhfdT/kPNAPcfVvjZ+CQp+WoGKhNXRUEiVTFv7U15ZNzdZ ESdKqbXTrecsg== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vGgER-00000000pWB-2uES; Wed, 05 Nov 2025 11:19:35 -0500 Message-ID: <20251105161935.545400234@kernel.org> User-Agent: quilt/0.68 Date: Wed, 05 Nov 2025 11:19:12 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton Subject: [PATCH 3/5] tracing: Have tracer option be instance specific References: <20251105161909.590008129@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 Tracers can add specify options to modify them. This logic was added before instances were created and the tracer flags were global variables. After instances were created where a tracer may exist in more than one instance, the flags were not updated from being global into instance specific. This causes confusion with these options. For example, the function tracer has an option to enable function arguments: # cd /sys/kernel/tracing # mkdir instances/foo # echo function > instances/foo/current_tracer # echo 1 > options/func-args # echo function > current_tracer # cat trace [..] -0 [005] d..3. 1050.656187: rcu_needs_cpu() <-tick_nohz_next= _event -0 [005] d..3. 1050.656188: get_next_timer_interrupt(basej= =3D0x10002dbad, basem=3D0xf45fd7d300) <-tick_nohz_next_event -0 [005] d..3. 1050.656189: _raw_spin_lock(lock=3D0xffff8944= bdf5de80) <-__get_next_timer_interrupt -0 [005] d..4. 1050.656190: do_raw_spin_lock(lock=3D0xffff89= 44bdf5de80) <-__get_next_timer_interrupt -0 [005] d..4. 1050.656191: _raw_spin_lock_nested(lock=3D0xf= fff8944bdf5f140, subclass=3D1) <-__get_next_timer_interrupt # cat instances/foo/options/func-args 1 # cat instances/foo/trace [..] kworker/4:1-88 [004] ...1. 298.127735: next_zone <-refresh_cpu_vm_= stats kworker/4:1-88 [004] ...1. 298.127736: first_online_pgdat <-refres= h_cpu_vm_stats kworker/4:1-88 [004] ...1. 298.127738: next_online_pgdat <-refresh= _cpu_vm_stats kworker/4:1-88 [004] ...1. 298.127739: fold_diff <-refresh_cpu_vm_= stats kworker/4:1-88 [004] ...1. 298.127741: round_jiffies_relative <-vm= stat_update [..] The above shows that setting "func-args" in the top level instance also set it in the instance "foo", but since the interface of the trace flags are per instance, the update didn't take affect in the "foo" instance. Update the infrastructure to allow tracers to add a "default_flags" field in the tracer structure that can be set instead of "flags" which will make the flags per instance. If a tracer needs to keep the flags global (like blktrace), keeping the "flags" field set will keep the old behavior. This does not update function or the function graph tracers. That will be handled later. Fixes: f20a580627f43 ("ftrace: Allow instances to use function tracing") Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.c | 221 +++++++++++++++++++++++++++++-------------- kernel/trace/trace.h | 3 + 2 files changed, 154 insertions(+), 70 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ed929d331e1d..dea1566b3301 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -94,6 +94,13 @@ static bool tracepoint_printk_stop_on_boot __initdata; static bool traceoff_after_boot __initdata; static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key); =20 +/* Store tracers and their flags per instance */ +struct tracers { + struct list_head list; + struct tracer *tracer; + struct tracer_flags *flags; +}; + /* * To prevent the comm cache from being overwritten when no * tracing is active, only save the comm when a trace event @@ -2164,6 +2171,9 @@ static int save_selftest(struct tracer *type) static int run_tracer_selftest(struct tracer *type) { struct trace_array *tr =3D &global_trace; + struct trace_tracer *type =3D tracers->trace; + struct tracer_flags *saved_flags =3D tr->current_trace_flags; + struct tracer_flags *flags; struct tracer *saved_tracer =3D tr->current_trace; int ret; =20 @@ -2194,6 +2204,7 @@ static int run_tracer_selftest(struct tracer *type) tracing_reset_online_cpus(&tr->array_buffer); =20 tr->current_trace =3D type; + tr->current_trace_flags =3D type->flags ? : type->default_flags; =20 #ifdef CONFIG_TRACER_MAX_TRACE if (type->use_max_tr) { @@ -2210,6 +2221,7 @@ static int run_tracer_selftest(struct tracer *type) ret =3D type->selftest(type, tr); /* the test is responsible for resetting too */ tr->current_trace =3D saved_tracer; + tr->current_trace_flags =3D saved_flags; if (ret) { printk(KERN_CONT "FAILED!\n"); /* Add the warning after printing 'FAILED' */ @@ -2302,10 +2314,23 @@ static inline int do_run_tracer_selftest(struct tra= cer *type) } #endif /* CONFIG_FTRACE_STARTUP_TEST */ =20 -static int add_tracer_options(struct trace_array *tr, struct tracer *t); +static int add_tracer(struct trace_array *tr, struct tracer *t); =20 static void __init apply_trace_boot_options(void); =20 +static void free_tracers(struct trace_array *tr) +{ + struct tracers *t, *n; + + lockdep_assert_held(&trace_types_lock); + + list_for_each_entry_safe(t, n, &tr->tracers, list) { + list_del(&t->list); + kfree(t->flags); + kfree(t); + } +} + /** * register_tracer - register a tracer with the ftrace system. * @type: the plugin for the tracer @@ -2314,6 +2339,7 @@ static void __init apply_trace_boot_options(void); */ int __init register_tracer(struct tracer *type) { + struct trace_array *tr; struct tracer *t; int ret =3D 0; =20 @@ -2353,10 +2379,13 @@ int __init register_tracer(struct tracer *type) if (ret < 0) goto out; =20 - ret =3D add_tracer_options(&global_trace, type); - if (ret < 0) { - pr_warn("Failed to create tracer options for %s\n", type->name); - goto out; + list_for_each_entry(tr, &ftrace_trace_arrays, list) { + ret =3D add_tracer(tr, type); + if (ret < 0) { + /* The tracer will still exist but without options */ + pr_warn("Failed to create tracer options for %s\n", type->name); + break; + } } =20 type->next =3D trace_types; @@ -5139,6 +5168,7 @@ 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; @@ -5152,12 +5182,14 @@ static int tracing_trace_options_show(struct seq_fi= le *m, void *v) seq_printf(m, "no%s\n", trace_options[i]); } =20 - trace =3D tr->current_trace; - if (!trace->flags || !trace->flags->opts) + flags =3D tr->current_trace_flags; + if (!flags || !flags->opts) return 0; =20 - tracer_flags =3D tr->current_trace->flags->val; - trace_opts =3D tr->current_trace->flags->opts; + trace =3D tr->current_trace; + + tracer_flags =3D flags->val; + trace_opts =3D flags->opts; =20 for (i =3D 0; trace_opts[i].name; i++) { if (tracer_flags & trace_opts[i].bit) @@ -5191,8 +5223,7 @@ static int __set_tracer_option(struct trace_array *tr, /* Try to assign a tracer specific option */ static int set_tracer_option(struct trace_array *tr, char *cmp, int neg) { - struct tracer *trace =3D tr->current_trace; - struct tracer_flags *tracer_flags =3D trace->flags; + struct tracer_flags *tracer_flags =3D tr->current_trace_flags; struct tracer_opt *opts =3D NULL; int i; =20 @@ -5203,7 +5234,7 @@ static int set_tracer_option(struct trace_array *tr, = char *cmp, int neg) opts =3D &tracer_flags->opts[i]; =20 if (strcmp(cmp, opts->name) =3D=3D 0) - return __set_tracer_option(tr, trace->flags, opts, neg); + return __set_tracer_option(tr, tracer_flags, opts, neg); } =20 return -EINVAL; @@ -6224,11 +6255,6 @@ int tracing_update_buffers(struct trace_array *tr) return ret; } =20 -struct trace_option_dentry; - -static int -create_trace_option_files(struct trace_array *tr, struct tracer *tracer); - /* * Used to clear out the tracer before deletion of an instance. * Must have trace_types_lock held. @@ -6244,26 +6270,15 @@ static void tracing_set_nop(struct trace_array *tr) tr->current_trace->reset(tr); =20 tr->current_trace =3D &nop_trace; + tr->current_trace_flags =3D nop_trace.flags; } =20 static bool tracer_options_updated; =20 -static int add_tracer_options(struct trace_array *tr, struct tracer *t) -{ - /* Only enable if the directory has been created already. */ - if (!tr->dir && !(tr->flags & TRACE_ARRAY_FL_GLOBAL)) - return 0; - - /* Only create trace option files after update_tracer_options finish */ - if (!tracer_options_updated) - return 0; - - return create_trace_option_files(tr, t); -} - int tracing_set_tracer(struct trace_array *tr, const char *buf) { - struct tracer *t; + struct tracer *trace; + struct tracers *t; #ifdef CONFIG_TRACER_MAX_TRACE bool had_max_tr; #endif @@ -6281,18 +6296,20 @@ int tracing_set_tracer(struct trace_array *tr, cons= t char *buf) ret =3D 0; } =20 - for (t =3D trace_types; t; t =3D t->next) { - if (strcmp(t->name, buf) =3D=3D 0) + list_for_each_entry(t, &tr->tracers, list) { + if (strcmp(t->tracer->name, buf) =3D=3D 0) break; } if (!t) return -EINVAL; =20 - if (t =3D=3D tr->current_trace) + if (t->tracer =3D=3D tr->current_trace) return 0; =20 + trace =3D t->tracer; + #ifdef CONFIG_TRACER_SNAPSHOT - if (t->use_max_tr) { + if (trace->use_max_tr) { local_irq_disable(); arch_spin_lock(&tr->max_lock); ret =3D tr->cond_snapshot ? -EBUSY : 0; @@ -6303,14 +6320,14 @@ int tracing_set_tracer(struct trace_array *tr, cons= t char *buf) } #endif /* Some tracers won't work on kernel command line */ - if (system_state < SYSTEM_RUNNING && t->noboot) { + if (system_state < SYSTEM_RUNNING && trace->noboot) { pr_warn("Tracer '%s' is not allowed on command line, ignored\n", - t->name); + trace->name); return -EINVAL; } =20 /* Some tracers are only allowed for the top level buffer */ - if (!trace_ok_for_array(t, tr)) + if (!trace_ok_for_array(trace, tr)) return -EINVAL; =20 /* If trace pipe files are being read, we can't change the tracer */ @@ -6329,8 +6346,9 @@ int tracing_set_tracer(struct trace_array *tr, const = char *buf) =20 /* Current trace needs to be nop_trace before synchronize_rcu */ tr->current_trace =3D &nop_trace; + tr->current_trace_flags =3D nop_trace.flags; =20 - if (had_max_tr && !t->use_max_tr) { + if (had_max_tr && !trace->use_max_tr) { /* * We need to make sure that the update_max_tr sees that * current_trace changed to nop_trace to keep it from @@ -6343,7 +6361,7 @@ int tracing_set_tracer(struct trace_array *tr, const = char *buf) tracing_disarm_snapshot(tr); } =20 - if (!had_max_tr && t->use_max_tr) { + if (!had_max_tr && trace->use_max_tr) { ret =3D tracing_arm_snapshot_locked(tr); if (ret) return ret; @@ -6352,18 +6370,21 @@ int tracing_set_tracer(struct trace_array *tr, cons= t char *buf) tr->current_trace =3D &nop_trace; #endif =20 - if (t->init) { - ret =3D tracer_init(t, tr); + tr->current_trace_flags =3D t->flags ? : t->tracer->flags; + + if (trace->init) { + ret =3D tracer_init(trace, tr); if (ret) { #ifdef CONFIG_TRACER_MAX_TRACE - if (t->use_max_tr) + if (trace->use_max_tr) tracing_disarm_snapshot(tr); #endif + tr->current_trace_flags =3D nop_trace.flags; return ret; } } =20 - tr->current_trace =3D t; + tr->current_trace =3D trace; tr->current_trace->enabled++; trace_branch_enable(tr); =20 @@ -9587,40 +9608,20 @@ create_trace_option_file(struct trace_array *tr, =20 topt->entry =3D trace_create_file(opt->name, TRACE_MODE_WRITE, t_options, topt, &trace_options_fops); - } =20 static int -create_trace_option_files(struct trace_array *tr, struct tracer *tracer) +create_trace_option_files(struct trace_array *tr, struct tracer *tracer, + struct tracer_flags *flags) { struct trace_option_dentry *topts; struct trace_options *tr_topts; - struct tracer_flags *flags; struct tracer_opt *opts; int cnt; - int i; - - if (!tracer) - return 0; - - flags =3D tracer->flags; =20 if (!flags || !flags->opts) return 0; =20 - /* - * If this is an instance, only create flags for tracers - * the instance may have. - */ - if (!trace_ok_for_array(tracer, tr)) - return 0; - - for (i =3D 0; i < tr->nr_topts; i++) { - /* Make sure there's no duplicate flags. */ - if (WARN_ON_ONCE(tr->topts[i].tracer->flags =3D=3D tracer->flags)) - return -EINVAL; - } - opts =3D flags->opts; =20 for (cnt =3D 0; opts[cnt].name; cnt++) @@ -9652,6 +9653,80 @@ create_trace_option_files(struct trace_array *tr, st= ruct tracer *tracer) return 0; } =20 +static int get_global_flags_val(struct tracer *tracer) +{ + struct tracers *t; + + list_for_each_entry(t, &global_trace.tracers, list) { + if (t->tracer !=3D tracer) + continue; + if (!t->flags) + return -1; + return t->flags->val; + } + return -1; +} + +static int add_tracer(struct trace_array *tr, struct tracer *tracer) +{ + struct tracer_flags *flags; + struct tracers *t; + + /* Only enable if the directory has been created already. */ + if (!tr->dir && !(tr->flags & TRACE_ARRAY_FL_GLOBAL)) + return 0; + + /* Only add tracer after update_tracer_options finish */ + if (!tracer_options_updated) + return 0; + + /* + * If this is an instance, only create flags for tracers + * the instance may have. + */ + if (!trace_ok_for_array(tracer, tr)) + return 0; + + t =3D kmalloc(sizeof(*t), GFP_KERNEL); + if (!t) + return -ENOMEM; + + t->tracer =3D tracer; + t->flags =3D NULL; + list_add(&t->list, &tr->tracers); + + flags =3D tracer->flags; + if (!flags) { + if (!tracer->default_flags) + return 0; + + /* + * If the tracer defines default flags, it means the flags are + * per trace instance. + */ + flags =3D kmalloc(sizeof(*flags), GFP_KERNEL); + if (!flags) { + list_del(&t->list); + kfree(t); + return -ENOMEM; + } + + *flags =3D *tracer->default_flags; + flags->trace =3D tracer; + + t->flags =3D flags; + + /* If this is an instance, inherit the global_trace flags */ + if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL)) { + int val =3D get_global_flags_val(tracer); + if (!WARN_ON_ONCE(val < 0)) + flags->val =3D val; + } + } + + return create_trace_option_files(tr, tracer, flags); +} + static struct dentry * create_trace_option_core_file(struct trace_array *tr, const char *option, long index) @@ -10100,13 +10175,13 @@ static void init_trace_flags_index(struct trace_a= rray *tr) tr->trace_flags_index[i] =3D i; } =20 -static int __update_tracer_options(struct trace_array *tr) +static int __update_tracer(struct trace_array *tr) { struct tracer *t; int ret =3D 0; =20 for (t =3D trace_types; t && !ret; t =3D t->next) - ret =3D add_tracer_options(tr, t); + ret =3D add_tracer(tr, t); =20 return ret; } @@ -10115,7 +10190,7 @@ static __init void update_tracer_options(struct tra= ce_array *tr) { guard(mutex)(&trace_types_lock); tracer_options_updated =3D true; - __update_tracer_options(tr); + __update_tracer(tr); } =20 /* Must have trace_types_lock held */ @@ -10160,7 +10235,7 @@ static int trace_array_create_dir(struct trace_arra= y *tr) } =20 init_tracer_tracefs(tr, tr->dir); - ret =3D __update_tracer_options(tr); + ret =3D __update_tracer(tr); if (ret) { event_trace_del_tracer(tr); tracefs_remove(tr->dir); @@ -10215,11 +10290,13 @@ trace_array_create_systems(const char *name, cons= t char *systems, spin_lock_init(&tr->snapshot_trigger_lock); #endif tr->current_trace =3D &nop_trace; + tr->current_trace_flags =3D nop_trace.flags; =20 INIT_LIST_HEAD(&tr->systems); INIT_LIST_HEAD(&tr->events); INIT_LIST_HEAD(&tr->hist_vars); INIT_LIST_HEAD(&tr->err_log); + INIT_LIST_HEAD(&tr->tracers); INIT_LIST_HEAD(&tr->marker_list); =20 #ifdef CONFIG_MODULES @@ -10392,6 +10469,7 @@ static int __remove_instance(struct trace_array *tr) free_percpu(tr->last_func_repeats); free_trace_buffers(tr); clear_tracing_err_log(tr); + free_tracers(tr); =20 if (tr->range_name) { reserve_mem_release_by_name(tr->range_name); @@ -11426,6 +11504,7 @@ __init static int tracer_alloc_buffers(void) * just a bootstrap of current_trace anyway. */ global_trace.current_trace =3D &nop_trace; + global_trace.current_trace_flags =3D nop_trace.flags; =20 global_trace.max_lock =3D (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; #ifdef CONFIG_TRACER_MAX_TRACE @@ -11439,6 +11518,8 @@ __init static int tracer_alloc_buffers(void) =20 init_trace_flags_index(&global_trace); =20 + INIT_LIST_HEAD(&global_trace.tracers); + register_tracer(&nop_trace); =20 /* Function tracing may start here (via kernel command line) */ diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 8ecaf91ca823..299862aad66c 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -392,6 +392,7 @@ struct trace_array { int buffer_percent; unsigned int n_err_log_entries; struct tracer *current_trace; + struct tracer_flags *current_trace_flags; u64 trace_flags; unsigned char trace_flags_index[TRACE_FLAGS_MAX_SIZE]; unsigned int flags; @@ -406,6 +407,7 @@ struct trace_array { struct list_head systems; struct list_head events; struct list_head marker_list; + struct list_head tracers; struct trace_event_file *trace_marker_file; cpumask_var_t tracing_cpumask; /* only trace on set CPUs */ /* one per_cpu trace_pipe can be opened by only one user */ @@ -637,6 +639,7 @@ struct tracer { u64 mask, int set); struct tracer *next; struct tracer_flags *flags; + struct tracer_flags *default_flags; int enabled; bool print_max; bool allow_instances; --=20 2.51.0 From nobody Wed Feb 11 03:42:05 2026 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 6A57C334C3F; Wed, 5 Nov 2025 16:19:27 +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=1762359567; cv=none; b=P28J3+8W5LBUnPwnGMJzXw8yeX4yY/I6R2ir1i5XG9IYY2Z4IOY68FdONh/iTKaEposKp0vxPsF3YR9irkvtSLJhEAYA/CPSfO6Ekq2wNIfmoiTDqP2PaTXE08fe14NjiIyVf4FhNVJEWV1/Ph7PlyxSY4Hi90vnqOrrrR6IMEs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762359567; c=relaxed/simple; bh=OUFFj9AZqHaaEQJANSjC5PFp63yqEirX5OV3P3nO7UQ=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=JiTRZz8L9jKh0nU6gahWsW5gQmZ/GleBTScKyOYU+P8RVWmfQxd+ZRH6KOY1/nAzbKcQ6DYRrOJLAXHINDu+LlUD3SFNhFH6uEPJ5cVDeQ1IIowmFA5n/xow5vt9u8SVxBhNP1FGS+9E2UDKuiBHRXH1xt97gI3mp+t/KPzB/fI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KVDPBOrx; 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="KVDPBOrx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 08385C116B1; Wed, 5 Nov 2025 16:19:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762359567; bh=OUFFj9AZqHaaEQJANSjC5PFp63yqEirX5OV3P3nO7UQ=; h=Date:From:To:Cc:Subject:References:From; b=KVDPBOrxwkwjVktm7dQqrTaSvKPiswILANUHekUFvIB9wxFKAvBfHgviIug/xhc3l c3kdOagj2fDVoihPlULMlDlrWCNyTYHYaIcX26mFVJ99b9E2veGobDOKvjY4o2vFz0 SCmlHoZjTwnX//Izhn5oEraEn/g/R+v/qTmEC+9y1PobAlBw2ffd9DZSkhyjp2A5ZO e+mKeBNbVBXVIWTcHcgwD1QjDTiE3/WEWYkEThIU5z+7PL72n+dXSqpaU0u8U7unIl hC2aMn9UHb+z0R9MfqHVGxmSjxQ4FUFNsNgZXpYHUDDK5BMaTMpKGH+ns/lNnAdjyq KGF/WRHlP5kMQ== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vGgER-00000000pWf-3bHP; Wed, 05 Nov 2025 11:19:35 -0500 Message-ID: <20251105161935.712544514@kernel.org> User-Agent: quilt/0.68 Date: Wed, 05 Nov 2025 11:19:13 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton Subject: [PATCH 4/5] tracing: Have function tracer define options per instance References: <20251105161909.590008129@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 Currently the function tracer's options are saved via a global mask when it should be per instance. Use the new infrastructure to define a "default_flags" field in the tracer structure that is used for the top level instance as well as new ones. Currently the global mask causes confusion: # cd /sys/kernel/tracing # mkdir instances/foo # echo function > instances/foo/current_tracer # echo 1 > options/func-args # echo function > current_tracer # cat trace [..] -0 [005] d..3. 1050.656187: rcu_needs_cpu() <-tick_nohz_next= _event -0 [005] d..3. 1050.656188: get_next_timer_interrupt(basej= =3D0x10002dbad, basem=3D0xf45fd7d300) <-tick_nohz_next_event -0 [005] d..3. 1050.656189: _raw_spin_lock(lock=3D0xffff8944= bdf5de80) <-__get_next_timer_interrupt -0 [005] d..4. 1050.656190: do_raw_spin_lock(lock=3D0xffff89= 44bdf5de80) <-__get_next_timer_interrupt -0 [005] d..4. 1050.656191: _raw_spin_lock_nested(lock=3D0xf= fff8944bdf5f140, subclass=3D1) <-__get_next_timer_interrupt # cat instances/foo/options/func-args 1 # cat instances/foo/trace [..] kworker/4:1-88 [004] ...1. 298.127735: next_zone <-refresh_cpu_vm_= stats kworker/4:1-88 [004] ...1. 298.127736: first_online_pgdat <-refres= h_cpu_vm_stats kworker/4:1-88 [004] ...1. 298.127738: next_online_pgdat <-refresh= _cpu_vm_stats kworker/4:1-88 [004] ...1. 298.127739: fold_diff <-refresh_cpu_vm_= stats kworker/4:1-88 [004] ...1. 298.127741: round_jiffies_relative <-vm= stat_update [..] The above shows that updating the "func-args" option at the top level instance also updates the "func-args" option in the instance but because the update is only done by the instance that gets changed (as it should), it's confusing to see that the option is already set in the other instance. Fixes: f20a580627f43 ("ftrace: Allow instances to use function tracing") Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_functions.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index d17c18934445..c12795c2fb39 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -154,11 +154,11 @@ static int function_trace_init(struct trace_array *tr) if (!tr->ops) return -ENOMEM; =20 - func =3D select_trace_function(func_flags.val); + func =3D select_trace_function(tr->current_trace_flags->val); if (!func) return -EINVAL; =20 - if (!handle_func_repeats(tr, func_flags.val)) + if (!handle_func_repeats(tr, tr->current_trace_flags->val)) return -ENOMEM; =20 ftrace_init_array_ops(tr, func); @@ -459,14 +459,14 @@ func_set_flag(struct trace_array *tr, u32 old_flags, = u32 bit, int set) u32 new_flags; =20 /* Do nothing if already set. */ - if (!!set =3D=3D !!(func_flags.val & bit)) + if (!!set =3D=3D !!(tr->current_trace_flags->val & bit)) return 0; =20 /* We can change this flag only when not running. */ if (tr->current_trace !=3D &function_trace) return 0; =20 - new_flags =3D (func_flags.val & ~bit) | (set ? bit : 0); + new_flags =3D (tr->current_trace_flags->val & ~bit) | (set ? bit : 0); func =3D select_trace_function(new_flags); if (!func) return -EINVAL; @@ -491,7 +491,7 @@ static struct tracer function_trace __tracer_data =3D .init =3D function_trace_init, .reset =3D function_trace_reset, .start =3D function_trace_start, - .flags =3D &func_flags, + .default_flags =3D &func_flags, .set_flag =3D func_set_flag, .allow_instances =3D true, #ifdef CONFIG_FTRACE_SELFTEST --=20 2.51.0 From nobody Wed Feb 11 03:42:05 2026 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 67A2F33FE19; Wed, 5 Nov 2025 16:19:27 +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=1762359567; cv=none; b=m26DtlDg7+Coy2TE3lwg5UMRFbQ13SHqPbxgZtocgjKN602Nur5JncdLxUw5Lt1660X03/JOre7KW3tKcSccBi0dI3M4AJAF+pdJDPPOlo6+oo1OdNBZJnyJfQH907wCntrbL1aPYFCq4b871Jreyc8sik4Exiev21QppOk5tfk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762359567; c=relaxed/simple; bh=N+TFR99mamonjH8vPWRk0SrejJFvgn4sQrqG8EbDDpA=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=qegKOyWPE2/Sd2Zu00Z0nH1cSTdbiJrFvqmxJ80LcnKzijJabSIWuO6W8A5FXG70MqfjjMMkC+OalMMDo1b2DoXDs5j5zPnWBCBCunFHRSinrZOhC4224qFd+NffqZweApPO69dW5FLgiGzj2pk39wNGf4KFrTnV6CQ1uSfQw6Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iNgOgTAD; 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="iNgOgTAD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 41D31C4CEF8; Wed, 5 Nov 2025 16:19:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762359567; bh=N+TFR99mamonjH8vPWRk0SrejJFvgn4sQrqG8EbDDpA=; h=Date:From:To:Cc:Subject:References:From; b=iNgOgTADcEwA7xn3kZGun3yTiHSAKRokB+XxbSMigkkSIHExcTPEZKwcL7NZO0G0H 2fxHNQITQWWN5DcLsGO927PcviUMPXRQ2gbQXArh1PWU1kMisZHjLmJm5v4/919aXp Gqs2yvQ2nnNxSxFHPIZ1HotflZf0GRnL84AM7aSoXObKDLLVHpRcR3fsUWHtIEJGDi I7g0ZHUHwtLjG2qD9+p08+oeAndCYOoCcACAr+rBGDBkF0VkNsBatYN996idLCIUdx dbOrEY10Hh7k4EO+Z69yYSVlc/BeTan60GHwu3/F/p8mdeKdHN+la0dfUlWa8IadK3 riGvjApb+HvCQ== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1vGgES-00000000pX9-05mz; Wed, 05 Nov 2025 11:19:36 -0500 Message-ID: <20251105161935.878361977@kernel.org> User-Agent: quilt/0.68 Date: Wed, 05 Nov 2025 11:19:14 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton Subject: [PATCH 5/5] tracing: Have function graph tracer define options per instance References: <20251105161909.590008129@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 Currently the function graph tracer's options are saved via a global mask when it should be per instance. Use the new infrastructure to define a "default_flags" field in the tracer structure that is used for the top level instance as well as new ones. Currently the global mask causes confusion: # cd /sys/kernel/tracing # mkdir instances/foo # echo function_graph > instances/foo/current_tracer # echo 1 > options/funcgraph-args # echo function_graph > current_tracer # cat trace [..] 2) | _raw_spin_lock_irq(lock=3D0xffff96b97dea16c0) { 2) 0.422 us | do_raw_spin_lock(lock=3D0xffff96b97dea16c0); 7) | rcu_sched_clock_irq(user=3D0) { 2) 1.478 us | } 7) 0.758 us | rcu_is_cpu_rrupt_from_idle(); 2) 0.647 us | enqueue_hrtimer(timer=3D0xffff96b97dea2058, ba= se=3D0xffff96b97dea1740, mode=3D0); # cat instances/foo/options/funcgraph-args 1 # cat instances/foo/trace [..] 4) | __x64_sys_read() { 4) | ksys_read() { 4) 0.755 us | fdget_pos(); 4) | vfs_read() { 4) | rw_verify_area() { 4) | security_file_permission() { 4) | apparmor_file_permission() { 4) | common_file_perm() { 4) | aa_file_perm() { 4) | rcu_read_lock_held() { [..] The above shows that updating the "funcgraph-args" option at the top level instance also updates the "funcgraph-args" option in the instance but because the update is only done by the instance that gets changed (as it should), it's confusing to see that the option is already set in the other instance. Fixes: c132be2c4fcc1 ("function_graph: Have the instances use their own ftr= ace_ops for filtering") Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_functions_graph.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_func= tions_graph.c index fe9607edc8f9..4e86adf6dd4d 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -101,9 +101,9 @@ static struct tracer_flags tracer_flags =3D { .opts =3D trace_opts }; =20 -static bool tracer_flags_is_set(u32 flags) +static bool tracer_flags_is_set(struct trace_array *tr, u32 flags) { - return (tracer_flags.val & flags) =3D=3D flags; + return (tr->current_trace_flags->val & flags) =3D=3D flags; } =20 /* @@ -263,7 +263,7 @@ static int graph_entry(struct ftrace_graph_ent *trace, =20 trace_ctx =3D tracing_gen_ctx(); if (IS_ENABLED(CONFIG_FUNCTION_GRAPH_RETADDR) && - tracer_flags_is_set(TRACE_GRAPH_PRINT_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); } else { @@ -441,7 +441,7 @@ static int graph_trace_init(struct trace_array *tr) { int ret; =20 - if (tracer_flags_is_set(TRACE_GRAPH_ARGS)) + if (tracer_flags_is_set(tr, TRACE_GRAPH_ARGS)) tr->gops->entryfunc =3D trace_graph_entry_args; else tr->gops->entryfunc =3D trace_graph_entry; @@ -1459,7 +1459,8 @@ print_graph_function_flags(struct trace_iterator *ite= r, u32 flags) static enum print_line_t print_graph_function(struct trace_iterator *iter) { - return print_graph_function_flags(iter, tracer_flags.val); + struct trace_array *tr =3D iter->tr; + return print_graph_function_flags(iter, tr->current_trace_flags->val); } =20 static enum print_line_t @@ -1535,7 +1536,10 @@ static void __print_graph_headers_flags(struct trace= _array *tr, =20 static void print_graph_headers(struct seq_file *s) { - print_graph_headers_flags(s, tracer_flags.val); + struct trace_iterator *iter =3D s->private; + struct trace_array *tr =3D iter->tr; + + print_graph_headers_flags(s, tr->current_trace_flags->val); } =20 void print_graph_headers_flags(struct seq_file *s, u32 flags) @@ -1660,7 +1664,7 @@ static struct tracer graph_trace __tracer_data =3D { .reset =3D graph_trace_reset, .print_line =3D print_graph_function, .print_header =3D print_graph_headers, - .flags =3D &tracer_flags, + .default_flags =3D &tracer_flags, .set_flag =3D func_graph_set_flag, .allow_instances =3D true, #ifdef CONFIG_FTRACE_SELFTEST --=20 2.51.0