解析内核错误信息

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