]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
tracing: Integrate similar probe argument parsers
authorMasami Hiramatsu <mhiramat@kernel.org>
Mon, 5 Nov 2018 09:01:40 +0000 (18:01 +0900)
committerSteven Rostedt (VMware) <rostedt@goodmis.org>
Sun, 9 Dec 2018 01:54:09 +0000 (20:54 -0500)
Integrate similar argument parsers for kprobes and uprobes events
into traceprobe_parse_probe_arg().

Link: http://lkml.kernel.org/r/154140850016.17322.9836787731210512176.stgit@devbox
Reviewed-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
kernel/trace/trace_kprobe.c
kernel/trace/trace_probe.c
kernel/trace/trace_probe.h
kernel/trace/trace_uprobe.c

index fec67188c4d28542f0b88f9ca9aca5fee5668e8d..d313bcc259dc9b11aeb0e1981bb5f8b5b8bd50bd 100644 (file)
@@ -548,7 +548,6 @@ static int create_trace_kprobe(int argc, char **argv)
        bool is_return = false, is_delete = false;
        char *symbol = NULL, *event = NULL, *group = NULL;
        int maxactive = 0;
-       char *arg;
        long offset = 0;
        void *addr = NULL;
        char buf[MAX_EVENT_NAME_LEN];
@@ -676,53 +675,10 @@ static int create_trace_kprobe(int argc, char **argv)
        }
 
        /* parse arguments */
-       ret = 0;
        for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
-               struct probe_arg *parg = &tk->tp.args[i];
-
-               /* Increment count for freeing args in error case */
-               tk->tp.nr_args++;
-
-               /* Parse argument name */
-               arg = strchr(argv[i], '=');
-               if (arg) {
-                       *arg++ = '\0';
-                       parg->name = kstrdup(argv[i], GFP_KERNEL);
-               } else {
-                       arg = argv[i];
-                       /* If argument name is omitted, set "argN" */
-                       snprintf(buf, MAX_EVENT_NAME_LEN, "arg%d", i + 1);
-                       parg->name = kstrdup(buf, GFP_KERNEL);
-               }
-
-               if (!parg->name) {
-                       pr_info("Failed to allocate argument[%d] name.\n", i);
-                       ret = -ENOMEM;
-                       goto error;
-               }
-
-               if (!is_good_name(parg->name)) {
-                       pr_info("Invalid argument[%d] name: %s\n",
-                               i, parg->name);
-                       ret = -EINVAL;
-                       goto error;
-               }
-
-               if (traceprobe_conflict_field_name(parg->name,
-                                                       tk->tp.args, i)) {
-                       pr_info("Argument[%d] name '%s' conflicts with "
-                               "another field.\n", i, argv[i]);
-                       ret = -EINVAL;
-                       goto error;
-               }
-
-               /* Parse fetch argument */
-               ret = traceprobe_parse_probe_arg(arg, &tk->tp.size, parg,
-                                                flags);
-               if (ret) {
-                       pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
+               ret = traceprobe_parse_probe_arg(&tk->tp, i, argv[i], flags);
+               if (ret)
                        goto error;
-               }
        }
 
        ret = register_trace_kprobe(tk);
index bd30e9398d2a8b2afbc49839c969efd277ae2728..449150c6a87fde2d1a3e5e840ccaee190824d1ae 100644 (file)
@@ -348,7 +348,7 @@ static int __parse_bitfield_probe_arg(const char *bf,
 }
 
 /* String length checking wrapper */
-int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
+static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
                struct probe_arg *parg, unsigned int flags)
 {
        struct fetch_insn *code, *scode, *tmp = NULL;
@@ -491,8 +491,8 @@ fail:
 }
 
 /* Return 1 if name is reserved or already used by another argument */
