----- Original Message ----- > > ----- Original Message ----- > > > If this is a memory corruption in one of the slab, would it be better > > if "crash" just skipped this slab (or marked it as 'fail to load') and > > show info for the rest of caches? > > I suppose that could be done, but there is no recording of the kmem_cache > slab list entries during intialization, so there's currently nothing that > could be "marked". But perhaps a list of "bad" slab caches could be created > by kmem_cache_init() which could be consulted later when "kmem -[sS]" cycle > through the slab list. If your problem is due to slab cache corruption, would something like the attached (and inlined) patch work for you? --- crash-7.0.1/defs.h.orig +++ crash-7.0.1/defs.h @@ -2183,6 +2183,8 @@ struct vm_table { /* kern int cpu_slab_type; int nr_vm_event_items; char **vm_event_items; + int nr_bad_slab_caches; + ulong *bad_slab_caches; }; #define NODES (0x1) --- crash-7.0.1/memory.c.orig +++ crash-7.0.1/memory.c @@ -8412,6 +8412,43 @@ kmem_cache_downsize(void) FREEBUF(cache_buf); } +/* + * Stash a list of presumably-corrupted slab cache addresses. + */ +static void +mark_bad_slab_cache(ulong cache) +{ + size_t sz; + + if (vt->nr_bad_slab_caches) { + sz = sizeof(ulong) * (vt->nr_bad_slab_caches + 1); + if (!(vt->bad_slab_caches = realloc(vt->bad_slab_caches, sz))) { + error(INFO, "cannot realloc bad_slab_caches array\n"); + vt->nr_bad_slab_caches = 0; + return; + } + } else { + if (!(vt->bad_slab_caches = (ulong *)malloc(sizeof(ulong)))) { + error(INFO, "cannot malloc bad_slab_caches array\n"); + return; + } + } + + vt->bad_slab_caches[vt->nr_bad_slab_caches++] = cache; +} + +static int +bad_slab_cache(ulong cache) +{ + int i; + + for (i = 0; i < vt->nr_bad_slab_caches; i++) { + if (vt->bad_slab_caches[i] == cache) + return TRUE; + } + + return FALSE; +} /* * Determine the largest cpudata limit for a given cache. @@ -8507,8 +8544,13 @@ kmem_cache_s_array_nodes: for (i = max_limit = 0; (i < kt->cpus) && cpudata[i]; i++) { if (!readmem(cpudata[i]+OFFSET(array_cache_limit), KVADDR, &limit, sizeof(int), - "array cache limit", RETURN_ON_ERROR)) - goto bail_out; + "array cache limit", RETURN_ON_ERROR)) { + error(INFO, + "kmem_cache: %lx: invalid array_cache pointer: %lx\n", + cache, cpudata[i]); + mark_bad_slab_cache(cache); + return max_limit; + } if (CRASHDEBUG(3)) fprintf(fp, " array limit[%d]: %d\n", i, limit); if (limit > max_limit) @@ -9213,6 +9255,11 @@ dump_kmem_cache_percpu_v2(struct meminfo goto next_cache; } + if (bad_slab_cache(si->cache)) { + fprintf(fp, "%lx %-18s [INVALID/CORRUPTED]\n", si->cache, buf); + goto next_cache; + } + si->curname = buf; readmem(si->cache+OFFSET(kmem_cache_s_objsize), @@ -11728,6 +11775,15 @@ dump_vm_table(int verbose) fprintf(fp, " kmem_cache_count: %ld\n", vt->kmem_cache_count); fprintf(fp, " kmem_cache_namelen: %d\n", vt->kmem_cache_namelen); fprintf(fp, "kmem_cache_len_nodes: %ld\n", vt->kmem_cache_len_nodes); + fprintf(fp, " nr_bad_slab_caches: %d\n", vt->nr_bad_slab_caches); + if (!vt->nr_bad_slab_caches) + fprintf(fp, " bad_slab_caches: (unused)\n"); + else { + for (i = 0; i < vt->nr_bad_slab_caches; i++) { + fprintf(fp, " bad_slab_caches[%d]: %lx\n", + i, vt->bad_slab_caches[i]); + } + } fprintf(fp, " PG_reserved: %lx\n", vt->PG_reserved); fprintf(fp, " PG_slab: %ld (%lx)\n", vt->PG_slab, (ulong)1 << vt->PG_slab); Thanks, Dave
--- crash-7.0.1/defs.h.orig +++ crash-7.0.1/defs.h @@ -2183,6 +2183,8 @@ struct vm_table { /* kern int cpu_slab_type; int nr_vm_event_items; char **vm_event_items; + int nr_bad_slab_caches; + ulong *bad_slab_caches; }; #define NODES (0x1) --- crash-7.0.1/memory.c.orig +++ crash-7.0.1/memory.c @@ -8412,6 +8412,43 @@ kmem_cache_downsize(void) FREEBUF(cache_buf); } +/* + * Stash a list of presumably-corrupted slab cache addresses. + */ +static void +mark_bad_slab_cache(ulong cache) +{ + size_t sz; + + if (vt->nr_bad_slab_caches) { + sz = sizeof(ulong) * (vt->nr_bad_slab_caches + 1); + if (!(vt->bad_slab_caches = realloc(vt->bad_slab_caches, sz))) { + error(INFO, "cannot realloc bad_slab_caches array\n"); + vt->nr_bad_slab_caches = 0; + return; + } + } else { + if (!(vt->bad_slab_caches = (ulong *)malloc(sizeof(ulong)))) { + error(INFO, "cannot malloc bad_slab_caches array\n"); + return; + } + } + + vt->bad_slab_caches[vt->nr_bad_slab_caches++] = cache; +} + +static int +bad_slab_cache(ulong cache) +{ + int i; + + for (i = 0; i < vt->nr_bad_slab_caches; i++) { + if (vt->bad_slab_caches[i] == cache) + return TRUE; + } + + return FALSE; +} /* * Determine the largest cpudata limit for a given cache. @@ -8507,8 +8544,13 @@ kmem_cache_s_array_nodes: for (i = max_limit = 0; (i < kt->cpus) && cpudata[i]; i++) { if (!readmem(cpudata[i]+OFFSET(array_cache_limit), KVADDR, &limit, sizeof(int), - "array cache limit", RETURN_ON_ERROR)) - goto bail_out; + "array cache limit", RETURN_ON_ERROR)) { + error(INFO, + "kmem_cache: %lx: invalid array_cache pointer: %lx\n", + cache, cpudata[i]); + mark_bad_slab_cache(cache); + return max_limit; + } if (CRASHDEBUG(3)) fprintf(fp, " array limit[%d]: %d\n", i, limit); if (limit > max_limit) @@ -9213,6 +9255,11 @@ dump_kmem_cache_percpu_v2(struct meminfo goto next_cache; } + if (bad_slab_cache(si->cache)) { + fprintf(fp, "%lx %-18s [INVALID/CORRUPTED]\n", si->cache, buf); + goto next_cache; + } + si->curname = buf; readmem(si->cache+OFFSET(kmem_cache_s_objsize), @@ -11728,6 +11775,15 @@ dump_vm_table(int verbose) fprintf(fp, " kmem_cache_count: %ld\n", vt->kmem_cache_count); fprintf(fp, " kmem_cache_namelen: %d\n", vt->kmem_cache_namelen); fprintf(fp, "kmem_cache_len_nodes: %ld\n", vt->kmem_cache_len_nodes); + fprintf(fp, " nr_bad_slab_caches: %d\n", vt->nr_bad_slab_caches); + if (!vt->nr_bad_slab_caches) + fprintf(fp, " bad_slab_caches: (unused)\n"); + else { + for (i = 0; i < vt->nr_bad_slab_caches; i++) { + fprintf(fp, " bad_slab_caches[%d]: %lx\n", + i, vt->bad_slab_caches[i]); + } + } fprintf(fp, " PG_reserved: %lx\n", vt->PG_reserved); fprintf(fp, " PG_slab: %ld (%lx)\n", vt->PG_slab, (ulong)1 << vt->PG_slab);
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility