Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Sumit Garg and committed by
Daniel Thompson
9a5db530 c25abcd6

+58 -49
+58 -49
kernel/debug/kdb/kdb_main.c
··· 654 654 * zero for success, a kdb diagnostic if error 655 655 */ 656 656 struct kdb_macro { 657 - int count; 658 - bool usable; 659 - kdbtab_t cmd; 660 - char **command; 657 + kdbtab_t cmd; /* Macro command */ 658 + struct list_head statements; /* Associated statement list */ 661 659 }; 660 + 661 + struct kdb_macro_statement { 662 + char *statement; /* Statement text */ 663 + struct list_head list_node; /* Statement list node */ 664 + }; 665 + 662 666 static struct kdb_macro *kdb_macro; 663 - static int kdb_macro_count; 664 667 static bool defcmd_in_progress; 665 668 666 669 /* Forward references */ ··· 671 668 672 669 static int kdb_defcmd2(const char *cmdstr, const char *argv0) 673 670 { 674 - struct kdb_macro *s = kdb_macro + kdb_macro_count - 1; 675 - char **save_command = s->command; 671 + struct kdb_macro_statement *kms; 672 + 673 + if (!kdb_macro) 674 + return KDB_NOTIMP; 675 + 676 676 if (strcmp(argv0, "endefcmd") == 0) { 677 677 defcmd_in_progress = false; 678 - if (!s->count) 679 - s->usable = false; 680 - if (s->usable) 681 - kdb_register(&s->cmd); 678 + if (!list_empty(&kdb_macro->statements)) 679 + kdb_register(&kdb_macro->cmd); 682 680 return 0; 683 681 } 684 - if (!s->usable) 685 - return KDB_NOTIMP; 686 - s->command = kcalloc(s->count + 1, sizeof(*(s->command)), GFP_KDB); 687 - if (!s->command) { 688 - kdb_printf("Could not allocate new kdb_defcmd table for %s\n", 682 + 683 + kms = kmalloc(sizeof(*kms), GFP_KDB); 684 + if (!kms) { 685 + kdb_printf("Could not allocate new kdb macro command: %s\n", 689 686 cmdstr); 690 - s->usable = false; 691 687 return KDB_NOTIMP; 692 688 } 693 - memcpy(s->command, save_command, s->count * sizeof(*(s->command))); 694 - s->command[s->count++] = kdb_strdup(cmdstr, GFP_KDB); 695 - kfree(save_command); 689 + 690 + kms->statement = kdb_strdup(cmdstr, GFP_KDB); 691 + list_add_tail(&kms->list_node, &kdb_macro->statements); 692 + 696 693 return 0; 697 694 } 698 695 699 696 static int kdb_defcmd(int argc, const char **argv) 700 697 { 701 - struct kdb_macro *save_kdb_macro = kdb_macro, *s; 702 698 kdbtab_t *mp; 703 699 704 700 if (defcmd_in_progress) { ··· 706 704 kdb_defcmd2("endefcmd", "endefcmd"); 707 705 } 708 706 if (argc == 0) { 709 - int i; 710 - for (s = kdb_macro; s < kdb_macro + kdb_macro_count; ++s) { 711 - kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->cmd.cmd_name, 712 - s->cmd.cmd_usage, s->cmd.cmd_help); 713 - for (i = 0; i < s->count; ++i) 714 - kdb_printf("%s", s->command[i]); 715 - kdb_printf("endefcmd\n"); 707 + kdbtab_t *kp; 708 + struct kdb_macro *kmp; 709 + struct kdb_macro_statement *kms; 710 + 711 + list_for_each_entry(kp, &kdb_cmds_head, list_node) { 712 + if (kp->cmd_func == kdb_exec_defcmd) { 713 + kdb_printf("defcmd %s \"%s\" \"%s\"\n", 714 + kp->cmd_name, kp->cmd_usage, 715 + kp->cmd_help); 716 + kmp = container_of(kp, struct kdb_macro, cmd); 717 + list_for_each_entry(kms, &kmp->statements, 718 + list_node) 719 + kdb_printf("%s", kms->statement); 720 + kdb_printf("endefcmd\n"); 721 + } 716 722 } 717 723 return 0; 718 724 } ··· 730 720 kdb_printf("Command only available during kdb_init()\n"); 731 721 return KDB_NOTIMP; 732 722 } 733 - kdb_macro = kmalloc_array(kdb_macro_count + 1, sizeof(*kdb_macro), 734 - GFP_KDB); 723 + kdb_macro = kzalloc(sizeof(*kdb_macro), GFP_KDB); 735 724 if (!kdb_macro) 736 725 goto fail_defcmd; 737 - memcpy(kdb_macro, save_kdb_macro, 738 - kdb_macro_count * sizeof(*kdb_macro)); 739 - s = kdb_macro + kdb_macro_count; 740 - memset(s, 0, sizeof(*s)); 741 - s->usable = true; 742 726 743 - mp = &s->cmd; 727 + mp = &kdb_macro->cmd; 744 728 mp->cmd_func = kdb_exec_defcmd; 745 729 mp->cmd_minlen = 0; 746 730 mp->cmd_flags = KDB_ENABLE_ALWAYS_SAFE; ··· 755 751 strcpy(mp->cmd_help, argv[3]+1); 756 752 mp->cmd_help[strlen(mp->cmd_help)-1] = '\0'; 757 753 } 758 - ++kdb_macro_count; 754 + 755 + INIT_LIST_HEAD(&kdb_macro->statements); 759 756 defcmd_in_progress = true; 760 - kfree(save_kdb_macro); 761 757 return 0; 762 758 fail_help: 763 759 kfree(mp->cmd_usage); ··· 767 763 kfree(kdb_macro); 768 764 fail_defcmd: 769 765 kdb_printf("Could not allocate new kdb_macro entry for %s\n", argv[1]); 770 - kdb_macro = save_kdb_macro; 771 766 return KDB_NOTIMP; 772 767 } 773 768 ··· 781 778 */ 782 779 static int kdb_exec_defcmd(int argc, const char **argv) 783 780 { 784 - int i, ret; 785 - struct kdb_macro *s; 781 + int ret; 782 + kdbtab_t *kp; 783 + struct kdb_macro *kmp; 784 + struct kdb_macro_statement *kms; 785 + 786 786 if (argc != 0) 787 787 return KDB_ARGCOUNT; 788 - for (s = kdb_macro, i = 0; i < kdb_macro_count; ++i, ++s) { 789 - if (strcmp(s->cmd.cmd_name, argv[0]) == 0) 788 + 789 + list_for_each_entry(kp, &kdb_cmds_head, list_node) { 790 + if (strcmp(kp->cmd_name, argv[0]) == 0) 790 791 break; 791 792 } 792 - if (i == kdb_macro_count) { 793 + if (list_entry_is_head(kp, &kdb_cmds_head, list_node)) { 793 794 kdb_printf("kdb_exec_defcmd: could not find commands for %s\n", 794 795 argv[0]); 795 796 return KDB_NOTIMP; 796 797 } 797 - for (i = 0; i < s->count; ++i) { 798 - /* Recursive use of kdb_parse, do not use argv after 799 - * this point */ 798 + kmp = container_of(kp, struct kdb_macro, cmd); 799 + list_for_each_entry(kms, &kmp->statements, list_node) { 800 + /* 801 + * Recursive use of kdb_parse, do not use argv after this point. 802 + */ 800 803 argv = NULL; 801 - kdb_printf("[%s]kdb> %s\n", s->cmd.cmd_name, s->command[i]); 802 - ret = kdb_parse(s->command[i]); 804 + kdb_printf("[%s]kdb> %s\n", kmp->cmd.cmd_name, kms->statement); 805 + ret = kdb_parse(kms->statement); 803 806 if (ret) 804 807 return ret; 805 808 }