Linux Trace Kernel
 help / color / mirror / Atom feed
From: <hu.shengming@zte.com.cn>
To: <hu.shengming@zte.com.cn>
Cc: <rostedt@goodmis.org>, <mhiramat@kernel.org>,
	<mathieu.desnoyers@efficios.com>, <mark.rutland@arm.com>,
	<corbet@lwn.net>, <skhan@linuxfoundation.org>,
	<rdunlap@infradead.org>, <linux-kernel@vger.kernel.org>,
	<linux-trace-kernel@vger.kernel.org>, <linux-doc@vger.kernel.org>,
	<ran.xiaokai@zte.com.cn>, <xu.xin16@zte.com.cn>,
	<zhang.run@zte.com.cn>
Subject: ​[RFC PATCH 2/4] ftrace: Centralize task filter state updates
Date: Sun, 30 Aug 2026 19:10:29 +0800 (CST)	[thread overview]
Message-ID: <20260830191029780ubpoH6QdASK9mvsfhLTcA@zte.com.cn> (raw)
In-Reply-To: <20260830190743637MhXoixrAPc1rfm-G8eIcg@zte.com.cn>

From: Shengming Hu <hu.shengming@zte.com.cn>

A later change will add task comm filtering alongside the existing PID
filters. Both filters need to share the sched_switch probe and the
per-CPU cached task decision.

Move the probe registration and cache refresh logic into
ftrace_task_filters_changed(). This gives PID and future task filters
a single place to update the shared state when a filter changes.

The helper also refreshes the cached result for currently running tasks
when one PID filter is cleared while the other remains active, instead
of leaving the result unchanged until the next schedule-in.

Signed-off-by: Shengming Hu <hu.shengming@zte.com.cn>
---
 kernel/trace/ftrace.c | 58 +++++++++++++++++++++++++++----------------
 1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 479ea004adc3..0c73abb8fec8 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -8637,6 +8637,16 @@ ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops)
 	return ops->func;
 }

+static bool ftrace_task_filters_active(struct trace_array *tr)
+{
+	return rcu_dereference_protected(tr->function_pids,
+					 lockdep_is_held(&ftrace_lock)) ||
+		rcu_dereference_protected(tr->function_no_pids,
+					  lockdep_is_held(&ftrace_lock));
+}
+
+static void ignore_task_cpu(void *data);
+
 static void
 ftrace_filter_task_sched_switch_probe(void *data, bool preempt,
 				     struct task_struct *prev,
@@ -8703,11 +8713,31 @@ void ftrace_pid_follow_fork(struct trace_array *tr, bool enable)
 	}
 }

