免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 9391 | 回复: 1
打印 上一主题 下一主题

request_irq引发BUG: sleeping function called from invalid context at mm/slab.c [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-06-10 14:42 |只看该作者 |倒序浏览
最近在调试linux的console的时候,发现了一个问题:linux能够正常启动,但是dmesg的时候,看到如下oops信息.从oops信息来看,
这些信息的出现是由于kernel_init -> init_post -> sys_open((const char __user *) "/dev/console", O_RDWR, 0)而来的,然后调用到了
console驱动的open函数rs_open,rs_open调用了startup,在startup函数中又调用了request_irq函数:

retval = request_irq(state->irq, rs_interrupt_single, SA_RESTORER,"serial", &IRQ_ports[state->irq]);

但是很不明白,为什么这个request_irq语句就引起了oops错误,其他驱动注册的时候也调用了request_irq函数了阿,但都没有出现oops的错误!
而且,可恨的是,此处request_irq的调用引起了oops错误,但它的返回值居然是正确的,而且,console也可以正常使用!
请高手大概指点一下问题可能在哪里。

此内核版本linux-2.6.29,开发版不带mmu,内核是参照snapggear4.0.0移植的!
我一直怀疑是内核对nommmu的支持没有移植好,但是启动以后,console,网卡,串口都是ok的,应用程序本也基本都可以跑!

BUG: sleeping function called from invalid context at mm/slab.c:3201
in_atomic(): 0, irqs_disabled(): 128, pid: 1, name: swapper
[<000223bc>] (dump_stack+0x0/0x14) from [<0002fd68>] (__might_sleep+0xe0/0x104)
[<0002fc88>] (__might_sleep+0x0/0x104) from [<000783c0>] (kmem_cache_alloc+0x38/0x14
r5:00000006 r4:00dcc000
[<00078388>] (kmem_cache_alloc+0x0/0x14 from [<00060500>] (request_irq+0x8c/0xdc)
r7:002d0098 r6:00000080 r5:00000006 r4:00dcc000
[<00060474>] (request_irq+0x0/0xdc) from [<0014a348>] (startup+0xfc/0x300)
[<0014a24c>] (startup+0x0/0x300) from [<0014b8a0>] (rs_open+0x1e0/0x40
r8:00500001 r7:00000000 r6:00000000 r5:002dbbb4 r4:00315444
[<0014b6c0>] (rs_open+0x0/0x40 from [<00142b48>] (tty_open+0x2b4/0x3ec)
[<00142894>] (tty_open+0x0/0x3ec) from [<0007ed7c>] (chrdev_open+0x1a4/0x1cc)
[<0007ebd8>] (chrdev_open+0x0/0x1cc) from [<0007af60>] (__dentry_open+0x194/0x2a4)
[<0007adcc>] (__dentry_open+0x0/0x2a4) from [<0007b194>] (nameidata_to_filp+0x4c/0x64)
[<0007b148>] (nameidata_to_filp+0x0/0x64) from [<0008544c>] (do_filp_open+0x358/0x6ec)
r5:0035bf14 r4:00000000
[<000850f4>] (do_filp_open+0x0/0x6ec) from [<0007b38c>] (do_sys_open+0x60/0xa4)
[<0007b32c>] (do_sys_open+0x0/0xa4) from [<0007b3f4>] (sys_open+0x24/0x2
r8:00000000 r7:00000000 r6:0001b904 r5:0001b904 r4:002e4894
[<0007b3d0>] (sys_open+0x0/0x2 from [<0001e440>] (init_post+0x34/0x120)
[<0001e40c>] (init_post+0x0/0x120) from [<00008a14>] (kernel_init+0x114/0x164)
r4:002e4894
[<00008900>] (kernel_init+0x0/0x164) from [<0003ae40>] (do_exit+0x0/0x610)
r6:00000000 r5:00000000 r4:00000000

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2010-06-10 16:34 |只看该作者
查看内核代码,在mm/slab.c:3201685处的代码为:might_sleep();
在include/linux/kernel.h中,有对might_sleep的描述:
* might_sleep - annotation for functions that can sleep
*
* this macro will print a stack trace if it is executed in an atomic
* context (spinlock, irq-handler, ...).
只有在编译内核的时候选择了CONFIG_DEBUG_SPINLOCK_SLEEP或者CONFIG_DEBUG_PREEMPT,might_sleep才会起作用!
所以,一般的使用方法是:
在mm/slab.c中有一句:
might_sleep_if(flags & __GFP_WAIT);
#define might_sleep_if(cond) do { if (cond) might_sleep(); } while (0)
假如flags标记包含__GFP_WAIT,那么就表示要在原子上下文中用__GFP_WAIT标记来分配内存,这明显是不允许的,所以,打印出oops
目前还没有想到比较好的解决办法,这可能是内核的bug,我只能先把这个选项关闭!
但这确实是个bug,表示代码在原子上下文中休眠了!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP