kmalloc fail导致系统异常

博客分析了在中断服务例程(ISR)中进行内存分配可能导致的系统异常问题。由于ISR不应包含可调度操作,使用`kmalloc(GFP_ATOMIC)`而非`kmalloc(GFP_KERNEL)`更为安全,因为`GFP_KERNEL`可能引起调度并导致内存分配失败,从而触发kernel BUG。文中举例展示了因内存分配失败引发的错误日志。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果在中断ISR中间有作memory alloc的动作,有可能会遇到如下的BUG log信息,分析如下:

1  ISR中不能存在任何可调度的动作,如sleep等

2  在ISR中申请memory时,最好尽量使用 kmalloc(xxx, GFP_ATOMIC), 而不要使用kmalloc(xxx, GFP_KERNEL), 因为GFP_KERNEL是可以被打断的,如果因memory not enough 或其他原因alloc fail掉,则kmalloc动作将会被调度走,并等待下一次alloc, 这样就会导致kernel BUG.


[80572.488640] BUG: scheduling while atomic: BGM/821/0x40000103

[80572.494232] Modules linked in: snd_mtk mali_kbase(O) ump(O) kds(O) mtk_mmap(PO) usbhid usb_storage mtk_hcd ntfs btmtk_usb mt7662u_sta(O) driver_cli(PO) mtk_mod(PO) fusion(O)
[80572.509686] CPU: 1 PID: 821 Comm: BGM Tainted: P        W  O 3.10.79 #1
[80572.516296] [<c0012d24>] (unwind_backtrace+0x0/0xdc) from [<c0010db0>] (show_stack+0x10/0x14)
[80572.524793] [<c0010db0>] (show_stack+0x10/0x14) from [<c037d720>] (__schedule_bug+0x48/0x64)
[80572.533211] [<c037d720>] (__schedule_bug+0x48/0x64) fr
03-08
### kmalloc 函数使用说明 `kmalloc()` 是 Linux 内核中最常用的动态内存分配函数之一。该函数用于从内核的 slab 分配器获取一块连续的物理地址空间,并返回指向这块内存区域的指针[^2]。 #### 函数原型 ```c void *kmalloc(size_t size, gfp_t flags); ``` - `size`: 请求分配的字节数。 - `flags`: 指定如何以及何时应该尝试满足请求的一组标志位组合,这些标志可以控制分配行为,比如是否允许睡眠等待、是否可以从高端内存区分配等。 #### 返回值 如果成功,则返回一个指向新分配内存块的指针;如果失败则返回 NULL。需要注意的是,通过 `kmalloc()` 获取到的内存并不保证被初始化为特定值,在使用前应当自行初始化以避免未定义的行为。 #### 示例代码 下面是一个简单的例子来展示怎样利用 `kmalloc()` 进行动态内存分配: ```c #include <linux/slab.h> struct my_struct { int a; char b; }; // 假设这是某个驱动程序的一部分 static struct my_struct *example; int init_module(void){ example = (struct my_struct *)kmalloc(sizeof(struct my_struct), GFP_KERNEL); if (!example) { // 如果分配失败处理逻辑 printk(KERN_ALERT "Failed to allocate memory\n"); return -ENOMEM; } // 初始化数据结构... memset(example, 0, sizeof(struct my_struct)); example->a = 10; example->b = 'A'; return 0; } void cleanup_module(void){ kfree(example); // 记得释放之前申请过的资源 } ``` 此段代码展示了如何安全地调用 `kmalloc()` 来创建一个新的自定义类型实例并对其进行适当的操作。当不再需要这段内存时,应始终记得调用相应的释放接口 (`kfree`) 来回收它所占用的空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值