[Crash-utility] [PATCH] Fix for "kmem <addr>" for kernels configured with CONFIG_SLUB and SLAB_RED_ZONE.

Dave Anderson anderson at redhat.com
Thu Feb 2 20:25:04 UTC 2017



----- Original Message -----
> Dave Anderson <anderson at redhat.com> writes:
> 
> > Right, but the question is whether it makes more sense to display the
> > full slab object address containing the red-zone buffer or not.  When
> > debugging slab corruption for example, I would argue it's more relevant
> > to show the full object address.  For example, if you want to follow
> > that linked list from kmem_cache_cpu.freelist pointer, if I'm not mistaken
> > the next pointer in each object will be located in the first word of the
> > object.  Anyway, that is more in line with the original intent of kmem -S
> > command, even in the case when slub debug is turned on.
> >
> > On the other hand, in your example above, you are presuming the address
> > shown should be what the kmalloc() or kmem_cache_alloc() caller receives,
> > which I agree has merit.  But consider that you can enter any address
> > within an object, and get the same result.
> >
> > I wonder whether there can be a compromise, such that in the case of slub
> > debug, there could be extra information in the output display that
> > indicates
> > that the object contains a red zone buffer?
> 
> I see. Then how about this? Adding additional information "(data %lx)".
> 
> With red_left_zone (object addr < data addr),
> 
> crash> kmem ffffea0004de2c00
> CACHE            NAME                 OBJSIZE  ALLOCATED     TOTAL  SLABS
> SSIZE
> ffff88013a719900 ext4_inode_cache        2200        730       742     53
> 32k
>   SLAB              MEMORY            NODE  TOTAL  ALLOCATED  FREE
>   ffffea0004de2c00  ffff8801378b0000     0     14          2    12
>   FREE / [ALLOCATED]
>    ffff8801378b0000  (data ffff8801378b0008, cpu 0 cache)
>   [ffff8801378b08b8] (data ffff8801378b08c0)
> 
> Without red_left_zone (object addr == data addr),
> 
> crash> kmem ffffea0004e5be00
> CACHE            NAME                 OBJSIZE  ALLOCATED     TOTAL  SLABS
> SSIZE
> ffff88013a6f2f00 ext4_inode_cache        2200        730       742     53
> 32k
>   SLAB              MEMORY            NODE  TOTAL  ALLOCATED  FREE
>   ffffea0004e5be00  ffff8801396f8000     0     14          2    12
>   FREE / [ALLOCATED]
>    ffff8801396f8000  (cpu 0 cache)
>   [ffff8801396f88a0]
> 
> Thanks.
> 
> ---
> Fix for "kmem <addr>" for kernels configured with CONFIG_SLUB and
> SLAB_RED_ZONE.
> 
> If SLAB_RED_ZONE is enabled, slub adds guard zone of sizeof(void *)
> onto left of object on v4.6 or later.
> 
> Without this fix, like following SUPERBLK and [allocate addr] has
> difference.
> 
> crash> mount
>      MOUNT           SUPERBLK     TYPE   DEVNAME   DIRNAME
> ffff88013ae58040 ffff88013ac35698 rootfs rootfs    /
> [...]
> crash> kmem ffff88013ac35698
> CACHE            NAME                 OBJSIZE  ALLOCATED     TOTAL  SLABS
> SSIZE
> ffff88013ac05bc0 kmalloc-4096            4096        118       126     18
> 32k
>   SLAB              MEMORY            NODE  TOTAL  ALLOCATED  FREE
>   ffffea0004eb0c00  ffff88013ac30000     0      7          7     0
>   FREE / [ALLOCATED]
>   [ffff88013ac35690]
> [...]
> 
> This left pad for RED_ZONE may confuses the user, so this adds
> additional information, like following if data_start != object_start.
> 
> crash> kmem ffffea0004de2c00
> CACHE            NAME                 OBJSIZE  ALLOCATED     TOTAL  SLABS
> SSIZE
> ffff88013a719900 ext4_inode_cache        2200        730       742     53
> 32k
>   SLAB              MEMORY            NODE  TOTAL  ALLOCATED  FREE
>   ffffea0004de2c00  ffff8801378b0000     0     14          2    12
>   FREE / [ALLOCATED]
>    ffff8801378b0000  (data ffff8801378b0008, cpu 0 cache)
>   [ffff8801378b08b8] (data ffff8801378b08c0)
> 
> ---

That's kind of cluttered -- I was thinking of something like this:

crash> kmem ffffea0004de2c00
CACHE            NAME                 OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE
ffff88013a719900 ext4_inode_cache        2200        730       742     53    32k
  SLAB              MEMORY            NODE  TOTAL  ALLOCATED  FREE  RED_ZONE
  ffffea0004de2c00  ffff8801378b0000     0     14          2    12      8
  FREE / [ALLOCATED] 
   ffff8801378b0000  (cpu 0 cache)
  [ffff8801378b08b8] 

or better yet, this:

crash> kmem ffffea0004de2c00
CACHE            NAME                 OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE
ffff88013a719900 ext4_inode_cache        2200        730       742     53    32k
  SLAB              MEMORY            NODE  TOTAL  ALLOCATED  FREE 
  ffffea0004de2c00  ffff8801378b0000     0     14          2    12       
  FREE / [ALLOCATED] SLAB_RED_ZONE: 8
   ffff8801378b0000  (cpu 0 cache)
  [ffff8801378b08b8] 

