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

Commit f4ef6a43 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull tracing fixes from Steven Rostedt:
 "Various fixes in tracing:

   - Tracepoints should not give warning on OOM failures

   - Use special field for function pointer in trace event

   - Fix igrab issues in uprobes

   - Fixes to the new histogram triggers"

* tag 'trace-v4.17-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  tracepoint: Do not warn on ENOMEM
  tracing: Add field modifier parsing hist error for hist triggers
  tracing: Add field parsing hist error for hist triggers
  tracing: Restore proper field flag printing when displaying triggers
  tracing: initcall: Ordered comparison of function pointers
  tracing: Remove igrab() iput() call from uprobes.c
  tracing: Fix bad use of igrab in trace_uprobe.c
parents ecd649b3 d66a270b
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -31,7 +31,11 @@ TRACE_EVENT(initcall_start,
	TP_ARGS(func),

	TP_STRUCT__entry(
		__field(initcall_t, func)
		/*
		 * Use field_struct to avoid is_signed_type()
		 * comparison of a function pointer
		 */
		__field_struct(initcall_t, func)
	),

	TP_fast_assign(
@@ -48,7 +52,11 @@ TRACE_EVENT(initcall_finish,
	TP_ARGS(func, ret),

	TP_STRUCT__entry(
		__field(initcall_t,	func)
		/*
		 * Use field_struct to avoid is_signed_type()
		 * comparison of a function pointer
		 */
		__field_struct(initcall_t,	func)
		__field(int,			ret)
	),

+3 −4
Original line number Diff line number Diff line
@@ -491,7 +491,7 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
	if (!uprobe)
		return NULL;

	uprobe->inode = igrab(inode);
	uprobe->inode = inode;
	uprobe->offset = offset;
	init_rwsem(&uprobe->register_rwsem);
	init_rwsem(&uprobe->consumer_rwsem);
@@ -502,7 +502,6 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
	if (cur_uprobe) {
		kfree(uprobe);
		uprobe = cur_uprobe;
		iput(inode);
	}

	return uprobe;
@@ -701,7 +700,6 @@ static void delete_uprobe(struct uprobe *uprobe)
	rb_erase(&uprobe->rb_node, &uprobes_tree);
	spin_unlock(&uprobes_treelock);
	RB_CLEAR_NODE(&uprobe->rb_node); /* for uprobe_is_active() */
	iput(uprobe->inode);
	put_uprobe(uprobe);
}

@@ -873,7 +871,8 @@ static void __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *u
 * tuple).  Creation refcount stops uprobe_unregister from freeing the
 * @uprobe even before the register operation is complete. Creation
 * refcount is released when the last @uc for the @uprobe
 * unregisters.
 * unregisters. Caller of uprobe_register() is required to keep @inode
 * (and the containing mount) referenced.
 *
 * Return errno if it cannot successully install probes
 * else return 0 (success)
+12 −0
Original line number Diff line number Diff line
@@ -2466,6 +2466,7 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,
		else if (strcmp(modifier, "usecs") == 0)
			*flags |= HIST_FIELD_FL_TIMESTAMP_USECS;
		else {
			hist_err("Invalid field modifier: ", modifier);
			field = ERR_PTR(-EINVAL);
			goto out;
		}
@@ -2481,6 +2482,7 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,
	else {
		field = trace_find_event_field(file->event_call, field_name);
		if (!field || !field->size) {
			hist_err("Couldn't find field: ", field_name);
			field = ERR_PTR(-EINVAL);
			goto out;
		}
@@ -4913,6 +4915,16 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field)
		seq_printf(m, "%s", field_name);
	} else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP)
		seq_puts(m, "common_timestamp");

	if (hist_field->flags) {
		if (!(hist_field->flags & HIST_FIELD_FL_VAR_REF) &&
		    !(hist_field->flags & HIST_FIELD_FL_EXPR)) {
			const char *flags = get_hist_field_flags(hist_field);

			if (flags)
				seq_printf(m, ".%s", flags);
		}
	}
}

