Commit 544521d6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull probes updates from Masami Hiramatsu:

 - kprobes: Cleanups using guard() and __free(): Use cleanup.h macros to
   cleanup code and remove all gotos from kprobes code.

 - tracing/probes: Also cleanups tracing/*probe events code with guard()
   and __free(). These patches are just to simplify the parser codes.

 - kprobes: Reduce preempt disable scope in check_kprobe_access_safe()

   This reduces preempt disable time to only when getting the module
   refcount in check_kprobe_access_safe().

   Previously it disabled preempt needlessly for other checks including
   jump_label_text_reserved(), which took a long time because of the
   linear search.

* tag 'probes-v6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  tracing/kprobes: Simplify __trace_kprobe_create() by removing gotos
  tracing: Use __free() for kprobe events to cleanup
  tracing: Use __free() in trace_probe for cleanup
  kprobes: Remove remaining gotos
  kprobes: Remove unneeded goto
  kprobes: Use guard for rcu_read_lock
  kprobes: Use guard() for external locks
  jump_label: Define guard() for jump_label_lock
  tracing/eprobe: Adopt guard() and scoped_guard()
  tracing/uprobe: Adopt guard() and scoped_guard()
  tracing/kprobe: Adopt guard() and scoped_guard()
  kprobes: Adopt guard() and scoped_guard()
  kprobes: Reduce preempt disable scope in check_kprobe_access_safe()
parents e0b1f591 92705460
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@

#include <linux/types.h>
#include <linux/compiler.h>
#include <linux/cleanup.h>

extern bool static_key_initialized;

@@ -347,6 +348,8 @@ static inline void static_key_disable(struct static_key *key)

#endif	/* CONFIG_JUMP_LABEL */

DEFINE_LOCK_GUARD_0(jump_label_lock, jump_label_lock(), jump_label_unlock())

#define STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
#define jump_label_enabled static_key_enabled

+269 −323

File changed.

Preview size limit exceeded, changes collapsed.

+17 −19
Original line number Diff line number Diff line
@@ -917,10 +917,10 @@ static int __trace_eprobe_create(int argc, const char *argv[])
		goto error;
	}

	mutex_lock(&event_mutex);
	scoped_guard(mutex, &event_mutex) {
		event_call = find_and_get_event(sys_name, sys_event);
		ep = alloc_event_probe(group, event, event_call, argc - 2);
	mutex_unlock(&event_mutex);
	}

	if (IS_ERR(ep)) {
		ret = PTR_ERR(ep);
@@ -952,23 +952,21 @@ static int __trace_eprobe_create(int argc, const char *argv[])
	if (ret < 0)
		goto error;
	init_trace_eprobe_call(ep);
	mutex_lock(&event_mutex);
	scoped_guard(mutex, &event_mutex) {
		ret = trace_probe_register_event_call(&ep->tp);
		if (ret) {
			if (ret == -EEXIST) {
				trace_probe_log_set_index(0);
				trace_probe_log_err(0, EVENT_EXIST);
			}
		mutex_unlock(&event_mutex);
			goto error;
		}
		ret = dyn_event_add(&ep->devent, &ep->tp.event->call);
		if (ret < 0) {
			trace_probe_unregister_event_call(&ep->tp);
		mutex_unlock(&event_mutex);
			goto error;
		}
	mutex_unlock(&event_mutex);
	}
	return ret;
parse_error:
	ret = -EINVAL;
+73 −82

File changed.

Preview size limit exceeded, changes collapsed.

+17 −34
Original line number Diff line number Diff line
@@ -1409,7 +1409,7 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
					   struct traceprobe_parse_context *ctx)
{
	struct fetch_insn *code, *tmp = NULL;
	char *type, *arg;
	char *type, *arg __free(kfree) = NULL;
	int ret, len;

	len = strlen(argv);
@@ -1426,22 +1426,16 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
		return -ENOMEM;