Dave





> 
>  defs.h    |    1 +
>  memory.c  |   28 ++++++++++++++++++++++++----
>  symbols.c |    2 ++
>  3 files changed, 27 insertions(+), 4 deletions(-)
> 
> diff -puN memory.c~slub-red_zone-fix memory.c
> --- crash-64/memory.c~slub-red_zone-fix	2017-02-02 13:01:54.263337316 +0900
> +++ crash-64-hirofumi/memory.c	2017-02-03 04:48:24.692595383 +0900
> @@ -723,6 +723,7 @@ vm_init(void)
>  		MEMBER_OFFSET_INIT(kmem_cache_node, "kmem_cache", "node");
>  		MEMBER_OFFSET_INIT(kmem_cache_cpu_slab, "kmem_cache", "cpu_slab");
>  		MEMBER_OFFSET_INIT(kmem_cache_list, "kmem_cache", "list");
> +		MEMBER_OFFSET_INIT(kmem_cache_red_left_pad, "kmem_cache", "red_left_pad");
>  		MEMBER_OFFSET_INIT(kmem_cache_name, "kmem_cache", "name");
>  		MEMBER_OFFSET_INIT(kmem_cache_flags, "kmem_cache", "flags");
>  		MEMBER_OFFSET_INIT(kmem_cache_cpu_freelist, "kmem_cache_cpu", "freelist");
> @@ -18354,7 +18355,7 @@ do_slab_slub(struct meminfo *si, int ver
>  	physaddr_t paddr;
>  	ulong vaddr;
>  	ushort inuse, objects;
> -	ulong freelist, cpu_freelist, cpu_slab_ptr;
> +	ulong freelist, cpu_freelist, cpu_slab_ptr, red_left_pad;
>  	int i, free_objects, cpu_slab, is_free, node;
>  	ulong p, q;
>  
> @@ -18442,6 +18443,13 @@ do_slab_slub(struct meminfo *si, int ver
>  			fprintf(fp, "< SLUB: free list END (%d found) >\n", i);
>  	}
>  
> +	red_left_pad = 0;
> +	if (VALID_MEMBER(kmem_cache_red_left_pad)) {
> +#define SLAB_RED_ZONE 0x00000400UL
> +		ulong flags = ULONG(si->cache_buf + OFFSET(kmem_cache_flags));
> +		if (flags & SLAB_RED_ZONE)
> +			red_left_pad = ULONG(si->cache_buf + OFFSET(kmem_cache_red_left_pad));
> +	}
>  	for (p = vaddr; p < vaddr + objects * si->size; p += si->size) {
>  		hq_open();
>  		is_free = FALSE;
> @@ -18482,9 +18490,21 @@ do_slab_slub(struct meminfo *si, int ver
>  
>  		fprintf(fp, "  %s%lx%s",
>  			is_free ? " " : "[",
> -			p, is_free ? "  " : "]");
> -		if (is_free && (cpu_slab >= 0))
> -			fprintf(fp, "(cpu %d cache)", cpu_slab);
> +			p, is_free ? " " : "]");
> +		if (red_left_pad || (is_free && (cpu_slab >= 0))) {
> +			int need_comma = 0;
> +			fprintf(fp, " (");
> +			if (red_left_pad) {
> +				fprintf(fp, "data %lx", p + red_left_pad);
> +				need_comma = 1;
> +			}
> +			if (is_free && (cpu_slab >= 0)) {
> +				if (need_comma)
> +					fprintf(fp, ", ");
> +				fprintf(fp, "cpu %d cache", cpu_slab);
> +			}
> +			fprintf(fp, ")");
> +		}
>  		fprintf(fp, "\n");
>  
>  	}
> diff -puN defs.h~slub-red_zone-fix defs.h
> --- crash-64/defs.h~slub-red_zone-fix	2017-02-02 13:01:54.264337322 +0900
> +++ crash-64-hirofumi/defs.h	2017-02-03 03:26:39.211648619 +0900
> @@ -1696,6 +1696,7 @@ struct offset_table {
>  	long kmem_cache_align;
>  	long kmem_cache_name;
>  	long kmem_cache_list;
> +	long kmem_cache_red_left_pad;
>  	long kmem_cache_node;
>  	long kmem_cache_cpu_slab;
>  	long page_inuse;
> diff -puN symbols.c~slub-red_zone-fix symbols.c
> --- crash-64/symbols.c~slub-red_zone-fix	2017-02-02 13:01:54.264337322 +0900
> +++ crash-64-hirofumi/symbols.c	2017-02-03 03:26:39.213648633 +0900
> @@ -9330,6 +9330,8 @@ dump_offset_table(char *spec, ulong make
>                  OFFSET(kmem_cache_name));
>          fprintf(fp, "               kmem_cache_list: %ld\n",
>                  OFFSET(kmem_cache_list));
> +        fprintf(fp, "       kmem_cache_red_left_pad: %ld\n",
> +                OFFSET(kmem_cache_red_left_pad));
>          fprintf(fp, "               kmem_cache_node: %ld\n",
>                  OFFSET(kmem_cache_node));
>          fprintf(fp, "           kmem_cache_cpu_slab: %ld\n",
> _
> 
> 
> --
> OGAWA Hirofumi <hirofumi at mail.parknet.co.jp>
> 




More information about the Crash-utility mailing list