-int traceprobe_conflict_field_name(const char *name,
-                              struct probe_arg *args, int narg)
+static int traceprobe_conflict_field_name(const char *name,
+                                         struct probe_arg *args, int narg)
 {
        int i;
 
@@ -507,6 +507,47 @@ int traceprobe_conflict_field_name(const char *name,
        return 0;
 }
 
+int traceprobe_parse_probe_arg(struct trace_probe *tp, int i, char *arg,
+                               unsigned int flags)
+{
+       struct probe_arg *parg = &tp->args[i];
+       char *body;
+       int ret;
+
+       /* Increment count for freeing args in error case */
+       tp->nr_args++;
+
+       body = strchr(arg, '=');
+       if (body) {
+               parg->name = kmemdup_nul(arg, body - arg, GFP_KERNEL);
+               body++;
+       } else {
+               /* If argument name is omitted, set "argN" */
+               parg->name = kasprintf(GFP_KERNEL, "arg%d", i + 1);
+               body = arg;
+       }
+       if (!parg->name)
+               return -ENOMEM;
+
+       if (!is_good_name(parg->name)) {
+               pr_info("Invalid argument[%d] name: %s\n",
+                       i, parg->name);
+               return -EINVAL;
+       }
+
+       if (traceprobe_conflict_field_name(parg->name, tp->args, i)) {
+               pr_info("Argument[%d]: '%s' conflicts with another field.\n",
+                       i, parg->name);
+               return -EINVAL;
+       }
+
+       /* Parse fetch argument */
+       ret = traceprobe_parse_probe_arg_body(body, &tp->size, parg, flags);
+       if (ret)
+               pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
+       return ret;
+}
+
 void traceprobe_free_probe_arg(struct probe_arg *arg)
 {
        struct fetch_insn *code = arg->code;
index 974afc1a3e73eaed3be4d7f925e0fd9ae6fc5c25..feeec261b3563faa7b7468e671a7729871503e8d 100644 (file)
@@ -272,11 +272,8 @@ find_event_file_link(struct trace_probe *tp, struct trace_event_file *file)
 #define TPARG_FL_FENTRY BIT(2)
 #define TPARG_FL_MASK  GENMASK(2, 0)
 
-extern int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
-                  struct probe_arg *parg, unsigned int flags);
-
-extern int traceprobe_conflict_field_name(const char *name,
-                              struct probe_arg *args, int narg);
+extern int traceprobe_parse_probe_arg(struct trace_probe *tp, int i,
+                               char *arg, unsigned int flags);
 
 extern int traceprobe_update_arg(struct probe_arg *arg);
 extern void traceprobe_free_probe_arg(struct probe_arg *arg);
index b708e4ff7ea7817e73d70c3602a0ab76877da4e5..6eaaa21506857fd5f5f9dd1ed57c7b5a2079bde1 100644 (file)
@@ -517,51 +517,11 @@ static int create_trace_uprobe(int argc, char **argv)
        }
 
        /* parse arguments */
-       ret = 0;
        for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
-               struct probe_arg *parg = &tu->tp.args[i];
-
-               /* Increment count for freeing args in error case */
-               tu->tp.nr_args++;
-
-               /* Parse argument name */
-               arg = strchr(argv[i], '=');
-               if (arg) {
-                       *arg++ = '\0';
-                       parg->name = kstrdup(argv[i], GFP_KERNEL);
-               } else {
-                       arg = argv[i];
-                       /* If argument name is omitted, set "argN" */
-                       snprintf(buf, MAX_EVENT_NAME_LEN, "arg%d", i + 1);
-                       parg->name = kstrdup(buf, GFP_KERNEL);
-               }
-
-               if (!parg->name) {
-                       pr_info("Failed to allocate argument[%d] name.\n", i);
-                       ret = -ENOMEM;
-                       goto error;
-               }
-
-               if (!is_good_name(parg->name)) {
-                       pr_info("Invalid argument[%d] name: %s\n", i, parg->name);
-                       ret = -EINVAL;
-                       goto error;
-               }
-
-               if (traceprobe_conflict_field_name(parg->name, tu->tp.args, i)) {
-                       pr_info("Argument[%d] name '%s' conflicts with "
-                               "another field.\n", i, argv[i]);
-                       ret = -EINVAL;
-                       goto error;
-               }
-
-               /* Parse fetch argument */
-               ret = traceprobe_parse_probe_arg(arg, &tu->tp.size, parg,
+               ret = traceprobe_parse_probe_arg(&tu->tp, i, argv[i],
                                        is_return ? TPARG_FL_RETURN : 0);
-               if (ret) {
-                       pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
+               if (ret)
                        goto error;
-               }
        }
 
        ret = register_trace_uprobe(tu);