	parg->comm = kstrdup(arg, GFP_KERNEL);
	if (!parg->comm) {
		ret = -ENOMEM;
		goto out;
	}
	if (!parg->comm)
		return -ENOMEM;

	type = parse_probe_arg_type(arg, parg, ctx);
	if (IS_ERR(type)) {
		ret = PTR_ERR(type);
		goto out;
	}
	if (IS_ERR(type))
		return PTR_ERR(type);

	code = tmp = kcalloc(FETCH_INSN_MAX, sizeof(*code), GFP_KERNEL);
	if (!code) {
		ret = -ENOMEM;
		goto out;
	}
	if (!code)
		return -ENOMEM;
	code[FETCH_INSN_MAX - 1].op = FETCH_OP_END;

	ctx->last_type = NULL;
@@ -1497,8 +1491,6 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
				kfree(code->data);
	}
	kfree(tmp);
out:
	kfree(arg);

	return ret;
}
@@ -1668,7 +1660,7 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[],
{
	const struct btf_param *params = NULL;
	int i, j, n, used, ret, args_idx = -1;
	const char **new_argv = NULL;
	const char **new_argv __free(kfree) = NULL;

	ret = argv_has_var_arg(argc, argv, &args_idx, ctx);
	if (ret < 0)
@@ -1707,7 +1699,7 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[],
				ret = sprint_nth_btf_arg(n, "", buf + used,
							 bufsize - used, ctx);
				if (ret < 0)
					goto error;
					return ERR_PTR(ret);

				new_argv[j++] = buf + used;
				used += ret + 1;
@@ -1721,25 +1713,20 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[],
			n = simple_strtoul(argv[i] + 4, &type, 10);
			if (type && !(*type == ':' || *type == '\0')) {
				trace_probe_log_err(0, BAD_VAR);
				ret = -ENOENT;
				goto error;
				return ERR_PTR(-ENOENT);
			}
			/* Note: $argN starts from $arg1 */
			ret = sprint_nth_btf_arg(n - 1, type, buf + used,
						 bufsize - used, ctx);
			if (ret < 0)
				goto error;
				return ERR_PTR(ret);
			new_argv[j++] = buf + used;
			used += ret + 1;
		} else
			new_argv[j++] = argv[i];
	}

	return new_argv;

error:
	kfree(new_argv);
	return ERR_PTR(ret);
	return_ptr(new_argv);
}

/* @buf: *buf must be equal to NULL. Caller must to free *buf */
@@ -1747,14 +1734,14 @@ int traceprobe_expand_dentry_args(int argc, const char *argv[], char **buf)
{
	int i, used, ret;
	const int bufsize = MAX_DENTRY_ARGS_LEN;
	char *tmpbuf = NULL;
	char *tmpbuf __free(kfree) = NULL;

	if (*buf)
		return -EINVAL;

	used = 0;
	for (i = 0; i < argc; i++) {
		char *tmp;
		char *tmp __free(kfree) = NULL;
		char *equal;
		size_t arg_len;

@@ -1769,7 +1756,7 @@ int traceprobe_expand_dentry_args(int argc, const char *argv[], char **buf)

		tmp = kstrdup(argv[i], GFP_KERNEL);
		if (!tmp)
			goto nomem;
			return -ENOMEM;

		equal = strchr(tmp, '=');
		if (equal)
@@ -1790,18 +1777,14 @@ int traceprobe_expand_dentry_args(int argc, const char *argv[], char **buf)
				       offsetof(struct file, f_path.dentry),
				       equal ? equal + 1 : tmp);

		kfree(tmp);
		if (ret >= bufsize - used)
			goto nomem;
			return -ENOMEM;
		argv[i] = tmpbuf + used;
		used += ret + 1;
	}

	*buf = tmpbuf;
	*buf = no_free_ptr(tmpbuf);
	return 0;
nomem:
	kfree(tmpbuf);
	return -ENOMEM;
}

void traceprobe_finish_parse(struct traceprobe_parse_context *ctx)
Loading