Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc0f51d3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents ad51271a 2e028c4f
Loading
Loading
Loading
Loading
+396 −112

File changed.

Preview size limit exceeded, changes collapsed.

+4 −2
Original line number Diff line number Diff line
@@ -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
+124 −18
Original line number Diff line number Diff line
@@ -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;

	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 ? "     |    " : "");
	const char tgid_space[] = "          ";
	const char space[] = "  ";

	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);
+9 −0
Original line number Diff line number Diff line
@@ -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,
+6 −0
Original line number Diff line number Diff line
@@ -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);
Loading