----- Original Message -----
But your patch does this:
@@ -8117,8 +8135,9 @@ kmem_cache_s_array_nodes:
"array cache array", RETURN_ON_ERROR))
goto bail_out;
- for (i = max_limit = 0; (i < ARRAY_LENGTH(kmem_cache_s_array)) &&
- cpudata[i]; i++) {
+ for (i = max_limit = 0; (i < kmem_cache_nr_cpu)
+ && (i < ARRAY_LENGTH(kmem_cache_s_array))
+ && cpudata[i]; i++) {
if (!readmem(cpudata[i]+OFFSET(array_cache_limit),
KVADDR, &limit, sizeof(int),
"array cache limit", RETURN_ON_ERROR))
On "old" slab systems, your new "kmem_cache_nr_cpu" variable remains
at
its initialized value of zero, and the loop never gets entered. So I don't
think you wanted to keep the (i < kmem_cache_nr_cpu) there, right?
How's this work for you? (patch also attached)
--- crash-6.0.3/memory.c.orig
+++ crash-6.0.3/memory.c
@@ -7977,14 +7977,32 @@ kmem_cache_downsize(void)
char *cache_buf;
uint buffer_size;
int nr_node_ids;
+ int nr_cpu_ids;
if ((THIS_KERNEL_VERSION < LINUX(2,6,22)) ||
- (vt->flags & NODELISTS_IS_PTR) ||
!(vt->flags & PERCPU_KMALLOC_V2_NODES) ||
!kernel_symbol_exists("cache_cache") ||
!MEMBER_EXISTS("kmem_cache", "buffer_size"))
return;
+ if (vt->flags & NODELISTS_IS_PTR) {
+ /*
+ * kmem_cache.array[] is actually sized by
+ * the number of cpus; real value is nr_cpu_ids,
+ * but fallback is kt->cpus.
+ */
+ if (kernel_symbol_exists("nr_cpu_ids"))
+ get_symbol_data("nr_cpu_ids", sizeof(int),
+ &nr_cpu_ids);
+ else
+ nr_cpu_ids = kt->cpus;
+
+ ARRAY_LENGTH(kmem_cache_s_array) = nr_cpu_ids;
+ ASSIGN_SIZE(kmem_cache_s) = OFFSET(kmem_cache_s_array) +
+ sizeof(ulong) * nr_cpu_ids;
+ return;
+ }
+
cache_buf = GETBUF(SIZE(kmem_cache_s));
if (!readmem(symbol_value("cache_cache"), KVADDR, cache_buf,
Dave