当前位置: 技术问答>linux和unix
求助,内核kmalloc问题
来源: 互联网 发布时间:2016-12-02
本文导语: 没怎么写过内核模块,今天写了个提示如下错误,自己比较菜,大家看看,谢谢 BUG: scheduling while atomic: mynetlink/0x10000100/19413 [] schedule+0x43/0xa55 [] do_IRQ+0xb5/0xc3 [] __cond_resched+0x16/0x34 [] cond_resched+0x26/0x31 [] kme...
没怎么写过内核模块,今天写了个提示如下错误,自己比较菜,大家看看,谢谢
BUG: scheduling while atomic: mynetlink/0x10000100/19413
[] schedule+0x43/0xa55
[] do_IRQ+0xb5/0xc3
[] __cond_resched+0x16/0x34
[] cond_resched+0x26/0x31
[] kmem_cache_alloc+0x11/0x4b
[] pro_thread+0x191/0x2e0 [redirect]
[] syscall_exit_work+0x12/0x17
[] pro_thread_thread+0x0/0x2e0 [redirect]
[] autoremove_wake_function+0x0/0x2d
[] pro_thread_thread+0x0/0x2e0 [redirect]
[] kernel_thread_helper+0x7/0x10
BUG: scheduling while atomic: mynetlink/0x10000100/19413
[] schedule+0x43/0xa55
[] do_IRQ+0xb5/0xc3
[] __cond_resched+0x16/0x34
[] cond_resched+0x26/0x31
[] kmem_cache_alloc+0x11/0x4b
[] pro_thread+0x191/0x2e0 [redirect]
[] syscall_exit_work+0x12/0x17
[] pro_thread_thread+0x0/0x2e0 [redirect]
[] autoremove_wake_function+0x0/0x2d
[] pro_thread_thread+0x0/0x2e0 [redirect]
[] kernel_thread_helper+0x7/0x10
|
中断环境下不能使用GFP_KERNEL请求内存,这种方式会休眠。必须用GFP_ATOMIC原子方式。
|
中断环境是指中断处理程序或softirq中,此时内核代表硬件或自身执行,而不是代表进程,所以不能睡眠。
睡眠是和进程相关的概念,此时如果睡眠那唤醒时又恢复到哪个进程呢?
睡眠是和进程相关的概念,此时如果睡眠那唤醒时又恢复到哪个进程呢?
|
参加第二版,下面是他的相关内容:
When executing an interrupt handler or bottom half, the kernel is in interrupt context. Recall that process context is the mode of operation the kernel is in while it is executing on behalf of a process. for example, executing a system call or running a kernel thread. In process context, the current macro points to the associated task. Furthermore, because a process is coupled to the kernel in process context, process context can sleep or otherwise invoke the scheduler.
Interrupt context, on the other hand, is not associated with a process. The current macro is not relevant (although it points to the interrupted process). Without a backing process, interrupt context cannot sleephow would it ever reschedule? Therefore, you cannot call certain functions from interrupt context. If a function sleeps, you cannot use it from your interrupt handler. this limits the functions that one can call from an interrupt handler.
其中bottom half在linux2.6中的实现就是softirq。
可知Interrupt context中不能进行与进程相关的睡眠和调度。
When executing an interrupt handler or bottom half, the kernel is in interrupt context. Recall that process context is the mode of operation the kernel is in while it is executing on behalf of a process. for example, executing a system call or running a kernel thread. In process context, the current macro points to the associated task. Furthermore, because a process is coupled to the kernel in process context, process context can sleep or otherwise invoke the scheduler.
Interrupt context, on the other hand, is not associated with a process. The current macro is not relevant (although it points to the interrupted process). Without a backing process, interrupt context cannot sleephow would it ever reschedule? Therefore, you cannot call certain functions from interrupt context. If a function sleeps, you cannot use it from your interrupt handler. this limits the functions that one can call from an interrupt handler.
其中bottom half在linux2.6中的实现就是softirq。
可知Interrupt context中不能进行与进程相关的睡眠和调度。
|
看内核源码,这个bug的触发是你 禁用了系统抢占又去调用schedule。
就是想你说的这样使用GFP_KERNEL 参数调用kmalloc时,它可能会调用schedule的。因为你当前是中断环境系统抢占已经被禁用,所以不能使用GFP_KERNEL参数了。
这时你应该使用GFP_ATOMIC参数来调用kmalloc 就可以了,或者在进入中断之前,事先用kmalloc( GFP_KERNEL 分配好接受内存。
就是想你说的这样使用GFP_KERNEL 参数调用kmalloc时,它可能会调用schedule的。因为你当前是中断环境系统抢占已经被禁用,所以不能使用GFP_KERNEL参数了。
这时你应该使用GFP_ATOMIC参数来调用kmalloc 就可以了,或者在进入中断之前,事先用kmalloc( GFP_KERNEL 分配好接受内存。