From 1f36cd021322d1575ea25b6446ee79b030c81752 Mon Sep 17 00:00:00 2001 From: Toshikazu Nakayama Date: Wed, 10 Nov 2010 11:59:02 +0900 Subject: [PATCH 3/4] Handle module percpu. [v3] Discard previous expand patch. Add function staff for handling percpu module symbol in per module space according to Dave's proposal. get_mod_percpu_sym_owner() Find out percpu symbol owner module. is_percpu_symbol() Check whether symbol is percpu (kernel/module) or not. Signed-off-by: Toshikazu Nakayama --- symbols.c | 46 +++++++++++++++++++++++++++++++++++++--------- 1 files changed, 37 insertions(+), 9 deletions(-) diff --git a/symbols.c b/symbols.c index 5b59fb2..54dcfcb 100755 --- a/symbols.c +++ b/symbols.c @@ -71,7 +71,8 @@ static void Elf32_Sym_to_common(Elf32_Sym *, struct elf_common *); static void Elf64_Sym_to_common(Elf64_Sym *, struct elf_common *); static void cmd_datatype_common(ulong); static int display_per_cpu_info(struct syment *); - +static struct load_module *get_mod_percpu_sym_owner(struct syment *); +static int is_percpu_symbol(struct syment *); #define KERNEL_SECTIONS (void *)(1) #define MODULE_SECTIONS (void *)(2) @@ -4433,16 +4434,12 @@ per_cpu_symbol_search(char *symbol) return sp; new = symbol + strlen("per_cpu__"); if ((sp = symbol_search(new))) { - if ((sp->type == 'V') || - ((sp->value >= st->__per_cpu_start) && - (sp->value < st->__per_cpu_end))) + if ((sp->type == 'V') || (is_percpu_symbol(sp))) return sp; } } else { if ((sp = symbol_search(symbol))) { - if ((sp->type == 'V') || - ((sp->value >= st->__per_cpu_start) && - (sp->value < st->__per_cpu_end))) + if ((sp->type == 'V') || (is_percpu_symbol(sp))) return sp; } @@ -5699,8 +5696,7 @@ display_per_cpu_info(struct syment *sp) char buf[BUFSIZE]; if (((kt->flags & (SMP|PER_CPU_OFF)) != (SMP|PER_CPU_OFF)) || - (sp->value < symbol_value("__per_cpu_start")) || - (sp->value >= symbol_value("__per_cpu_end")) || + (!is_percpu_symbol(sp)) || !((sp->type == 'd') || (sp->type == 'D') || (sp->type == 'V'))) return FALSE; @@ -5720,6 +5716,38 @@ display_per_cpu_info(struct syment *sp) return TRUE; } +static struct load_module *get_mod_percpu_sym_owner(struct syment *sp) +{ + int i; + struct load_module *lm; + + /* + * Find out percpu symbol owner module. + * If found out, sp is module's percpu symbol. + */ + for (i = 0; i < st->mods_installed; i++) { + lm = &st->load_modules[i]; + if (!lm->mod_percpu || !lm->mod_percpu_size) + continue; + if (IN_MODULE_PCPU(sp->value, lm)) + return lm; + } + return NULL; +} + +static int is_percpu_symbol(struct syment *sp) +{ + if (sp->value >= st->__per_cpu_start) { + if (sp->value < st->__per_cpu_end) + /* kernel percpu symbol */ + return 1; + else if (get_mod_percpu_sym_owner(sp)) + /* module percpu symbol */ + return 2; + } + return 0; +} + /* * As a latch ditch effort before a command is thrown away by exec_command(), * args[0] is checked to see whether it's the name of a variable, structure, -- 1.7.3.2.161.g3089c