From: Masami Hiramatsu <[email protected]>

Decompose parse_probe_vars() by extracting retval, stack, current task
struct, and function argument parsing logic into dedicated static
helper functions (parse_probe_var_retval, parse_probe_var_stack,
parse_probe_var_current, and parse_probe_var_arg). This simplifies
parse_probe_vars() and improves its readability.

Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Masami Hiramatsu (Google) <[email protected]>
---
 kernel/trace/trace_probe.c |  248 +++++++++++++++++++++++++++-----------------
 1 file changed, 151 insertions(+), 97 deletions(-)

diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index 18c212122344..b762336ebf03 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -1319,67 +1319,147 @@ NOKPROBE_SYMBOL(store_trace_entry_data)
 
 #define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
 
-/* Parse $vars. @orig_arg points '$', which syncs to @ctx->offset */
-static int parse_probe_vars(char *orig_arg, const struct fetch_type *t,
-                           struct fetch_insn **pcode,
-                           struct fetch_insn *end,
-                           struct traceprobe_parse_context *ctx)
+static int parse_probe_var_retval(char *orig_arg, char *arg,
+                                 struct fetch_insn **pcode,
+                                 struct fetch_insn *end,
+                                 struct traceprobe_parse_context *ctx,
+                                 int *err)
 {
        struct fetch_insn *code = *pcode;
-       int err = TP_ERR_BAD_VAR;
-       char *arg = orig_arg + 1;
+
+       if (!(ctx->flags & TPARG_FL_RETURN)) {
+               *err = TP_ERR_RETVAL_ON_PROBE;
+               return -EINVAL;
+       }
+       if (!(ctx->flags & TPARG_FL_KERNEL) ||
+           !IS_ENABLED(CONFIG_PROBE_EVENTS_BTF_ARGS)) {
+               code->op = FETCH_OP_RETVAL;
+               return 0;
+       }
+       return parse_btf_arg(orig_arg, pcode, end, ctx);
+}
+
+static int parse_probe_var_stack(char *arg, int len, struct fetch_insn *code,
+                                struct traceprobe_parse_context *ctx,
+                                int *err)
+{
        unsigned long param;
-       int ret = 0;
-       int len;
+       int ret;
 
-       if (ctx->flags & TPARG_FL_TEVENT) {
-               if (parse_trace_event(arg, code, ctx) < 0) {
-                       /* 'comm' should be checked after field parsing. */
-                       if (strcmp(arg, "comm") == 0 || strcmp(arg, "COMM") == 
0) {
-                               code->op = FETCH_OP_COMM;
-                               return 0;
-                       }
-                       goto inval;
-               }
+       if (arg[len] == '\0') {
+               code->op = FETCH_OP_STACKP;
                return 0;
        }
 
-       if (str_has_prefix(arg, "retval")) {
-               if (!(ctx->flags & TPARG_FL_RETURN)) {
-                       err = TP_ERR_RETVAL_ON_PROBE;
-                       goto inval;
-               }
-               if (!(ctx->flags & TPARG_FL_KERNEL) ||
-                   !IS_ENABLED(CONFIG_PROBE_EVENTS_BTF_ARGS)) {
-                       code->op = FETCH_OP_RETVAL;
-                       return 0;
+       if (isdigit(arg[len])) {
+               ret = kstrtoul(arg + len, 10, &param);
+               if (ret)
+                       return ret;
+
+               if ((ctx->flags & TPARG_FL_KERNEL) &&
+                   param > PARAM_MAX_STACK) {
+                       *err = TP_ERR_BAD_STACK_NUM;
+                       return -EINVAL;
                }
+               code->op = FETCH_OP_STACK;
+               code->param = (unsigned int)param;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int parse_probe_var_current(char *orig_arg, char *arg,
+                                  struct fetch_insn **pcode,
+                                  struct fetch_insn *end,
+                                  struct traceprobe_parse_context *ctx,
+                                  int *err)
+{
+       struct fetch_insn *code = *pcode;
+
+       /* $current is only supported by kernel probe. */
+       if (!(ctx->flags & TPARG_FL_KERNEL)) {
+               *err = TP_ERR_BAD_VAR;
+               return -EINVAL;
+       }
+       arg += strlen("current");
+       if (*arg == '-' && IS_ENABLED(CONFIG_PROBE_EVENTS_BTF_ARGS))
                return parse_btf_arg(orig_arg, pcode, end, ctx);
+
+       if (*arg != '\0')
+               return -EINVAL;
+
+       code->op = FETCH_OP_CURRENT;
+       return 0;
+}
+
+#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
+static int parse_probe_var_arg(char *arg, int len, struct fetch_insn *code,
+                              struct traceprobe_parse_context *ctx,
+                              int *err)
+{
+       unsigned long param;
+       int ret;
+
+       ret = kstrtoul(arg + len, 10, &param);
+       if (ret)
+               return ret;
+
+       if (!param || param > PARAM_MAX_STACK) {
+               *err = TP_ERR_BAD_ARG_NUM;
+               return -EINVAL;
        }
+       param--; /* argN starts from 1, but internal arg[N] starts from 0 */
 
-       len = str_has_prefix(arg, "stack");
-       if (len) {
+       if (tparg_is_function_entry(ctx->flags)) {
+               code->op = FETCH_OP_ARG;
+               code->param = (unsigned int)param;
+               /*
+                * The tracepoint probe will probe a stub function, and the
+                * first parameter of the stub is a dummy and should be ignored.
+                */
+               if (ctx->flags & TPARG_FL_TPOINT)
+                       code->param++;
+       } else if (tparg_is_function_return(ctx->flags)) {
+               /* function entry argument access from return probe */
+               ret = __store_entry_arg(ctx->tp, param);
+               if (ret < 0)    /* This error should be an internal error */
+                       return ret;
 
-               if (arg[len] == '\0') {
-                       code->op = FETCH_OP_STACKP;
-                       return 0;
-               }
+               code->op = FETCH_OP_EDATA;
+               code->offset = ret;
+       } else {
+               *err = TP_ERR_NOFENTRY_ARGS;
+               return -EINVAL;
+       }
+       return 0;
+}
+#else
+static int parse_probe_var_arg(char *arg, int len, struct fetch_insn *code,
+                              struct traceprobe_parse_context *ctx,
+                              int *err)
+{
+       *err = TP_ERR_BAD_VAR;
+       return -EINVAL;
+}
+#endif
 
-               if (isdigit(arg[len])) {
-                       ret = kstrtoul(arg + len, 10, &param);
-                       if (ret)
-                               goto inval;
+/* Parse $vars. @orig_arg points '$', which syncs to @ctx->offset */
+static int parse_probe_vars(char *orig_arg, const struct fetch_type *t,
+                           struct fetch_insn **pcode,
+                           struct fetch_insn *end,
+                           struct traceprobe_parse_context *ctx)
+{
+       struct fetch_insn *code = *pcode;
+       char *arg = orig_arg + 1;
+       int err = TP_ERR_BAD_VAR;
+       int ret = -EINVAL;
+       int len;
 
-                       if ((ctx->flags & TPARG_FL_KERNEL) &&
-                           param > PARAM_MAX_STACK) {
-                               err = TP_ERR_BAD_STACK_NUM;
-                               goto inval;
-                       }
-                       code->op = FETCH_OP_STACK;
-                       code->param = (unsigned int)param;
+       if (ctx->flags & TPARG_FL_TEVENT) {
+               ret = parse_trace_event(arg, code, ctx);
+               if (!ret)
                        return 0;
-               }
-               goto inval;
        }
 
        if (strcmp(arg, "comm") == 0 || strcmp(arg, "COMM") == 0) {
@@ -1387,65 +1467,39 @@ static int parse_probe_vars(char *orig_arg, const 
struct fetch_type *t,
                return 0;
        }
 
-       /* $current returns the address of the current task_struct. */
-       if (str_has_prefix(arg, "current")) {
-               /* $current is only supported by kernel probe. */
-               if (!(ctx->flags & TPARG_FL_KERNEL)) {
-                       err = TP_ERR_BAD_VAR;
-                       goto inval;
-               }
-               arg += strlen("current");
-               if (*arg == '-' && IS_ENABLED(CONFIG_PROBE_EVENTS_BTF_ARGS))
-                       return parse_btf_arg(orig_arg, pcode, end, ctx);
-
-               if (*arg != '\0')
-                       goto inval;
+       /* eprobe only support event fields or '$comm'. */
+       if (ctx->flags & TPARG_FL_TEVENT)
+               goto end;
 
-               code->op = FETCH_OP_CURRENT;
-               return 0;
+       if (str_has_prefix(arg, "retval")) {
+               ret = parse_probe_var_retval(orig_arg, arg, pcode, end, ctx, 
&err);
+               goto end;
        }
 
-#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
-       len = str_has_prefix(arg, "arg");
+       len = str_has_prefix(arg, "stack");
        if (len) {
-               ret = kstrtoul(arg + len, 10, &param);
-               if (ret)
-                       goto inval;
-
-               if (!param || param > PARAM_MAX_STACK) {
-                       err = TP_ERR_BAD_ARG_NUM;
-                       goto inval;
-               }
-               param--; /* argN starts from 1, but internal arg[N] starts from 
0 */
+               ret = parse_probe_var_stack(arg, len, code, ctx, &err);
+               goto end;
+       }
 
-               if (tparg_is_function_entry(ctx->flags)) {
-                       code->op = FETCH_OP_ARG;
-                       code->param = (unsigned int)param;
-                       /*
-                        * The tracepoint probe will probe a stub function, and 
the
-                        * first parameter of the stub is a dummy and should be 
ignored.
-                        */
-                       if (ctx->flags & TPARG_FL_TPOINT)
-                               code->param++;
-               } else if (tparg_is_function_return(ctx->flags)) {
-                       /* function entry argument access from return probe */
-                       ret = __store_entry_arg(ctx->tp, param);
-                       if (ret < 0)    /* This error should be an internal 
error */
-                               return ret;
+       /* $current returns the address of the current task_struct. */
+       if (str_has_prefix(arg, "current")) {
+               ret = parse_probe_var_current(orig_arg, arg, pcode, end, ctx, 
&err);
+               goto end;
+       }
 
-                       code->op = FETCH_OP_EDATA;
-                       code->offset = ret;
-               } else {
-                       err = TP_ERR_NOFENTRY_ARGS;
-                       goto inval;
-               }
-               return 0;
+       len = str_has_prefix(arg, "arg");
+       if (len) {
+               ret = parse_probe_var_arg(arg, len, code, ctx, &err);
+               goto end;
        }
-#endif
 
-inval:
-       __trace_probe_log_err(ctx->offset, err);
-       return -EINVAL;
+end:
+       if (ret < 0) {
+               __trace_probe_log_err(ctx->offset, err);
+               return ret;
+       }
+       return 0;
 }
 
 static int str_to_immediate(char *str, unsigned long *imm)


Reply via email to