diff options
| author | Sumit Garg <sumit.garg@linaro.org> | 2021-07-12 19:16:19 +0530 | 
|---|---|---|
| committer | Daniel Thompson <daniel.thompson@linaro.org> | 2021-07-27 17:04:50 +0100 | 
| commit | 9a5db530aa7d98b10c4f5104027565c98cca49e6 (patch) | |
| tree | c49ad576491e01de4af10782ddaeb1a50d2aee92 /kernel/debug | |
| parent | c25abcd625505f53b72dc156bac32b5120826742 (diff) | |
kdb: Simplify kdb_defcmd macro logic
Switch to use a linked list instead of dynamic array which makes
allocation of kdb macro and traversing the kdb macro commands list
simpler.
Suggested-by: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Link: https://lore.kernel.org/r/20210712134620.276667-4-sumit.garg@linaro.org
Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
Diffstat (limited to 'kernel/debug')
| -rw-r--r-- | kernel/debug/kdb/kdb_main.c | 107 | 
1 files changed, 58 insertions, 49 deletions
| diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index b2880fad26d4..7c7a2ef834fc 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -654,13 +654,16 @@ static void kdb_cmderror(int diag)   *	zero for success, a kdb diagnostic if error   */  struct kdb_macro { -	int count; -	bool usable; -	kdbtab_t cmd; -	char **command; +	kdbtab_t cmd;			/* Macro command */ +	struct list_head statements;	/* Associated statement list */  }; + +struct kdb_macro_statement { +	char *statement;		/* Statement text */ +	struct list_head list_node;	/* Statement list node */ +}; +  static struct kdb_macro *kdb_macro; -static int kdb_macro_count;  static bool defcmd_in_progress;  /* Forward references */ @@ -668,34 +671,33 @@ static int kdb_exec_defcmd(int argc, const char **argv);  static int kdb_defcmd2(const char *cmdstr, const char *argv0)  { -	struct kdb_macro *s = kdb_macro + kdb_macro_count - 1; -	char **save_command = s->command; +	struct kdb_macro_statement *kms; + +	if (!kdb_macro) +		return KDB_NOTIMP; +  	if (strcmp(argv0, "endefcmd") == 0) {  		defcmd_in_progress = false; -		if (!s->count) -			s->usable = false; -		if (s->usable) -			kdb_register(&s->cmd); +		if (!list_empty(&kdb_macro->statements)) +			kdb_register(&kdb_macro->cmd);  		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", + +	kms = kmalloc(sizeof(*kms), GFP_KDB); +	if (!kms) { +		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); + +	kms->statement = kdb_strdup(cmdstr, GFP_KDB); +	list_add_tail(&kms->list_node, &kdb_macro->statements); +  	return 0;  }  static int kdb_defcmd(int argc, const char **argv)  { -	struct kdb_macro *save_kdb_macro = kdb_macro, *s;  	kdbtab_t *mp;  	if (defcmd_in_progress) { @@ -704,13 +706,21 @@ static int kdb_defcmd(int argc, const char **argv)  		kdb_defcmd2("endefcmd", "endefcmd");  	}  	if (argc == 0) { -		int i; -		for (s = kdb_macro; s < kdb_macro + kdb_macro_count; ++s) { -			kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->cmd.cmd_name, -				   s->cmd.cmd_usage, s->cmd.cmd_help); -			for (i = 0; i < s->count; ++i) -				kdb_printf("%s", s->command[i]); -			kdb_printf("endefcmd\n"); +		kdbtab_t *kp; +		struct kdb_macro *kmp; +		struct kdb_macro_statement *kms; + +		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, cmd); +				list_for_each_entry(kms, &kmp->statements, +						    list_node) +					kdb_printf("%s", kms->statement); +				kdb_printf("endefcmd\n"); +			}  		}  		return 0;  	} @@ -720,17 +730,11 @@ static int kdb_defcmd(int argc, const char **argv)  		kdb_printf("Command only available during kdb_init()\n");  		return KDB_NOTIMP;  	} -	kdb_macro = kmalloc_array(kdb_macro_count + 1, sizeof(*kdb_macro), -				  GFP_KDB); +	kdb_macro = kzalloc(sizeof(*kdb_macro), GFP_KDB);  	if (!kdb_macro)  		goto fail_defcmd; -	memcpy(kdb_macro, save_kdb_macro, -	       kdb_macro_count * sizeof(*kdb_macro)); -	s = kdb_macro + kdb_macro_count; -	memset(s, 0, sizeof(*s)); -	s->usable = true; -	mp = &s->cmd; +	mp = &kdb_macro->cmd;  	mp->cmd_func = kdb_exec_defcmd;  	mp->cmd_minlen = 0;  	mp->cmd_flags = KDB_ENABLE_ALWAYS_SAFE; @@ -751,9 +755,9 @@ static int kdb_defcmd(int argc, const char **argv)  		strcpy(mp->cmd_help, argv[3]+1);  		mp->cmd_help[strlen(mp->cmd_help)-1] = '\0';  	} -	++kdb_macro_count; + +	INIT_LIST_HEAD(&kdb_macro->statements);  	defcmd_in_progress = true; -	kfree(save_kdb_macro);  	return 0;  fail_help:  	kfree(mp->cmd_usage); @@ -763,7 +767,6 @@ fail_name:  	kfree(kdb_macro);  fail_defcmd:  	kdb_printf("Could not allocate new kdb_macro entry for %s\n", argv[1]); -	kdb_macro = save_kdb_macro;  	return KDB_NOTIMP;  } @@ -778,25 +781,31 @@ fail_defcmd:   */  static int kdb_exec_defcmd(int argc, const char **argv)  { -	int i, ret; -	struct kdb_macro *s; +	int ret; +	kdbtab_t *kp; +	struct kdb_macro *kmp; +	struct kdb_macro_statement *kms; +  	if (argc != 0)  		return KDB_ARGCOUNT; -	for (s = kdb_macro, i = 0; i < kdb_macro_count; ++i, ++s) { -		if (strcmp(s->cmd.cmd_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 == kdb_macro_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, cmd); +	list_for_each_entry(kms, &kmp->statements, list_node) { +		/* +		 * Recursive use of kdb_parse, do not use argv after this point. +		 */  		argv = NULL; -		kdb_printf("[%s]kdb> %s\n", s->cmd.cmd_name, s->command[i]); -		ret = kdb_parse(s->command[i]); +		kdb_printf("[%s]kdb> %s\n", kmp->cmd.cmd_name, kms->statement); +		ret = kdb_parse(kms->statement);  		if (ret)  			return ret;  	} | 
