Re: [RFC PATCH 07/15] Support percpu symbols for "sym" options

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, May 11, 2023 at 12:35 PM HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab@xxxxxxx> wrote:
Support percpu symbols for "sym" options and etc.

crash> mod -s kvm_intel
     MODULE       NAME                        BASE           SIZE  OBJECT FILE
ffffffffc0b1b480  kvm_intel             ffffffffc0d0c000   372736  /home/kernel/linux-next-next-20230310/arch/x86/kvm/kvm-intel.ko
crash> sym -m kvm_intel | head
35020 MODULE PERCPU START: kvm_intel
35020 (d) loaded_vmcss_on_cpu
35030 (d) vmxarea
35038 (D) current_vmcs
35040 (d) wakeup_vcpus_on_cpu_lock
35050 (d) wakeup_vcpus_on_cpu
35060 MODULE PERCPU END: kvm_intel
ffffffffc0aae000 MODULE RO_AFTER_INIT START: kvm_intel
ffffffffc0ab1720 (D) vmx_capability
ffffffffc0ab1740 (D) vmcs_config
crash> sym vmxarea
35030 (d) vmxarea [kvm_intel]

Signed-off-by: Kazuhito Hagio <k-hagio-ab@xxxxxxx>
---
 symbols.c | 82 ++++++++++++++++++++++++++-----------------------------
 1 file changed, 38 insertions(+), 44 deletions(-)

