解析内核错误信息

本文详细解析了在编写USB鼠标驱动时遇到的错误信息,包括错误原因、内核堆栈信息及解决方法。主要涉及到中断处理函数的参数使用不当,通过对比GFP_ATOMIC与GFP_KERNEL宏的作用,指出正确参数选择的重要性,并最终修正了问题。

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

BUG: sleeping function called from invalid context at mm/slub.c:795
in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper
[<c0038d70>] (unwind_backtrace+0x0/0xe4) from [<c00a0400>] (__kmalloc+0x6c/0xf4)
[<c00a0400>] (__kmalloc+0x6c/0xf4) from [<c01fac00>] (ohci_urb_enqueue+0x218/0x68c)
[<c01fac00>] (ohci_urb_enqueue+0x218/0x68c) from [<c01eed00>] (usb_hcd_submit_urb+0x7ac/0x8c4)
[<c01eed00>] (usb_hcd_submit_urb+0x7ac/0x8c4) from [<c01edc30>] (usb_hcd_giveback_urb+0x70/0xb8)
[<c01edc30>] (usb_hcd_giveback_urb+0x70/0xb8) from [<c01fa72c>] (finish_urb+0x7c/0xb8)
[<c01fa72c>] (finish_urb+0x7c/0xb8) from [<c01fbddc>] (finish_unlinks+0x168/0x2b8)
[<c01fbddc>] (finish_unlinks+0x168/0x2b8) from [<c01fe288>] (ohci_irq+0x438/0x4e4)
[<c01fe288>] (ohci_irq+0x438/0x4e4) from [<c01ed72c>] (usb_hcd_irq+0x38/0x88)
[<c01ed72c>] (usb_hcd_irq+0x38/0x88) from [<c0076068>] (handle_IRQ_event+0x24/0xe0)
[<c0076068>] (handle_IRQ_event+0x24/0xe0) from [<c00779a0>] (handle_level_irq+0xbc/0x13c)
[<c00779a0>] (handle_level_irq+0xbc/0x13c) from [<c0029070>] (asm_do_IRQ+0x70/0x94)
[<c0029070>] (asm_do_IRQ+0x70/0x94) from [<c0033248>] (__irq_svc+0x48/0xa0)
Exception stack(0xc0395f78 to 0xc0395fc0)
5f60:                                                       00000000 00000000
5f80: c0395fc0 00000000 c0394000 c039925c c03ba3a4 c05f2900 500212f4 410fb766
5fa0: 5002128c 00000000 cfb96044 c0395fc0 c00348c0 c00346dc 60000013 ffffffff
[<c0033248>] (__irq_svc+0x48/0xa0) from [<c00346dc>] (default_idle+0x14/0x18)
[<c00346dc>] (default_idle+0x14/0x18) from [<c00348c0>] (cpu_idle+0x40/0x8c)
[<c00348c0>] (cpu_idle+0x40/0x8c) from [<c00089ec>] (start_kernel+0x270/0x2c8)
[<c00089ec>] (start_kernel+0x270/0x2c8) from [<50008034>] (0x50008034)

这是我写USB鼠标驱动是出现的错误信息,BUG后面写的是出现错误的原因,然后后面的一大坨恐怖的东西原来是内核的堆栈信息,仔细看一下就会知道函数调用顺序了,

unwind_backtrace -> __kmalloc -> ohci_urb_enqueue -> usb_hcd_submit_urb -> usb_hcd_giveback_urb -> finish_urb ... 等等。

 

终于找到了错误原因了,原来是在鼠标中断处理函数sb_mouse_irq中调用这个函数的参数应该是这样的usb_submit_urb (urb, GFP_ATOMIC);

而不能用韦东山视频中的usb_submit_urb(uk_urb, GFP_KERNEL);

 

关于这两个宏的解释只找到了英文版的:

GFP_ATOMIC means roughly "make the allocation operation atomic(原子操作)".  This
means that the kernel will try to find the memory using a pile of free
memory set aside for urgent allocation.  If that pile doesn't have
enough free pages, the operation will fail.  This flag is useful for
allocation within interrupt handlers.

GFP_KERNEL will try a little harder to find memory.  There's a
possibility that the call to kmalloc() will sleep while the kernel is
trying to find memory (thus making it unsuitable for interrupt
handlers).  It's much more rare for an allocation with GFP_KERNEL to
fail than with GFP_ATOMIC.

In all cases, kmalloc() should only be used allocating small amounts of
memory (a few kb).  vmalloc() is better for larger amounts.

Also note that in lab 1 and lab 2, it would have been arguably better to
use GFP_KERNEL instead of GFP_ATOMIC.  GFP_ATOMIC should be saved for
those instances in which a sleep would be totally unacceptable.

This is a fuzzy issue though...there's no absolute right or wrong
answer.

这也解释了为什么会出现这个错误提示 BUG: sleeping function called from invalid context at mm/slub.c:795

转载于:https://www.cnblogs.com/cxd2014/p/4495452.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值