22、 BUG at __get_vm_area_node()

异常现场

当你在SYS_KERNEL_LOG里看到如下log,那么就属于BUG at __get_vm_area_node一类问题了

[ 271.881362]<0>-0)Internal error: Oops: 96000045 [#1] PREEMPT SMP
......
[ 280.012666]<0>-0)PC is at __get_vm_area_node.isra.28+0x1d4/0x1ec
[ 280.012672]<0>-0)LR is at get_vm_area_caller+0x2c/0x34
......
[ 280.014883]<0>-0)Call trace:
[ 280.014891]<0>-0)[<ffffffc00017df54>] __get_vm_area_node.isra.28+0x1d4/0x1ec
[ 280.014898]<0>-0)[<ffffffc00017ea48>] get_vm_area_caller+0x28/0x34
[ 280.014909]<0>-0)[<ffffffc0000948c4>] __ioremap+0x64/0xe8
[ 280.014920]<0>-0)[<ffffffc0006e0f2c>] hal_dma_dump_reg+0xf0/0xa0c
[ 280.014932]<0>-0)[<ffffffc0006d934c>] btif_bbs_write.constprop.24+0x2b0/0x2dc
[ 280.014943]<0>-0)[<ffffffc0006db1f8>] btif_dma_rx_data_receiver+0x1c/0x4c
[ 280.014950]<0>-0)[<ffffffc0006e0cf8>] hal_rx_dma_irq_handler+0x170/0x2b4
[ 280.014959]<0>-0)[<ffffffc0006d7c6c>] btif_rx_dma_irq_handler+0x64/0xec
[ 280.014970]<0>-0)[<ffffffc00011ff08>] handle_irq_event_percpu+0x98/0x3c8
[ 280.014978]<0>-0)[<ffffffc000120280>] handle_irq_event+0x48/0x78
[ 280.014987]<0>-0)[<ffffffc0001230c4>] handle_fasteoi_irq+0xb0/0x150
[ 280.014996]<0>-0)[<ffffffc00011f784>] generic_handle_irq+0x30/0x4c
[ 280.015005]<0>-0)[<ffffffc0000848e4>] handle_IRQ+0x94/0x1cc
[ 280.015012]<0>-0)[<ffffffc000081608>] gic_handle_irq+0x3c/0x80

代码位置:

kernel-3.18/mm/vmalloc.c

static struct vm_struct *__get_vm_area_node(unsigned long size,
unsigned long align, unsigned long flags, unsigned long start,
unsigned long end, int node, gfp_t gfp_mask, const void *caller)
{
struct vmap_area *va;
struct vm_struct *area;

BUG_ON(in_interrupt());
......
}

问题解读:

BUG_ON放在这里意思是在不允许在中断里调用__get_vm_area_node()函数

为什么呢?应该是设计时就不允许在中断里使用的,该函数使用了全局变量,用spin_lock保护,这种锁无法保护到中断上下文。如果在中断里使用__get_vm_area_node()可能会引起一系列问题。

哪些常用函数会调用到__get_vm_area_node()呢?

  • vmalloc()系列函数
  • ioremap()系列函数,包括of_iomap()函数

也即是说,这些函数禁止在中断里调用!

问题解决:

如果是在中断里调用ioremap()函数则可以考虑在初始化时就map好。比如上面的例子,就应该在初始化时就map好,在中断里直接用就行了。

如果是vmalloc(),可以考虑用kmalloc()替换。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值