From 6877a3bf72349274bc7231dcbb73f808429e6207 Mon Sep 17 00:00:00 2001 From: Toshikazu Nakayama Date: Fri, 5 Nov 2010 15:08:30 +0900 Subject: [PATCH 3/4] expand percpu area. Add percpu_mod_used in st. Evaluate percpu range by using new function is_per_cpu_range(syment *), retval: 1 (kernel percpu), 2 (module percpu), 0 (not in percpu). But retval is the same to TRUE/FALSE currently. Replace existing percpu range check with is_per_cpu_range(). Signed-off-by: Toshikazu Nakayama --- defs.h | 1 + symbols.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/defs.h b/defs.h index 3b279ae..0c60b37 100755 --- a/defs.h +++ b/defs.h @@ -1981,6 +1981,7 @@ struct symbol_table_data { ulong first_ksymbol; ulong __per_cpu_start; ulong __per_cpu_end; + ulong percpu_mod_used; }; /* flags for st */ diff --git a/symbols.c b/symbols.c index 0a1d170..b34fbad 100755 --- a/symbols.c +++ b/symbols.c @@ -1271,8 +1271,12 @@ store_module_symbols_v2(ulong total, int mods_installed) char buf3[BUFSIZE]; char buf4[BUFSIZE]; char *strbuf, *modbuf, *modsymbuf; - struct syment *sp; + struct syment *sp, *sp2; ulong first, last; + uint pcpu_num_used; + ulong pcpu_size; + uint block_size; + int *pcpu_vals, pcpu_reserved_chunk_limit; st->mods_installed = mods_installed; @@ -1621,6 +1625,33 @@ store_module_symbols_v2(ulong total, int mods_installed) } } + if (kt->flags & KALLSYMS_V2) { + /* expand percpu range for module. */ + if (((sp = symbol_search("pcpu_num_used")) && sp->value) && + ((sp2 = symbol_search("pcpu_size")))) { + readmem(sp->value, KVADDR, &pcpu_num_used, + sizeof(pcpu_num_used), "percpu used", + FAULT_ON_ERROR); + readmem(sp2->value, KVADDR, &pcpu_size, + sizeof(pcpu_size), "percpu size ptr", + FAULT_ON_ERROR); + pcpu_vals = (int *)malloc(sizeof(int) * pcpu_num_used); + readmem(pcpu_size, KVADDR, pcpu_vals, + sizeof(int) * pcpu_num_used, "percpu size vals", + FAULT_ON_ERROR); + block_size = 0; + for (i = 0; i < pcpu_num_used; i++) + block_size += abs(pcpu_vals[i]); + free(pcpu_vals); + st->percpu_mod_used += block_size; + } else if ((sp = symbol_search("pcpu_reserved_chunk_limit"))) { + readmem(sp->value, KVADDR, &pcpu_reserved_chunk_limit, + sizeof(pcpu_reserved_chunk_limit), + "percpu size val", FAULT_ON_ERROR); + st->percpu_mod_used = pcpu_reserved_chunk_limit; + } + } + st->flags |= MODULE_SYMS; if (symbol_query("__insmod_", NULL, NULL)) @@ -4412,6 +4443,19 @@ symbol_exists(char *symbol) return(FALSE); } +static int is_per_cpu_range(struct syment *sp) +{ + if (sp->value >= st->__per_cpu_start) { + if (sp->value < st->__per_cpu_end) + /* kernel percpu area */ + return 1; + else if (sp->value < st->__per_cpu_end + st->percpu_mod_used) + /* module percpu area */ + return 2; + } + return 0; +} + /* * Determine whether a per-cpu symbol exists. @@ -4433,16 +4477,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_per_cpu_range(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_per_cpu_range(sp))) return sp; } @@ -5699,8 +5739,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_per_cpu_range(sp)) || !((sp->type == 'd') || (sp->type == 'D') || (sp->type == 'V'))) return FALSE; -- 1.7.3.2.161.g3089c