mirror of
https://github.com/torvalds/linux.git
synced 2025-11-03 10:10:33 +02:00
tracing: Adopt __free() and guard() for trace_fprobe.c
Adopt __free() and guard() for trace_fprobe.c to remove gotos. Link: https://lore.kernel.org/173708043449.319651.12242878905778792182.stgit@mhiramat.roam.corp.google.com Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
This commit is contained in:
parent
4f7caaa2f9
commit
8275637215
1 changed files with 58 additions and 66 deletions
|
|
@ -416,6 +416,9 @@ static void free_trace_fprobe(struct trace_fprobe *tf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Since alloc_trace_fprobe() can return error, check the pointer is ERR too. */
|
||||||
|
DEFINE_FREE(free_trace_fprobe, struct trace_fprobe *, if (!IS_ERR_OR_NULL(_T)) free_trace_fprobe(_T))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate new trace_probe and initialize it (including fprobe).
|
* Allocate new trace_probe and initialize it (including fprobe).
|
||||||
*/
|
*/
|
||||||
|
|
@ -426,7 +429,7 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group,
|
||||||
struct module *mod,
|
struct module *mod,
|
||||||
int nargs, bool is_return)
|
int nargs, bool is_return)
|
||||||
{
|
{
|
||||||
struct trace_fprobe *tf;
|
struct trace_fprobe *tf __free(free_trace_fprobe) = NULL;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
tf = kzalloc(struct_size(tf, tp.args, nargs), GFP_KERNEL);
|
tf = kzalloc(struct_size(tf, tp.args, nargs), GFP_KERNEL);
|
||||||
|
|
@ -435,7 +438,7 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group,
|
||||||
|
|
||||||
tf->symbol = kstrdup(symbol, GFP_KERNEL);
|
tf->symbol = kstrdup(symbol, GFP_KERNEL);
|
||||||
if (!tf->symbol)
|
if (!tf->symbol)
|
||||||
goto error;
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
if (is_return)
|
if (is_return)
|
||||||
tf->fp.exit_handler = fexit_dispatcher;
|
tf->fp.exit_handler = fexit_dispatcher;
|
||||||
|
|
@ -447,13 +450,10 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group,
|
||||||
|
|
||||||
ret = trace_probe_init(&tf->tp, event, group, false, nargs);
|
ret = trace_probe_init(&tf->tp, event, group, false, nargs);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error;
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
dyn_event_init(&tf->devent, &trace_fprobe_ops);
|
dyn_event_init(&tf->devent, &trace_fprobe_ops);
|
||||||
return tf;
|
return_ptr(tf);
|
||||||
error:
|
|
||||||
free_trace_fprobe(tf);
|
|
||||||
return ERR_PTR(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct trace_fprobe *find_trace_fprobe(const char *event,
|
static struct trace_fprobe *find_trace_fprobe(const char *event,
|
||||||
|
|
@ -880,14 +880,12 @@ static int register_trace_fprobe(struct trace_fprobe *tf)
|
||||||
struct trace_fprobe *old_tf;
|
struct trace_fprobe *old_tf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&event_mutex);
|
guard(mutex)(&event_mutex);
|
||||||
|
|
||||||
old_tf = find_trace_fprobe(trace_probe_name(&tf->tp),
|
old_tf = find_trace_fprobe(trace_probe_name(&tf->tp),
|
||||||
trace_probe_group_name(&tf->tp));
|
trace_probe_group_name(&tf->tp));
|
||||||
if (old_tf) {
|
if (old_tf)
|
||||||
ret = append_trace_fprobe(tf, old_tf);
|
return append_trace_fprobe(tf, old_tf);
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Register new event */
|
/* Register new event */
|
||||||
ret = register_fprobe_event(tf);
|
ret = register_fprobe_event(tf);
|
||||||
|
|
@ -897,7 +895,7 @@ static int register_trace_fprobe(struct trace_fprobe *tf)
|
||||||
trace_probe_log_err(0, EVENT_EXIST);
|
trace_probe_log_err(0, EVENT_EXIST);
|
||||||
} else
|
} else
|
||||||
pr_warn("Failed to register probe event(%d)\n", ret);
|
pr_warn("Failed to register probe event(%d)\n", ret);
|
||||||
goto end;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register fprobe */
|
/* Register fprobe */
|
||||||
|
|
@ -907,8 +905,6 @@ static int register_trace_fprobe(struct trace_fprobe *tf)
|
||||||
else
|
else
|
||||||
dyn_event_add(&tf->devent, trace_probe_event_call(&tf->tp));
|
dyn_event_add(&tf->devent, trace_probe_event_call(&tf->tp));
|
||||||
|
|
||||||
end:
|
|
||||||
mutex_unlock(&event_mutex);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1069,7 +1065,10 @@ static int parse_symbol_and_return(int argc, const char *argv[],
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __trace_fprobe_create(int argc, const char *argv[])
|
DEFINE_FREE(module_put, struct module *, if (_T) module_put(_T))
|
||||||
|
|
||||||
|
static int trace_fprobe_create_internal(int argc, const char *argv[],
|
||||||
|
struct traceprobe_parse_context *ctx)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Argument syntax:
|
* Argument syntax:
|
||||||
|
|
@ -1095,23 +1094,20 @@ static int __trace_fprobe_create(int argc, const char *argv[])
|
||||||
* Type of args:
|
* Type of args:
|
||||||
* FETCHARG:TYPE : use TYPE instead of unsigned long.
|
* FETCHARG:TYPE : use TYPE instead of unsigned long.
|
||||||
*/
|
*/
|
||||||
struct trace_fprobe *tf = NULL;
|
struct trace_fprobe *tf __free(free_trace_fprobe) = NULL;
|
||||||
int i, new_argc = 0, ret = 0;
|
int i, new_argc = 0, ret = 0;
|
||||||
bool is_return = false;
|
bool is_return = false;
|
||||||
char *symbol = NULL;
|
char *symbol __free(kfree) = NULL;
|
||||||
const char *event = NULL, *group = FPROBE_EVENT_SYSTEM;
|
const char *event = NULL, *group = FPROBE_EVENT_SYSTEM;
|
||||||
const char **new_argv = NULL;
|
const char **new_argv __free(kfree) = NULL;
|
||||||
char buf[MAX_EVENT_NAME_LEN];
|
char buf[MAX_EVENT_NAME_LEN];
|
||||||
char gbuf[MAX_EVENT_NAME_LEN];
|
char gbuf[MAX_EVENT_NAME_LEN];
|
||||||
char sbuf[KSYM_NAME_LEN];
|
char sbuf[KSYM_NAME_LEN];
|
||||||
char abuf[MAX_BTF_ARGS_LEN];
|
char abuf[MAX_BTF_ARGS_LEN];
|
||||||
char *dbuf = NULL;
|
char *dbuf __free(kfree) = NULL;
|
||||||
bool is_tracepoint = false;
|
bool is_tracepoint = false;
|
||||||
struct module *tp_mod = NULL;
|
struct module *tp_mod __free(module_put) = NULL;
|
||||||
struct tracepoint *tpoint = NULL;
|
struct tracepoint *tpoint = NULL;
|
||||||
struct traceprobe_parse_context ctx = {
|
|
||||||
.flags = TPARG_FL_KERNEL | TPARG_FL_FPROBE,
|
|
||||||
};
|
|
||||||
|
|
||||||
if ((argv[0][0] != 'f' && argv[0][0] != 't') || argc < 2)
|
if ((argv[0][0] != 'f' && argv[0][0] != 't') || argc < 2)
|
||||||
return -ECANCELED;
|
return -ECANCELED;
|
||||||
|
|
@ -1121,13 +1117,11 @@ static int __trace_fprobe_create(int argc, const char *argv[])
|
||||||
group = TRACEPOINT_EVENT_SYSTEM;
|
group = TRACEPOINT_EVENT_SYSTEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_probe_log_init("trace_fprobe", argc, argv);
|
|
||||||
|
|
||||||
if (argv[0][1] != '\0') {
|
if (argv[0][1] != '\0') {
|
||||||
if (argv[0][1] != ':') {
|
if (argv[0][1] != ':') {
|
||||||
trace_probe_log_set_index(0);
|
trace_probe_log_set_index(0);
|
||||||
trace_probe_log_err(1, BAD_MAXACT);
|
trace_probe_log_err(1, BAD_MAXACT);
|
||||||
goto parse_error;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
event = &argv[0][2];
|
event = &argv[0][2];
|
||||||
}
|
}
|
||||||
|
|
@ -1137,14 +1131,14 @@ static int __trace_fprobe_create(int argc, const char *argv[])
|
||||||
/* a symbol(or tracepoint) must be specified */
|
/* a symbol(or tracepoint) must be specified */
|
||||||
ret = parse_symbol_and_return(argc, argv, &symbol, &is_return, is_tracepoint);
|
ret = parse_symbol_and_return(argc, argv, &symbol, &is_return, is_tracepoint);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto parse_error;
|
return -EINVAL;
|
||||||
|
|
||||||
trace_probe_log_set_index(0);
|
trace_probe_log_set_index(0);
|
||||||
if (event) {
|
if (event) {
|
||||||
ret = traceprobe_parse_event_name(&event, &group, gbuf,
|
ret = traceprobe_parse_event_name(&event, &group, gbuf,
|
||||||
event - argv[0]);
|
event - argv[0]);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto parse_error;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!event) {
|
if (!event) {
|
||||||
|
|
@ -1160,49 +1154,44 @@ static int __trace_fprobe_create(int argc, const char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_return)
|
if (is_return)
|
||||||
ctx.flags |= TPARG_FL_RETURN;
|
ctx->flags |= TPARG_FL_RETURN;
|
||||||
else
|
else
|
||||||
ctx.flags |= TPARG_FL_FENTRY;
|
ctx->flags |= TPARG_FL_FENTRY;
|
||||||
|
|
||||||
if (is_tracepoint) {
|
if (is_tracepoint) {
|
||||||
ctx.flags |= TPARG_FL_TPOINT;
|
ctx->flags |= TPARG_FL_TPOINT;
|
||||||
tpoint = find_tracepoint(symbol, &tp_mod);
|
tpoint = find_tracepoint(symbol, &tp_mod);
|
||||||
if (tpoint) {
|
if (tpoint) {
|
||||||
ctx.funcname = kallsyms_lookup(
|
ctx->funcname = kallsyms_lookup(
|
||||||
(unsigned long)tpoint->probestub,
|
(unsigned long)tpoint->probestub,
|
||||||
NULL, NULL, NULL, sbuf);
|
NULL, NULL, NULL, sbuf);
|
||||||
} else if (IS_ENABLED(CONFIG_MODULES)) {
|
} else if (IS_ENABLED(CONFIG_MODULES)) {
|
||||||
/* This *may* be loaded afterwards */
|
/* This *may* be loaded afterwards */
|
||||||
tpoint = TRACEPOINT_STUB;
|
tpoint = TRACEPOINT_STUB;
|
||||||
ctx.funcname = symbol;
|
ctx->funcname = symbol;
|
||||||
} else {
|
} else {
|
||||||
trace_probe_log_set_index(1);
|
trace_probe_log_set_index(1);
|
||||||
trace_probe_log_err(0, NO_TRACEPOINT);
|
trace_probe_log_err(0, NO_TRACEPOINT);
|
||||||
goto parse_error;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
ctx.funcname = symbol;
|
ctx->funcname = symbol;
|
||||||
|
|
||||||
argc -= 2; argv += 2;
|
argc -= 2; argv += 2;
|
||||||
new_argv = traceprobe_expand_meta_args(argc, argv, &new_argc,
|
new_argv = traceprobe_expand_meta_args(argc, argv, &new_argc,
|
||||||
abuf, MAX_BTF_ARGS_LEN, &ctx);
|
abuf, MAX_BTF_ARGS_LEN, ctx);
|
||||||
if (IS_ERR(new_argv)) {
|
if (IS_ERR(new_argv))
|
||||||
ret = PTR_ERR(new_argv);
|
return PTR_ERR(new_argv);
|
||||||
new_argv = NULL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (new_argv) {
|
if (new_argv) {
|
||||||
argc = new_argc;
|
argc = new_argc;
|
||||||
argv = new_argv;
|
argv = new_argv;
|
||||||
}
|
}
|
||||||
if (argc > MAX_TRACE_ARGS) {
|
if (argc > MAX_TRACE_ARGS)
|
||||||
ret = -E2BIG;
|
return -E2BIG;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = traceprobe_expand_dentry_args(argc, argv, &dbuf);
|
ret = traceprobe_expand_dentry_args(argc, argv, &dbuf);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
return ret;
|
||||||
|
|
||||||
/* setup a probe */
|
/* setup a probe */
|
||||||
tf = alloc_trace_fprobe(group, event, symbol, tpoint, tp_mod,
|
tf = alloc_trace_fprobe(group, event, symbol, tpoint, tp_mod,
|
||||||
|
|
@ -1211,16 +1200,16 @@ static int __trace_fprobe_create(int argc, const char *argv[])
|
||||||
ret = PTR_ERR(tf);
|
ret = PTR_ERR(tf);
|
||||||
/* This must return -ENOMEM, else there is a bug */
|
/* This must return -ENOMEM, else there is a bug */
|
||||||
WARN_ON_ONCE(ret != -ENOMEM);
|
WARN_ON_ONCE(ret != -ENOMEM);
|
||||||
goto out; /* We know tf is not allocated */
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse arguments */
|
/* parse arguments */
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
trace_probe_log_set_index(i + 2);
|
trace_probe_log_set_index(i + 2);
|
||||||
ctx.offset = 0;
|
ctx->offset = 0;
|
||||||
ret = traceprobe_parse_probe_arg(&tf->tp, i, argv[i], &ctx);
|
ret = traceprobe_parse_probe_arg(&tf->tp, i, argv[i], ctx);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error; /* This can be -ENOMEM */
|
return ret; /* This can be -ENOMEM */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_return && tf->tp.entry_arg) {
|
if (is_return && tf->tp.entry_arg) {
|
||||||
|
|
@ -1231,7 +1220,7 @@ static int __trace_fprobe_create(int argc, const char *argv[])
|
||||||
ret = traceprobe_set_print_fmt(&tf->tp,
|
ret = traceprobe_set_print_fmt(&tf->tp,
|
||||||
is_return ? PROBE_PRINT_RETURN : PROBE_PRINT_NORMAL);
|
is_return ? PROBE_PRINT_RETURN : PROBE_PRINT_NORMAL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error;
|
return ret;
|
||||||
|
|
||||||
ret = register_trace_fprobe(tf);
|
ret = register_trace_fprobe(tf);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
@ -1242,29 +1231,32 @@ static int __trace_fprobe_create(int argc, const char *argv[])
|
||||||
trace_probe_log_err(0, BAD_PROBE_ADDR);
|
trace_probe_log_err(0, BAD_PROBE_ADDR);
|
||||||
else if (ret != -ENOMEM && ret != -EEXIST)
|
else if (ret != -ENOMEM && ret != -EEXIST)
|
||||||
trace_probe_log_err(0, FAIL_REG_PROBE);
|
trace_probe_log_err(0, FAIL_REG_PROBE);
|
||||||
goto error;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
/* 'tf' is successfully registered. To avoid freeing, assign NULL. */
|
||||||
if (tp_mod)
|
tf = NULL;
|
||||||
module_put(tp_mod);
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int trace_fprobe_create_cb(int argc, const char *argv[])
|
||||||
|
{
|
||||||
|
struct traceprobe_parse_context ctx = {
|
||||||
|
.flags = TPARG_FL_KERNEL | TPARG_FL_FPROBE,
|
||||||
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
trace_probe_log_init("trace_fprobe", argc, argv);
|
||||||
|
ret = trace_fprobe_create_internal(argc, argv, &ctx);
|
||||||
traceprobe_finish_parse(&ctx);
|
traceprobe_finish_parse(&ctx);
|
||||||
trace_probe_log_clear();
|
trace_probe_log_clear();
|
||||||
kfree(new_argv);
|
|
||||||
kfree(symbol);
|
|
||||||
kfree(dbuf);
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
parse_error:
|
|
||||||
ret = -EINVAL;
|
|
||||||
error:
|
|
||||||
free_trace_fprobe(tf);
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int trace_fprobe_create(const char *raw_command)
|
static int trace_fprobe_create(const char *raw_command)
|
||||||
{
|
{
|
||||||
return trace_probe_create(raw_command, __trace_fprobe_create);
|
return trace_probe_create(raw_command, trace_fprobe_create_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int trace_fprobe_release(struct dyn_event *ev)
|
static int trace_fprobe_release(struct dyn_event *ev)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue