Merge tag 'trace-v4.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull more tracing updates from Steven Rostedt: "A few more minor updates: - Show the tgid mappings for user space trace tools to use - Fix and optimize the comm and tgid cache recording - Sanitize derived kprobe names - Ftrace selftest updates - trace file header fix - Update of Documentation/trace/ftrace.txt - Compiler warning fixes - Fix possible uninitialized variable" * tag 'trace-v4.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: ftrace: Fix uninitialized variable in match_records() ftrace: Remove an unneeded NULL check ftrace: Hide cached module code for !CONFIG_MODULES tracing: Do note expose stack_trace_filter without DYNAMIC_FTRACE tracing: Update Documentation/trace/ftrace.txt tracing: Fixup trace file header alignment selftests/ftrace: Add a testcase for kprobe event naming selftests/ftrace: Add a test to probe module functions selftests/ftrace: Update multiple kprobes test for powerpc trace/kprobes: Sanitize derived event names tracing: Attempt to record other information even if some fail tracing: Treat recording tgid for idle task as a success tracing: Treat recording comm for idle task as a success tracing: Add saved_tgids file to show cached pid to tgid mappings
This commit is contained in:
@@ -3816,7 +3816,7 @@ match_records(struct ftrace_hash *hash, char *func, int len, char *mod)
|
||||
int exclude_mod = 0;
|
||||
int found = 0;
|
||||
int ret;
|
||||
int clear_filter;
|
||||
int clear_filter = 0;
|
||||
|
||||
if (func) {
|
||||
func_g.type = filter_parse_regex(func, len, &func_g.search,
|
||||
@@ -3950,7 +3950,7 @@ static int cache_mod(struct trace_array *tr,
|
||||
continue;
|
||||
|
||||
/* no func matches all */
|
||||
if (!func || strcmp(func, "*") == 0 ||
|
||||
if (strcmp(func, "*") == 0 ||
|
||||
(ftrace_mod->func &&
|
||||
strcmp(ftrace_mod->func, func) == 0)) {
|
||||
ret = 0;
|
||||
@@ -3978,6 +3978,7 @@ static int
|
||||
ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len,
|
||||
int reset, int enable);
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
static void process_mod_list(struct list_head *head, struct ftrace_ops *ops,
|
||||
char *mod, bool enable)
|
||||
{
|
||||
@@ -4068,6 +4069,7 @@ static void process_cached_mods(const char *mod_name)
|
||||
|
||||
kfree(mod);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We register the module command as a template to show others how
|
||||
|
@@ -1916,7 +1916,11 @@ static int trace_save_cmdline(struct task_struct *tsk)
|
||||
{
|
||||
unsigned pid, idx;
|
||||
|
||||
if (!tsk->pid || unlikely(tsk->pid > PID_MAX_DEFAULT))
|
||||
/* treat recording of idle task as a success */
|
||||
if (!tsk->pid)
|
||||
return 1;
|
||||
|
||||
if (unlikely(tsk->pid > PID_MAX_DEFAULT))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@@ -2002,7 +2006,11 @@ int trace_find_tgid(int pid)
|
||||
|
||||
static int trace_save_tgid(struct task_struct *tsk)
|
||||
{
|
||||
if (unlikely(!tgid_map || !tsk->pid || tsk->pid > PID_MAX_DEFAULT))
|
||||
/* treat recording of idle task as a success */
|
||||
if (!tsk->pid)
|
||||
return 1;
|
||||
|
||||
if (unlikely(!tgid_map || tsk->pid > PID_MAX_DEFAULT))
|
||||
return 0;
|
||||
|
||||
tgid_map[tsk->pid] = tsk->tgid;
|
||||
@@ -2029,11 +2037,20 @@ static bool tracing_record_taskinfo_skip(int flags)
|
||||
*/
|
||||
void tracing_record_taskinfo(struct task_struct *task, int flags)
|
||||
{
|
||||
bool done;
|
||||
|
||||
if (tracing_record_taskinfo_skip(flags))
|
||||
return;
|
||||
if ((flags & TRACE_RECORD_CMDLINE) && !trace_save_cmdline(task))
|
||||
return;
|
||||
if ((flags & TRACE_RECORD_TGID) && !trace_save_tgid(task))
|
||||
|
||||
/*
|
||||
* Record as much task information as possible. If some fail, continue
|
||||
* to try to record the others.
|
||||
*/
|
||||
done = !(flags & TRACE_RECORD_CMDLINE) || trace_save_cmdline(task);
|
||||
done &= !(flags & TRACE_RECORD_TGID) || trace_save_tgid(task);
|
||||
|
||||
/* If recording any information failed, retry again soon. */
|
||||
if (!done)
|
||||
return;
|
||||
|
||||
__this_cpu_write(trace_taskinfo_save, false);
|
||||
@@ -2050,15 +2067,22 @@ void tracing_record_taskinfo(struct task_struct *task, int flags)
|
||||
void tracing_record_taskinfo_sched_switch(struct task_struct *prev,
|
||||
struct task_struct *next, int flags)
|
||||
{
|
||||
bool done;
|
||||
|
||||
if (tracing_record_taskinfo_skip(flags))
|
||||
return;
|
||||
|
||||
if ((flags & TRACE_RECORD_CMDLINE) &&
|
||||
(!trace_save_cmdline(prev) || !trace_save_cmdline(next)))
|
||||
return;
|
||||
/*
|
||||
* Record as much task information as possible. If some fail, continue
|
||||
* to try to record the others.
|
||||
*/
|
||||
done = !(flags & TRACE_RECORD_CMDLINE) || trace_save_cmdline(prev);
|
||||
done &= !(flags & TRACE_RECORD_CMDLINE) || trace_save_cmdline(next);
|
||||
done &= !(flags & TRACE_RECORD_TGID) || trace_save_tgid(prev);
|
||||
done &= !(flags & TRACE_RECORD_TGID) || trace_save_tgid(next);
|
||||
|
||||
if ((flags & TRACE_RECORD_TGID) &&
|
||||
(!trace_save_tgid(prev) || !trace_save_tgid(next)))
|
||||
/* If recording any information failed, retry again soon. */
|
||||
if (!done)
|
||||
return;
|
||||
|
||||
__this_cpu_write(trace_taskinfo_save, false);
|
||||
@@ -3334,14 +3358,23 @@ static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file
|
||||
unsigned int flags)
|
||||
{
|
||||
bool tgid = flags & TRACE_ITER_RECORD_TGID;
|
||||
const char tgid_space[] = " ";
|
||||
const char space[] = " ";
|
||||
|
||||
seq_printf(m, "# %s _-----=> irqs-off\n", tgid ? " " : "");
|
||||
seq_printf(m, "# %s / _----=> need-resched\n", tgid ? " " : "");
|
||||
seq_printf(m, "# %s| / _---=> hardirq/softirq\n", tgid ? " " : "");
|
||||
seq_printf(m, "# %s|| / _--=> preempt-depth\n", tgid ? " " : "");
|
||||
seq_printf(m, "# %s||| / delay\n", tgid ? " " : "");
|
||||
seq_printf(m, "# TASK-PID CPU#%s|||| TIMESTAMP FUNCTION\n", tgid ? " TGID " : "");
|
||||
seq_printf(m, "# | | | %s|||| | |\n", tgid ? " | " : "");
|
||||
seq_printf(m, "# %s _-----=> irqs-off\n",
|
||||
tgid ? tgid_space : space);
|
||||
seq_printf(m, "# %s / _----=> need-resched\n",
|
||||
tgid ? tgid_space : space);
|
||||
seq_printf(m, "# %s| / _---=> hardirq/softirq\n",
|
||||
tgid ? tgid_space : space);
|
||||
seq_printf(m, "# %s|| / _--=> preempt-depth\n",
|
||||
tgid ? tgid_space : space);
|
||||
seq_printf(m, "# %s||| / delay\n",
|
||||
tgid ? tgid_space : space);
|
||||
seq_printf(m, "# TASK-PID CPU#%s|||| TIMESTAMP FUNCTION\n",
|
||||
tgid ? " TGID " : space);
|
||||
seq_printf(m, "# | | | %s|||| | |\n",
|
||||
tgid ? " | " : space);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4689,6 +4722,76 @@ static const struct file_operations tracing_readme_fops = {
|
||||
.llseek = generic_file_llseek,
|
||||
};
|
||||
|
||||
static void *saved_tgids_next(struct seq_file *m, void *v, loff_t *pos)
|
||||
{
|
||||
int *ptr = v;
|
||||
|
||||
if (*pos || m->count)
|
||||
ptr++;
|
||||
|
||||
(*pos)++;
|
||||
|
||||
for (; ptr <= &tgid_map[PID_MAX_DEFAULT]; ptr++) {
|
||||
if (trace_find_tgid(*ptr))
|
||||
return ptr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *saved_tgids_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
void *v;
|
||||
loff_t l = 0;
|
||||
|
||||
if (!tgid_map)
|
||||
return NULL;
|
||||
|
||||
v = &tgid_map[0];
|
||||
while (l <= *pos) {
|
||||
v = saved_tgids_next(m, v, &l);
|
||||
if (!v)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static void saved_tgids_stop(struct seq_file *m, void *v)
|
||||
{
|
||||
}
|
||||
|
||||
static int saved_tgids_show(struct seq_file *m, void *v)
|
||||
{
|
||||
int pid = (int *)v - tgid_map;
|
||||
|
||||
seq_printf(m, "%d %d\n", pid, trace_find_tgid(pid));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct seq_operations tracing_saved_tgids_seq_ops = {
|
||||
.start = saved_tgids_start,
|
||||
.stop = saved_tgids_stop,
|
||||
.next = saved_tgids_next,
|
||||
.show = saved_tgids_show,
|
||||
};
|
||||
|
||||
static int tracing_saved_tgids_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
if (tracing_disabled)
|
||||
return -ENODEV;
|
||||
|
||||
return seq_open(filp, &tracing_saved_tgids_seq_ops);
|
||||
}
|
||||
|
||||
|
||||
static const struct file_operations tracing_saved_tgids_fops = {
|
||||
.open = tracing_saved_tgids_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static void *saved_cmdlines_next(struct seq_file *m, void *v, loff_t *pos)
|
||||
{
|
||||
unsigned int *ptr = v;
|
||||
@@ -7921,6 +8024,9 @@ static __init int tracer_init_tracefs(void)
|
||||
trace_create_file("saved_cmdlines_size", 0644, d_tracer,
|
||||
NULL, &tracing_saved_cmdlines_size_fops);
|
||||
|
||||
trace_create_file("saved_tgids", 0444, d_tracer,
|
||||
NULL, &tracing_saved_tgids_fops);
|
||||
|
||||
trace_eval_init();
|
||||
|
||||
trace_create_eval_file(d_tracer);
|
||||
|
@@ -598,6 +598,14 @@ static struct notifier_block trace_kprobe_module_nb = {
|
||||
.priority = 1 /* Invoked after kprobe module callback */
|
||||
};
|
||||
|
||||
/* Convert certain expected symbols into '_' when generating event names */
|
||||
static inline void sanitize_event_name(char *name)
|
||||
{
|
||||
while (*name++ != '\0')
|
||||
if (*name == ':' || *name == '.')
|
||||
*name = '_';
|
||||
}
|
||||
|
||||
static int create_trace_kprobe(int argc, char **argv)
|
||||
{
|
||||
/*
|
||||
@@ -736,6 +744,7 @@ static int create_trace_kprobe(int argc, char **argv)
|
||||
else
|
||||
snprintf(buf, MAX_EVENT_NAME_LEN, "%c_0x%p",
|
||||
is_return ? 'r' : 'p', addr);
|
||||
sanitize_event_name(buf);
|
||||
event = buf;
|
||||
}
|
||||
tk = alloc_trace_kprobe(group, event, addr, symbol, offset, maxactive,
|
||||
|
@@ -406,6 +406,8 @@ static const struct file_operations stack_trace_fops = {
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
|
||||
static int
|
||||
stack_trace_filter_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
@@ -423,6 +425,8 @@ static const struct file_operations stack_trace_filter_fops = {
|
||||
.release = ftrace_regex_release,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE */
|
||||
|
||||
int
|
||||
stack_trace_sysctl(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp,
|
||||
@@ -477,8 +481,10 @@ static __init int stack_trace_init(void)
|
||||
trace_create_file("stack_trace", 0444, d_tracer,
|
||||
NULL, &stack_trace_fops);
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
trace_create_file("stack_trace_filter", 0444, d_tracer,
|
||||
&trace_ops, &stack_trace_filter_fops);
|
||||
#endif
|
||||
|
||||
if (stack_trace_filter_buf[0])
|
||||
ftrace_set_early_filter(&trace_ops, stack_trace_filter_buf, 1);
|
||||
|
Reference in New Issue
Block a user