Skip to content

Commit 717e3f5

Browse files
committed
ftrace: Make function trace pid filtering a bit more exact
The set_ftrace_pid file is used to filter function tracing to only trace tasks that are listed in that file. Instead of testing the pids listed in that file (it's a bitmask) at each function trace event, the logic is done via a sched_switch hook. A flag is set when the next task to run is in the list of pids in the set_ftrace_pid file. But the sched_switch hook is not at the exact location of when the task switches, and the flag gets set before the task to be traced actually runs. This leaves a residue of traced functions that do not belong to the pid that should be filtered on. By changing the logic slightly, where instead of having a boolean flag to test, record the pid that should be traced, with special values for not to trace and always trace. Then at each function call, a check will be made to see if the function should be ignored, or if the current pid matches the function that should be traced, and only trace if it matches (or if it has the special value to always trace). Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent 6a13a0d commit 717e3f5

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

kernel/trace/ftrace.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,23 @@ static inline void ftrace_ops_init(struct ftrace_ops *ops)
139139
#endif
140140
}
141141

142+
#define FTRACE_PID_IGNORE -1
143+
#define FTRACE_PID_TRACE -2
144+
142145
static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip,
143146
struct ftrace_ops *op, struct pt_regs *regs)
144147
{
145148
struct trace_array *tr = op->private;
149+
int pid;
146150

147-
if (tr && this_cpu_read(tr->array_buffer.data->ftrace_ignore_pid))
148-
return;
151+
if (tr) {
152+
pid = this_cpu_read(tr->array_buffer.data->ftrace_ignore_pid);
153+
if (pid == FTRACE_PID_IGNORE)
154+
return;
155+
if (pid != FTRACE_PID_TRACE &&
156+
pid != current->pid)
157+
return;
158+
}
149159

150160
op->saved_func(ip, parent_ip, op, regs);
151161
}
@@ -6924,8 +6934,12 @@ ftrace_filter_pid_sched_switch_probe(void *data, bool preempt,
69246934

69256935
pid_list = rcu_dereference_sched(tr->function_pids);
69266936

6927-
this_cpu_write(tr->array_buffer.data->ftrace_ignore_pid,
6928-
trace_ignore_this_task(pid_list, next));
6937+
if (trace_ignore_this_task(pid_list, next))
6938+
this_cpu_write(tr->array_buffer.data->ftrace_ignore_pid,
6939+
FTRACE_PID_IGNORE);
6940+
else
6941+
this_cpu_write(tr->array_buffer.data->ftrace_ignore_pid,
6942+
next->pid);
69296943
}
69306944

69316945
static void
@@ -6978,7 +6992,7 @@ static void clear_ftrace_pids(struct trace_array *tr)
69786992
unregister_trace_sched_switch(ftrace_filter_pid_sched_switch_probe, tr);
69796993

69806994
for_each_possible_cpu(cpu)
6981-
per_cpu_ptr(tr->array_buffer.data, cpu)->ftrace_ignore_pid = false;
6995+
per_cpu_ptr(tr->array_buffer.data, cpu)->ftrace_ignore_pid = FTRACE_PID_TRACE;
69826996

69836997
rcu_assign_pointer(tr->function_pids, NULL);
69846998

@@ -7103,8 +7117,12 @@ static void ignore_task_cpu(void *data)
71037117
pid_list = rcu_dereference_protected(tr->function_pids,
71047118
mutex_is_locked(&ftrace_lock));
71057119

7106-
this_cpu_write(tr->array_buffer.data->ftrace_ignore_pid,
7107-
trace_ignore_this_task(pid_list, current));
7120+
if (trace_ignore_this_task(pid_list, current))
7121+
this_cpu_write(tr->array_buffer.data->ftrace_ignore_pid,
7122+
FTRACE_PID_IGNORE);
7123+
else
7124+
this_cpu_write(tr->array_buffer.data->ftrace_ignore_pid,
7125+
current->pid);
71087126
}
71097127

71107128
static ssize_t

kernel/trace/trace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,10 @@ struct trace_array_cpu {
178178
kuid_t uid;
179179
char comm[TASK_COMM_LEN];
180180

181-
bool ignore_pid;
182181
#ifdef CONFIG_FUNCTION_TRACER
183-
bool ftrace_ignore_pid;
182+
int ftrace_ignore_pid;
184183
#endif
184+
bool ignore_pid;
185185
};
186186

187187
struct tracer;

0 commit comments

Comments
 (0)