On Tue, Apr 13, 2021 at 05:14:57PM +0530, Sumit Garg wrote: > Switch to use a linked list instead of dynamic array which makes > allocation of kdb macro and traversing the kdb macro commands list > simpler. > > Also, rename defcmd_set struct to kdb_macro_t struct as it sounds more > appropriate given its purpose. Along with this directly embed kdbtab_t > struct instead of custom command fields in kdb_macro_t struct as its now > possible to register pre-allocated kdb commands via kdb_register_table().
There is a bit too much going on in this patch and that makes it really hard to review. More specifically it looks like it contains two unrelated changes. The first change embeddeds a kdbtab_t structure in defcmd_set and renames it for clarity. This removes the last non-trivial user of kdb_register_flags() and would ideally be included as part of a patch series that removes kdb_register_flags() from the code base entirely. For example currently there is one user of kdb_register() and this should be handled by changing the prototype of kdb_register() to take a single kdbtab_t* instead (e.g. an inline for kdb_register_table(..., 1). That then leaves two users of kdb_register_flags() which can both be switched over the new definition of kdb_register(). The second change modifies the internals how macro definitions work. I suspect it a good change but it is not easily reviewable when it is tangled up with the (partial) removal of kdb_register_flags(). Daniel. > > Suggested-by: Daniel Thompson <daniel.thomp...@linaro.org> > Signed-off-by: Sumit Garg <sumit.g...@linaro.org> > --- > > Changes in v2: > - Define new structs: kdb_macro_t and kdb_macro_cmd_t instead of > modifying existing kdb command struct and struct kdb_subcmd. > - Reword commit message. > > kernel/debug/kdb/kdb_main.c | 158 +++++++++++++++++++----------------- > 1 file changed, 83 insertions(+), 75 deletions(-) > > diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c > index 9d69169582c6..2f2c0e3b39a9 100644 > --- a/kernel/debug/kdb/kdb_main.c > +++ b/kernel/debug/kdb/kdb_main.c > @@ -678,16 +678,17 @@ static void kdb_cmderror(int diag) > * Returns: > * zero for success, a kdb diagnostic if error > */ > -struct defcmd_set { > - int count; > - bool usable; > - char *name; > - char *usage; > - char *help; > - char **command; > +struct kdb_macro_t { > + kdbtab_t cmd; /* Macro command name */ > + struct list_head commands; /* Associated command list */ > }; > -static struct defcmd_set *defcmd_set; > -static int defcmd_set_count; > + > +struct kdb_macro_cmd_t { > + char *cmd; /* Command name */ > + struct list_head list_node; /* Command list node */ > +}; > + > +static struct kdb_macro_t *kdb_macro; > static bool defcmd_in_progress; > > /* Forward references */ > @@ -695,53 +696,56 @@ static int kdb_exec_defcmd(int argc, const char **argv); > > static int kdb_defcmd2(const char *cmdstr, const char *argv0) > { > - struct defcmd_set *s = defcmd_set + defcmd_set_count - 1; > - char **save_command = s->command; > + struct kdb_macro_cmd_t *kmc; > + > + if (!kdb_macro) > + return KDB_NOTIMP; > + > if (strcmp(argv0, "endefcmd") == 0) { > defcmd_in_progress = false; > - if (!s->count) > - s->usable = false; > - if (s->usable) > - /* macros are always safe because when executed each > - * internal command re-enters kdb_parse() and is > - * safety checked individually. > - */ > - kdb_register_flags(s->name, kdb_exec_defcmd, s->usage, > - s->help, 0, > - KDB_ENABLE_ALWAYS_SAFE); > + if (!list_empty(&kdb_macro->commands)) > + kdb_register_table(&kdb_macro->cmd, 1); > return 0; > } > - if (!s->usable) > - return KDB_NOTIMP; > - s->command = kcalloc(s->count + 1, sizeof(*(s->command)), GFP_KDB); > - if (!s->command) { > - kdb_printf("Could not allocate new kdb_defcmd table for %s\n", > + > + kmc = kmalloc(sizeof(*kmc), GFP_KDB); > + if (!kmc) { > + kdb_printf("Could not allocate new kdb macro command: %s\n", > cmdstr); > - s->usable = false; > return KDB_NOTIMP; > } > - memcpy(s->command, save_command, s->count * sizeof(*(s->command))); > - s->command[s->count++] = kdb_strdup(cmdstr, GFP_KDB); > - kfree(save_command); > + > + kmc->cmd = kdb_strdup(cmdstr, GFP_KDB); > + list_add_tail(&kmc->list_node, &kdb_macro->commands); > + > return 0; > } > > static int kdb_defcmd(int argc, const char **argv) > { > - struct defcmd_set *save_defcmd_set = defcmd_set, *s; > + kdbtab_t *mp; > + > if (defcmd_in_progress) { > kdb_printf("kdb: nested defcmd detected, assuming missing " > "endefcmd\n"); > kdb_defcmd2("endefcmd", "endefcmd"); > } > if (argc == 0) { > - int i; > - for (s = defcmd_set; s < defcmd_set + defcmd_set_count; ++s) { > - kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->name, > - s->usage, s->help); > - for (i = 0; i < s->count; ++i) > - kdb_printf("%s", s->command[i]); > - kdb_printf("endefcmd\n"); > + kdbtab_t *kp; > + struct kdb_macro_t *kmp; > + struct kdb_macro_cmd_t *kmc; > + > + list_for_each_entry(kp, &kdb_cmds_head, list_node) { > + if (kp->cmd_func == kdb_exec_defcmd) { > + kdb_printf("defcmd %s \"%s\" \"%s\"\n", > + kp->cmd_name, kp->cmd_usage, > + kp->cmd_help); > + kmp = container_of(kp, struct kdb_macro_t, cmd); > + list_for_each_entry(kmc, &kmp->commands, > + list_node) > + kdb_printf("%s", kmc->cmd); > + kdb_printf("endefcmd\n"); > + } > } > return 0; > } > @@ -751,45 +755,43 @@ static int kdb_defcmd(int argc, const char **argv) > kdb_printf("Command only available during kdb_init()\n"); > return KDB_NOTIMP; > } > - defcmd_set = kmalloc_array(defcmd_set_count + 1, sizeof(*defcmd_set), > - GFP_KDB); > - if (!defcmd_set) > + kdb_macro = kzalloc(sizeof(*kdb_macro), GFP_KDB); > + if (!kdb_macro) > goto fail_defcmd; > - memcpy(defcmd_set, save_defcmd_set, > - defcmd_set_count * sizeof(*defcmd_set)); > - s = defcmd_set + defcmd_set_count; > - memset(s, 0, sizeof(*s)); > - s->usable = true; > - s->name = kdb_strdup(argv[1], GFP_KDB); > - if (!s->name) > + mp = &kdb_macro->cmd; > + > + mp->cmd_func = kdb_exec_defcmd; > + mp->cmd_minlen = 0; > + mp->cmd_flags = KDB_ENABLE_ALWAYS_SAFE; > + mp->cmd_name = kdb_strdup(argv[1], GFP_KDB); > + if (!mp->cmd_name) > goto fail_name; > - s->usage = kdb_strdup(argv[2], GFP_KDB); > - if (!s->usage) > + mp->cmd_usage = kdb_strdup(argv[2], GFP_KDB); > + if (!mp->cmd_usage) > goto fail_usage; > - s->help = kdb_strdup(argv[3], GFP_KDB); > - if (!s->help) > + mp->cmd_help = kdb_strdup(argv[3], GFP_KDB); > + if (!mp->cmd_help) > goto fail_help; > - if (s->usage[0] == '"') { > - strcpy(s->usage, argv[2]+1); > - s->usage[strlen(s->usage)-1] = '\0'; > + if (mp->cmd_usage[0] == '"') { > + strcpy(mp->cmd_usage, argv[2]+1); > + mp->cmd_usage[strlen(mp->cmd_usage)-1] = '\0'; > } > - if (s->help[0] == '"') { > - strcpy(s->help, argv[3]+1); > - s->help[strlen(s->help)-1] = '\0'; > + if (mp->cmd_help[0] == '"') { > + strcpy(mp->cmd_help, argv[3]+1); > + mp->cmd_help[strlen(mp->cmd_help)-1] = '\0'; > } > - ++defcmd_set_count; > + > + INIT_LIST_HEAD(&kdb_macro->commands); > defcmd_in_progress = true; > - kfree(save_defcmd_set); > return 0; > fail_help: > - kfree(s->usage); > + kfree(mp->cmd_usage); > fail_usage: > - kfree(s->name); > + kfree(mp->cmd_name); > fail_name: > - kfree(defcmd_set); > + kfree(kdb_macro); > fail_defcmd: > - kdb_printf("Could not allocate new defcmd_set entry for %s\n", argv[1]); > - defcmd_set = save_defcmd_set; > + kdb_printf("Could not allocate new kdb_macro entry for %s\n", argv[1]); > return KDB_NOTIMP; > } > > @@ -804,25 +806,31 @@ static int kdb_defcmd(int argc, const char **argv) > */ > static int kdb_exec_defcmd(int argc, const char **argv) > { > - int i, ret; > - struct defcmd_set *s; > + int ret; > + kdbtab_t *kp; > + struct kdb_macro_t *kmp; > + struct kdb_macro_cmd_t *kmc; > + > if (argc != 0) > return KDB_ARGCOUNT; > - for (s = defcmd_set, i = 0; i < defcmd_set_count; ++i, ++s) { > - if (strcmp(s->name, argv[0]) == 0) > + > + list_for_each_entry(kp, &kdb_cmds_head, list_node) { > + if (strcmp(kp->cmd_name, argv[0]) == 0) > break; > } > - if (i == defcmd_set_count) { > + if (list_entry_is_head(kp, &kdb_cmds_head, list_node)) { > kdb_printf("kdb_exec_defcmd: could not find commands for %s\n", > argv[0]); > return KDB_NOTIMP; > } > - for (i = 0; i < s->count; ++i) { > - /* Recursive use of kdb_parse, do not use argv after > - * this point */ > + kmp = container_of(kp, struct kdb_macro_t, cmd); > + list_for_each_entry(kmc, &kmp->commands, list_node) { > + /* > + * Recursive use of kdb_parse, do not use argv after this point. > + */ > argv = NULL; > - kdb_printf("[%s]kdb> %s\n", s->name, s->command[i]); > - ret = kdb_parse(s->command[i]); > + kdb_printf("[%s]kdb> %s\n", kmp->cmd.cmd_name, kmc->cmd); > + ret = kdb_parse(kmc->cmd); > if (ret) > return ret; > } > -- > 2.25.1 _______________________________________________ Kgdb-bugreport mailing list Kgdb-bugreport@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport