[Crash-utility] [PATCH] Add support for SLAB OBJFREELIST_SLAB.

Dave Anderson anderson at redhat.com
Fri Dec 2 18:59:26 UTC 2016



----- Original Message -----
> In this mode, the freelist can be an object and if the slab is full,
> there is no freelist. On the next free, an object is recycled to be used
> as the freelist but not clean-up. This change will go through only
> known freed objects to prevent errors of wrong/corrupt freelist entries.
> 
> Related to the linux kernel commit: b03a017bebc403d40aa53a092e79b3020786537d.

Thanks Thomas -- the patch queued for crash-7.1.8:

  https://github.com/crash-utility/crash/commit/59fbaf3e4b030b150f750f5b0ac7dfc3eafaa78f

Dave


> ---
>  memory.c | 30 ++++++++++++++++++++++++------
>  1 file changed, 24 insertions(+), 6 deletions(-)
> 
> diff --git a/memory.c b/memory.c
> index 4eac413..774d090 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -9880,6 +9880,7 @@ ignore_cache(struct meminfo *si, char *name)
>  #define SLAB_MAGIC_DESTROYED    0xB2F23C5AUL    /* slab has been destroyed
>  */
>  
>  #define SLAB_CFLGS_BUFCTL       0x020000UL      /* bufctls in own cache */
> +#define SLAB_CFLGS_OBJFREELIST  0x40000000UL    /* Freelist as an object */
>  
>  #define KMEM_SLAB_ADDR          (1)
>  #define KMEM_BUFCTL_ADDR        (2)
> @@ -12439,11 +12440,13 @@ gather_slab_free_list_percpu(struct meminfo *si)
>  static void
>  gather_slab_free_list_slab_overload_page(struct meminfo *si)
>  {
> -	int i, active;
> +	int i, active, start_offset;
>  	ulong obj, objnr, cnt, freelist;
>  	unsigned char *ucharptr;
>  	unsigned short *ushortptr;
>  	unsigned int *uintptr;
> +	unsigned int cache_flags, overload_active;
> +	ulong slab_overload_page;
>  
>  	if (CRASHDEBUG(1))
>  		fprintf(fp, "slab page: %lx active: %ld si->c_num: %ld\n",
> @@ -12452,12 +12455,19 @@ gather_slab_free_list_slab_overload_page(struct
> meminfo *si)
>  	if (si->s_inuse == si->c_num )
>  		return;
>  
> -	readmem(si->slab - OFFSET(page_lru) + OFFSET(page_freelist),
> +	slab_overload_page = si->slab - OFFSET(page_lru);
> +	readmem(slab_overload_page + OFFSET(page_freelist),
>  		KVADDR, &freelist, sizeof(void *), "page freelist",
>  		FAULT_ON_ERROR);
>          readmem(freelist, KVADDR, si->freelist,
>  		si->freelist_index_size * si->c_num,
>                  "freelist array", FAULT_ON_ERROR);
> +	readmem(si->cache+OFFSET(kmem_cache_s_flags),
> +		KVADDR, &cache_flags, sizeof(uint),
> +		"kmem_cache_s flags", FAULT_ON_ERROR);
> +        readmem(slab_overload_page + OFFSET(page_active),
> +                KVADDR, &overload_active, sizeof(uint),
> +                "active", FAULT_ON_ERROR);
>  
>  	BNEG(si->addrlist, sizeof(ulong) * (si->c_num+1));
>  	cnt = objnr = 0;
> @@ -12466,14 +12476,22 @@ gather_slab_free_list_slab_overload_page(struct
> meminfo *si)
>  	uintptr = NULL;
>  	active = si->s_inuse;
>  
> +	/*
> +	 * On an OBJFREELIST slab, the object might have been recycled
> +	 * and everything before the active count can be random data.
> +	 */
> +	start_offset = 0;
> +	if (cache_flags & SLAB_CFLGS_OBJFREELIST)
> +		start_offset = overload_active;
> +
>  	switch (si->freelist_index_size)
>  	{
> -	case 1: ucharptr = (unsigned char *)si->freelist; break;
> -	case 2: ushortptr = (unsigned short *)si->freelist; break;
> -	case 4: uintptr = (unsigned int *)si->freelist; break;
> +	case 1: ucharptr = (unsigned char *)si->freelist + start_offset; break;
> +	case 2: ushortptr = (unsigned short *)si->freelist + start_offset; break;
> +	case 4: uintptr = (unsigned int *)si->freelist + start_offset; break;
>  	}
>  
> -	for (i = 0; i < si->c_num; i++) {
> +	for (i = start_offset; i < si->c_num; i++) {
>  		switch (si->freelist_index_size)
>  		{
>  		case 1: objnr = (ulong)*ucharptr++; break;
> --
> 2.8.0.rc3.226.g39d4020
> 
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
> 




More information about the Crash-utility mailing list