static int event_hist_trigger_print(struct seq_file *m,
+14 −21
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ struct trace_uprobe {
	struct list_head		list;
	struct trace_uprobe_filter	filter;
	struct uprobe_consumer		consumer;
	struct path			path;
	struct inode			*inode;
	char				*filename;
	unsigned long			offset;
@@ -289,7 +290,7 @@ static void free_trace_uprobe(struct trace_uprobe *tu)
	for (i = 0; i < tu->tp.nr_args; i++)
		traceprobe_free_probe_arg(&tu->tp.args[i]);

	iput(tu->inode);
	path_put(&tu->path);
	kfree(tu->tp.call.class->system);
	kfree(tu->tp.call.name);
	kfree(tu->filename);
@@ -363,7 +364,6 @@ static int register_trace_uprobe(struct trace_uprobe *tu)
static int create_trace_uprobe(int argc, char **argv)
{
	struct trace_uprobe *tu;
	struct inode *inode;
	char *arg, *event, *group, *filename;
	char buf[MAX_EVENT_NAME_LEN];
	struct path path;
@@ -371,7 +371,6 @@ static int create_trace_uprobe(int argc, char **argv)
	bool is_delete, is_return;
	int i, ret;

	inode = NULL;
	ret = 0;
	is_delete = false;
	is_return = false;
@@ -437,21 +436,16 @@ static int create_trace_uprobe(int argc, char **argv)
	}
	/* Find the last occurrence, in case the path contains ':' too. */
	arg = strrchr(argv[1], ':');
	if (!arg) {
		ret = -EINVAL;
		goto fail_address_parse;
	}
	if (!arg)
		return -EINVAL;

	*arg++ = '\0';
	filename = argv[1];
	ret = kern_path(filename, LOOKUP_FOLLOW, &path);
	if (ret)
		goto fail_address_parse;

	inode = igrab(d_real_inode(path.dentry));
	path_put(&path);
		return ret;

	if (!inode || !S_ISREG(inode->i_mode)) {
	if (!d_is_reg(path.dentry)) {
		ret = -EINVAL;
		goto fail_address_parse;
	}
@@ -490,7 +484,7 @@ static int create_trace_uprobe(int argc, char **argv)
		goto fail_address_parse;
	}
	tu->offset = offset;
	tu->inode = inode;
	tu->path = path;
	tu->filename = kstrdup(filename, GFP_KERNEL);

	if (!tu->filename) {
@@ -558,7 +552,7 @@ static int create_trace_uprobe(int argc, char **argv)
	return ret;

fail_address_parse:
	iput(inode);
	path_put(&path);

	pr_info("Failed to parse address or file.\n");

@@ -922,6 +916,7 @@ probe_event_enable(struct trace_uprobe *tu, struct trace_event_file *file,
		goto err_flags;

	tu->consumer.filter = filter;
	tu->inode = d_real_inode(tu->path.dentry);
	ret = uprobe_register(tu->inode, tu->offset, &tu->consumer);
	if (ret)
		goto err_buffer;
@@ -967,6 +962,7 @@ probe_event_disable(struct trace_uprobe *tu, struct trace_event_file *file)
	WARN_ON(!uprobe_filter_is_empty(&tu->filter));

	uprobe_unregister(tu->inode, tu->offset, &tu->consumer);
	tu->inode = NULL;
	tu->tp.flags &= file ? ~TP_FLAG_TRACE : ~TP_FLAG_PROFILE;

	uprobe_buffer_disable();
@@ -1337,7 +1333,6 @@ struct trace_event_call *
create_local_trace_uprobe(char *name, unsigned long offs, bool is_return)
{
	struct trace_uprobe *tu;
	struct inode *inode;
	struct path path;
	int ret;

@@ -1345,11 +1340,8 @@ create_local_trace_uprobe(char *name, unsigned long offs, bool is_return)
	if (ret)
		return ERR_PTR(ret);

	inode = igrab(d_inode(path.dentry));
	if (!d_is_reg(path.dentry)) {
		path_put(&path);

	if (!inode || !S_ISREG(inode->i_mode)) {
		iput(inode);
		return ERR_PTR(-EINVAL);
	}

@@ -1364,11 +1356,12 @@ create_local_trace_uprobe(char *name, unsigned long offs, bool is_return)
	if (IS_ERR(tu)) {
		pr_info("Failed to allocate trace_uprobe.(%d)\n",
			(int)PTR_ERR(tu));
		path_put(&path);
		return ERR_CAST(tu);
	}

	tu->offset = offs;
	tu->inode = inode;
	tu->path = path;
	tu->filename = kstrdup(name, GFP_KERNEL);
	init_trace_event_call(tu, &tu->tp.call);

+2 −2
Original line number Diff line number Diff line
@@ -207,7 +207,7 @@ static int tracepoint_add_func(struct tracepoint *tp,
			lockdep_is_held(&tracepoints_mutex));
	old = func_add(&tp_funcs, func, prio);
	if (IS_ERR(old)) {
		WARN_ON_ONCE(1);
		WARN_ON_ONCE(PTR_ERR(old) != -ENOMEM);
		return PTR_ERR(old);
	}

@@ -239,7 +239,7 @@ static int tracepoint_remove_func(struct tracepoint *tp,
			lockdep_is_held(&tracepoints_mutex));
	old = func_remove(&tp_funcs, func);
	if (IS_ERR(old)) {
		WARN_ON_ONCE(1);
		WARN_ON_ONCE(PTR_ERR(old) != -ENOMEM);
		return PTR_ERR(old);
	}