diff --git a/symbols.c b/symbols.c
index 8343081f51f7..40e992e9ee12 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1302,7 +1302,7 @@ symname_hash_search(struct syment *table[], char *name)
 static void
 module_symbol_dump(char *module)
 {
-       int i, j, m, start, percpu_syms;
+       int i, j, m;
         struct syment *sp, *sp_end;
        struct load_module *lm;
        const char *p1, *p2;
@@ -1319,6 +1319,19 @@ module_symbol_dump(char *module)
                if (received_SIGINT() || output_closed())
                        return;

+               /* The percpu area isn't included in any module memory area. */

Could you please point out where the percpu area is? That can help us to understand easily. For example:

The percpu area is included in the .data..percpu section, and not in any module memory areas.
# objdump -h vmlinux|grep percpu
 19 .data..percpu 00035000  0000000000000000  0000000003240000  02600000  2**12

+               if (MODULE_PERCPU_SYMS_LOADED(lm)) {
+                       p1 = "MODULE PERCPU START";
+                       p2 = lm->mod_name;
+                       fprintf(fp, "%lx %s: %s\n", lm->mod_percpu, p1, p2);
+
+                       dump_percpu_symbols(lm);
+
+                       p1 = "MODULE PERCPU END";
+                       fprintf(fp, "%lx %s: %s\n",
+                               lm->mod_percpu + lm->mod_percpu_size, p1, p2);
+               }
+
                for (m = 0; m < lm->nr_mems; m++) {
                        j = lm->address_order[m];

@@ -1327,21 +1340,8 @@ module_symbol_dump(char *module)

                        sp = lm->symtable[j];
                        sp_end = lm->symend[j];
-                       percpu_syms = 0;

-                       for (start = FALSE; sp <= sp_end; sp++) {
-                               /* TODO
-                               if (IN_MODULE_PERCPU(sp->value, lm)) {
-                                       if (percpu_syms == DISPLAYED)
-                                               continue;
-                                       if (!start) {
-                                               percpu_syms = TBD;
-                                               continue;
-                                       }
-                                       dump_percpu_symbols(lm);
-                                       percpu_syms = DISPLAYED;
-                               }
-                               */
+                       for ( ; sp <= sp_end; sp++) {
                                if (MODULE_PSEUDO_SYMBOL(sp)) {
                                        if (MODULE_SECTION_START(sp)) {
                                                p1 = sp->name + strlen("_MODULE_SECTION_START ");
@@ -1352,30 +1352,15 @@ module_symbol_dump(char *module)
                                        } else if (STRNEQ(sp->name, module_start_tags[j])) {
                                                p1 = module_start_strs[j];
                                                p2 = sp->name + strlen(module_start_tags[j]);
-                                               start = TRUE;
                                        } else if (STRNEQ(sp->name, module_end_tags[j])) {
                                                p1 = module_end_strs[j];
                                                p2 = sp->name + strlen(module_end_tags[j]);
-                                               /* TODO
-                                               if (MODULE_PERCPU_SYMS_LOADED(lm) &&
-                                                   !percpu_syms) {
-                                                       dump_percpu_symbols(lm);
-                                                       percpu_syms = DISPLAYED;
-                                               }
-                                               */
                                        } else {
                                                p1 = "unknown tag";
                                                p2 = sp->name;
                                        }

                                        fprintf(fp, "%lx %s: %s\n", sp->value, p1, p2);
-
-                                       /* TODO
-                                       if (percpu_syms == TBD) {
-                                               dump_percpu_symbols(lm);
-                                               percpu_syms = DISPLAYED;
-                                       }
-                                       */
                                } else
                                        show_symbol(sp, 0, SHOW_RADIX());
                        }
@@ -1497,8 +1482,14 @@ dump_percpu_symbols(struct load_module *lm)
        struct syment *sp, *sp_end;

        if (MODULE_PERCPU_SYMS_LOADED(lm)) {
-               sp = lm->mod_symtable;
-               sp_end = lm->mod_symend;
+               if (MODULE_MEMORY()) {
+                       /* The lm should have mod_load_symtable. */
+                       sp = lm->mod_load_symtable;
+                       sp_end = lm->mod_load_symend;
+               } else {
+                       sp = lm->mod_symtable;
+                       sp_end = lm->mod_symend;
+               }
                for ( ; sp <= sp_end; sp++) {
                        if (IN_MODULE_PERCPU(sp->value, lm))
                                show_symbol(sp, 0, SHOW_RADIX());
@@ -2314,6 +2305,11 @@ store_module_symbols_v3(ulong total, int mods_installed)
        if (symbol_query("__insmod_", NULL, NULL))
                st->flags |= INSMOD_BUILTIN;

+       if (CRASHDEBUG(2)) {
+               for (sp = st->ext_module_symtable; sp < st->ext_module_symend; sp++)
+                       fprintf(fp, "%16lx %s\n", sp->value, sp->name);
+       }
+
        if (mcnt > total)
                error(FATAL, "store_module_symbols_v3: total: %ld mcnt: %d\n", total, mcnt);
 }
@@ -12128,6 +12124,13 @@ store_section_data(struct load_module *lm, bfd *bfd, asection *section)
        lm->mod_section_data[i].section = section;
        lm->mod_section_data[i].priority = prio;
        lm->mod_section_data[i].flags = section->flags & ~SEC_FOUND;
+       lm->mod_section_data[i].size = bfd_section_size(section);
+       lm->mod_section_data[i].offset = 0;
+       lm->mod_section_data[i].addr = 0;

The variable mod_section_data should be initialized once the memory is allocated successfully. Here it should set useful values to the member variables, unless it needs to set the zero for some of the member variables every time.

Thanks
Lianbo

+       if (strlen(name) < MAX_MOD_SEC_NAME)
+               strcpy(lm->mod_section_data[i].name, name);
+       else
+               strncpy(lm->mod_section_data[i].name, name, MAX_MOD_SEC_NAME-1);
        /*
         * The percpu section isn't included in kallsyms or module_core area.
         */
@@ -12135,14 +12138,8 @@ store_section_data(struct load_module *lm, bfd *bfd, asection *section)
            (STREQ(name,".data.percpu") || STREQ(name, ".data..percpu"))) {
                lm->mod_percpu_size = bfd_section_size(section);
                lm->mod_section_data[i].flags |= SEC_FOUND;
+               lm->mod_section_data[i].addr = lm->mod_percpu;
        }
-       lm->mod_section_data[i].size = bfd_section_size(section);
-       lm->mod_section_data[i].offset = 0;
-       lm->mod_section_data[i].addr = 0;
-       if (strlen(name) < MAX_MOD_SEC_NAME)
-               strcpy(lm->mod_section_data[i].name, name);
-       else
-               strncpy(lm->mod_section_data[i].name, name, MAX_MOD_SEC_NAME-1);
        lm->mod_sections += 1;
 }

@@ -13546,11 +13543,8 @@ append_section_symbols:
                }
                lm->symtable = lm->load_symtable;
                lm->symend = lm->load_symend;
-               for (i = MOD_TEXT; i < MOD_MEM_NUM_TYPES; i++) {
-                       if (!lm->symtable[i])
-                               continue;
-                       mod_symtable_hash_install_range(lm->symtable[i], lm->symend[i]);
-               }
+               /* percpu symbols is out of the ranges.. */
+               mod_symtable_hash_install_range(lm->mod_load_symtable, lm->mod_load_symend);
        } else {
                mod_symtable_hash_remove_range(lm->mod_symtable, lm->mod_symend);
                lm->mod_symtable = lm->mod_load_symtable;
--
2.31.1

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux