Current st->__per_cpu_end points at kernel's __per_cpu_end.
Since insmod require new percpu area for target module,
expand st->__per_cpu_end to include module's percpu area,
Replace from symbol_value("sym") to st->sym at display_per_cpu_info()
because they have already been initialized.
Signed-off-by: Toshikazu Nakayama <nakayama.ts(a)ncos.nec.co.jp>
---
symbols.c | 33 ++++++++++++++++++++++++++++++---
1 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/symbols.c b/symbols.c
index 0a1d170..4b4a0e3 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;
st->mods_installed = mods_installed;
@@ -1621,6 +1625,29 @@ 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->__per_cpu_end += block_size;
+ } else if ((sp = symbol_search("pcpu_reserved_chunk_limit")))
+ st->__per_cpu_end = sp->value;
+ }
+
st->flags |= MODULE_SYMS;
if (symbol_query("__insmod_", NULL, NULL))
@@ -5699,8 +5726,8 @@ 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")) ||
+ (sp->value < st->__per_cpu_start) ||
+ (sp->value >= st->__per_cpu_end) ||
!((sp->type == 'd') || (sp->type == 'D') || (sp->type ==
'V')))
return FALSE;
--
1.7.3.2.161.g3089c