跟踪kmalloc分到的memory为什么没有redzone and usercaller
[ 0.000000:0] kmem_cache_create: size-64 set redzone and calluser
[ 0.000000:0] kmem_cache_create: size-64 set poison
[ 0.000000:0] kmem_cache_create: size-64 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-64 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: AC name size-64, cachep ee000080
[ 0.000000:0] kmem_cache_create: size-96 set redzone and calluser
[ 0.000000:0] kmem_cache_create: size-96 set poison
[ 0.000000:0] kmem_cache_create: size-96 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-96 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: L3 name size-96, cachep ee000120
[ 0.000000:0] kmem_cache_create: size-32 set redzone and calluser
[ 0.000000:0] kmem_cache_create: size-32 set poison
[ 0.000000:0] kmem_cache_create: size-32 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-32 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-32, size 32
[ 0.000000:0] kmem_cache_init: kmalloc name size-64, size 64
[ 0.000000:0] kmem_cache_init: kmalloc name size-96, size 96
[ 0.000000:0] kmem_cache_create: size-128 set redzone and calluser
[ 0.000000:0] kmem_cache_create: size-128 set poison
[ 0.000000:0] kmem_cache_create: size-128 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-128 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-128, size 128
[ 0.000000:0] kmem_cache_create: size-192 set redzone and calluser
[ 0.000000:0] kmem_cache_create: size-192 set poison
[ 0.000000:0] kmem_cache_create: size-192 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-192 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-192, size 192
[ 0.000000:0] kmem_cache_create: size-256 set redzone and calluser
[ 0.000000:0] kmem_cache_create: size-256 set poison
[ 0.000000:0] kmem_cache_create: size-256 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-256 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-256, size 256
[ 0.000000:0] kmem_cache_create: size-512 set redzone and calluser
[ 0.000000:0] kmem_cache_create: size-512 set poison
[ 0.000000:0] kmem_cache_create: size-512 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-512 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-512, size 512
[ 0.000000:0] kmem_cache_create: size-1024 set redzone and calluser
[ 0.000000:0] kmem_cache_create: size-1024 set poison
[ 0.000000:0] kmem_cache_create: size-1024 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-1024 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-1024, size 1024
[ 0.000000:0] kmem_cache_create: size-2048 set redzone and calluser
[ 0.000000:0] kmem_cache_create: size-2048 set poison
[ 0.000000:0] kmem_cache_create: size-2048 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-2048 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-2048, size 2048
[ 0.000000:0] kmem_cache_create: size-4096 set poison
[ 0.000000:0] kmem_cache_create: size-4096 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-4096 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-4096, size 4096
[ 0.000000:0] kmem_cache_create: size-8192 set poison
[ 0.000000:0] kmem_cache_create: size-8192 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-8192 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-8192, size 8192
[ 0.000000:0] kmem_cache_create: size-16384 set poison
[ 0.000000:0] kmem_cache_create: size-16384 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-16384 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-16384, size 16384
[ 0.000000:0] kmem_cache_create: size-32768 set poison
[ 0.000000:0] kmem_cache_create: size-32768 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-32768 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-32768, size 32768
[ 0.000000:0] kmem_cache_create: size-65536 set poison
[ 0.000000:0] kmem_cache_create: size-65536 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-65536 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-65536, size 65536
[ 0.000000:0] kmem_cache_create: size-131072 set poison
[ 0.000000:0] kmem_cache_create: size-131072 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-131072 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-131072, size 131072
[ 0.000000:0] kmem_cache_create: size-262144 set poison
[ 0.000000:0] kmem_cache_create: size-262144 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-262144 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-262144, size 262144
[ 0.000000:0] kmem_cache_create: size-524288 set poison
[ 0.000000:0] kmem_cache_create: size-524288 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-524288 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-524288, size 524288
[ 0.000000:0] kmem_cache_create: size-1048576 set poison
[ 0.000000:0] kmem_cache_create: size-1048576 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-1048576 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-1048576, size 1048576
[ 0.000000:0] kmem_cache_create: size-2097152 set poison
[ 0.000000:0] kmem_cache_create: size-2097152 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-2097152 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-2097152, size 2097152
[ 0.000000:0] kmem_cache_create: size-4194304 set poison
[ 0.000000:0] kmem_cache_create: size-4194304 ralign 32, align 32
[ 0.000000:0] kmem_cache_create: size-4194304 disable redzone and usercaller
[ 0.000000:0] kmem_cache_init: kmalloc name size-4194304, size 4194304
问题出在输入参数align:ARCH_KMALLOC_MINALIGN[32】
kmem_cache_create:
从打印log看问题出在,也就是输入参数align:ARCH_KMALLOC_MINALIGN[32]
if (ralign < align) {
ralign = align;
}
/* disable debug if necessary 当前32 >8 所以关掉*/
if (ralign > __alignof__(unsigned long long)){
flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER);
pr_err("kmem_cache_create: %s disable redzone and usercaller\n", name);
}
怎样可以让它有啊?
跟踪宏定义ARCH_KMALLOC_MINALIGN:如下:
/*
* arch/arm/include/asm/cache.h
*/
#ifndef __ASMARM_CACHE_H
#define __ASMARM_CACHE_H
#define L1_CACHE_SHIFT CONFIG_ARM_L1_CACHE_SHIFT
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
/*
* Memory returned by kmalloc() may be used for DMA, so we must make
* sure that all such allocations are cache aligned. Otherwise,
* unrelated code may cause parts of the buffer to be read into the
* cache before the transfer is done, causing old data to be seen by
* the CPU.
*/
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
include/generated/autocong.h
#define CONFIG_ARM 1
#define CONFIG_ARM_L1_CACHE_SHIFT 5
include/linux/slab.h
/*
* Some archs want to perform DMA into kmalloc caches and need a guaranteed
* alignment larger than the alignment of a 64-bit integer.
* Setting ARCH_KMALLOC_MINALIGN in arch headers allows that.
*/
#ifdef ARCH_DMA_MINALIGN
#define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN
#else
#define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long)
#endif
所以,如果kmalloc分配出现red zone 等信息的话,只有不定义ARCH_DMA_MINALIGN即可。
使用redzone and usercaller分析问题
当前问题是struct dwc_otg_hcd_urb_t释放了之后还使用memory导致问题,查找哪里释放的?
现在的crash dump的kmalloc内存就包含了redzone and usercaller
从中我们就可有看到操作内存的函数。
当前出问题的是
crash> struct dwc_otg_hcd_urb_t -o
typedef struct dwc_otg_hcd_urb {
[0] void *priv;
[4] struct dwc_otg_qtd *qtd;
[8] void *buf;
[12] dwc_dma_t dma;
[16] void *setup_packet;
[20] dwc_dma_t setup_dma;
[24] uint32_t length;
[28] uint32_t actual_length;
[32] uint32_t status;
[36] uint32_t error_count;
[40] uint32_t packet_count;
[44] uint32_t flags;
[48] uint16_t interval;
[50] struct dwc_otg_hcd_pipe_info pipe_info;
[56] struct dwc_otg_hcd_iso_packet_desc iso_descs[];
} dwc_otg_hcd_urb_t;
SIZE: 56
应该使用size-64的kmalloc cache:
且已知的地址是:r2 : e63fdf48
考虑到redzone,其在kmem中看到的地址应该是e63fdf40;
crash> kmem -S size-64 | grep e63fdf
e63fdf40 (cpu 0 cache)
[e63fdf98]
下面看是那个函数释放了这块内存:
crash> rd e63fdf40 0x64
e63fdf40: 9d74e35b 09f91102 6b6b6b6b 6b6b6b6b [.t.....kkkkkkkk
e63fdf50: 6b6b6b6b 6b6b6b6b 6b6b6b6b 6b6b6b6b kkkkkkkkkkkkkkkk
e63fdf60: 6b6b6b6b 6b6b6b6b 6b6b6b6b 6b6b6b6b kkkkkkkkkkkkkkkk
e63fdf70: 6b6b6b6b 6b6b6b6b 6b6b6b6b 6b6b6b6b kkkkkkkkkkkkkkkk
e63fdf80: 6b6b6b6b a56b6b6b 9d74e35b 09f91102 kkkkkkk.[.t.....
e63fdf90: 00000000
c0311708
crash> dis -r c0311708
0xc03116f4 <__DWC_FREE>: mov r12, sp
0xc03116f8 <__DWC_FREE+4>: push {r11, r12, lr, pc}
0xc03116fc <__DWC_FREE+8>: sub r11, r12, #4
0xc0311700 <__DWC_FREE+12>: mov r0, r1
0xc0311704 <__DWC_FREE+16>: bl 0xc00ad90c <kfree>
0xc0311708 <__DWC_FREE+20>: ldm sp, {r11, sp, pc}
这里看是是函数:__DWC_FREE。
这就是我们想看到的。
问题是下面的for循环中:if()进入了多次,就是说释放后又进去了:又要释放。
static void complete_non_isoc_xfer_ddma(dwc_otg_hcd_t * hcd,
dwc_hc_t * hc,
dwc_otg_hc_regs_t * hc_regs,
dwc_otg_halt_status_e halt_status)
{
for (i = 0; i < qtd->n_desc; i++) {
dma_desc = &qh->desc_list[n_desc];
n_bytes = qh->n_bytes[n_desc];
failed =
update_non_isoc_urb_state_ddma(hcd, hc, qtd,
dma_desc,
halt_status, n_bytes,
&xfer_done);
if (failed
|| (xfer_done
&& (urb->status != -DWC_E_IN_PROGRESS))) {
hcd->fops->complete(hcd, urb->priv, urb,
urb->status);
dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh);
}
}
}