+static void ftrace_task_filters_changed(struct trace_array *tr,
+					bool was_enabled)
+{
+	bool enabled = ftrace_task_filters_active(tr);
+	int cpu;
+
+	if (!was_enabled && enabled)
+		register_trace_sched_switch(ftrace_filter_task_sched_switch_probe, tr);
+	else if (was_enabled && !enabled) {
+		unregister_trace_sched_switch(ftrace_filter_task_sched_switch_probe, tr);
+		for_each_possible_cpu(cpu)
+			per_cpu_ptr(tr->array_buffer.data, cpu)->ftrace_ignore_pid =
+				FTRACE_PID_TRACE;
+		return;
+	}
+
+	if (enabled)
+		on_each_cpu(ignore_task_cpu, tr, 1);
+}
+
 static void clear_ftrace_pids(struct trace_array *tr, int type)
 {
 	struct trace_pid_list *pid_list;
 	struct trace_pid_list *no_pid_list;
-	int cpu;
+	bool task_filters_enabled;

 	pid_list = rcu_dereference_protected(tr->function_pids,
 					     lockdep_is_held(&ftrace_lock));
@@ -8718,12 +8748,7 @@ static void clear_ftrace_pids(struct trace_array *tr, int type)
 	if (!pid_type_enabled(type, pid_list, no_pid_list))
 		return;

-	/* See if the pids still need to be checked after this */
-	if (!still_need_pid_events(type, pid_list, no_pid_list)) {
-		unregister_trace_sched_switch(ftrace_filter_task_sched_switch_probe, tr);
-		for_each_possible_cpu(cpu)
-			per_cpu_ptr(tr->array_buffer.data, cpu)->ftrace_ignore_pid = FTRACE_PID_TRACE;
-	}
+	task_filters_enabled = ftrace_task_filters_active(tr);

 	if (type & TRACE_PIDS)
 		rcu_assign_pointer(tr->function_pids, NULL);
@@ -8731,6 +8756,8 @@ static void clear_ftrace_pids(struct trace_array *tr, int type)
 	if (type & TRACE_NO_PIDS)
 		rcu_assign_pointer(tr->function_no_pids, NULL);

+	ftrace_task_filters_changed(tr, task_filters_enabled);
+
 	/* Wait till all users are no longer using pid filtering */
 	synchronize_rcu();

@@ -8935,27 +8962,24 @@ pid_write(struct file *filp, const char __user *ubuf,
 	struct seq_file *m = filp->private_data;
 	struct trace_array *tr = m->private;
 	struct trace_pid_list *filtered_pids;
-	struct trace_pid_list *other_pids;
 	struct trace_pid_list *pid_list;
+	bool task_filters_enabled;
 	ssize_t ret;

 	if (!cnt)
 		return 0;

 	guard(mutex)(&ftrace_lock);
+	task_filters_enabled = ftrace_task_filters_active(tr);

 	switch (type) {
 	case TRACE_PIDS:
 		filtered_pids = rcu_dereference_protected(tr->function_pids,
 					     lockdep_is_held(&ftrace_lock));
-		other_pids = rcu_dereference_protected(tr->function_no_pids,
-					     lockdep_is_held(&ftrace_lock));
 		break;
 	case TRACE_NO_PIDS:
 		filtered_pids = rcu_dereference_protected(tr->function_no_pids,
 					     lockdep_is_held(&ftrace_lock));
-		other_pids = rcu_dereference_protected(tr->function_pids,
-					     lockdep_is_held(&ftrace_lock));
 		break;
 	default:
 		WARN_ON_ONCE(1);
@@ -8979,17 +9003,9 @@ pid_write(struct file *filp, const char __user *ubuf,
 	if (filtered_pids) {
 		synchronize_rcu();
 		trace_pid_list_free(filtered_pids);
-	} else if (pid_list && !other_pids) {
-		/* Register a probe to set whether to ignore the tracing of a task */
-		register_trace_sched_switch(ftrace_filter_task_sched_switch_probe, tr);
 	}

-	/*
-	 * Ignoring of pids is done at task switch. But we have to
-	 * check for those tasks that are currently running.
-	 * Always do this in case a pid was appended or removed.
-	 */
-	on_each_cpu(ignore_task_cpu, tr, 1);
+	ftrace_task_filters_changed(tr, task_filters_enabled);

 	ftrace_update_pid_func();
 	ftrace_startup_all(0);
-- 
2.25.1

  parent reply	other threads:[~2026-08-30 11:10 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-30 11:07 [RFC PATCH 0/4] ftrace: Add task comm filtering for function tracing hu.shengming
2026-08-30 11:09 ` [RFC PATCH 1/4] ftrace: Generalize function task filter names hu.shengming
2026-08-30 11:10 ` hu.shengming [this message]
2026-08-30 11:24   ` ​[RFC PATCH 2/4] ftrace: Centralize task filter state updates sashiko-bot
2026-08-30 11:12 ` [RFC PATCH 3/4] ftrace: Add exact task comm filtering hu.shengming
2026-08-30 11:12 ` [RFC PATCH 4/4] Documentation/ftrace: Document function comm filters hu.shengming
2026-08-30 15:27   ` Randy Dunlap
2026-08-31 10:52     ` hu.shengming
2026-08-31  1:20 ` [RFC PATCH 0/4] ftrace: Add task comm filtering for function tracing Masami Hiramatsu
2026-08-31 10:41   ` hu.shengming
2026-08-31 13:49 ` Steven Rostedt
2026-09-03  1:03   ` hu.shengming

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20260830191029780ubpoH6QdASK9mvsfhLTcA@zte.com.cn \
    --to=hu.shengming@zte.com.cn \
    --cc=corbet@lwn.net \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=mhiramat@kernel.org \
    --cc=ran.xiaokai@zte.com.cn \
    --cc=rdunlap@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=skhan@linuxfoundation.org \
    --cc=xu.xin16@zte.com.cn \
    --cc=zhang.run@zte.com.cn \
    /path/to/YOUR_REPLY

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

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