我一直在做一些模块工作,我发生了随机发生的崩溃(通常在启动后10小时内)。
内核日志消息可能因崩溃而异,但在某些情况下我会得到这个:
<4>huh, entered c90390a8 with preempt_count 0000010d, exited with c0340000?
生成此日志的代码来自2.6.14内核kernel / timer.c:
int preempt_count = preempt_count();
fn(data);
if (preempt_count != preempt_count()) {
printk(KERN_WARNING "huh, entered %p "
"with preempt_count %08x, exited"
" with %08x?\n",
fn, preempt_count,
preempt_count());
BUG();
}
要发生这种情况,必须发生什么事情(显然preempt_count已更改,但可能会导致这种情况发生?)
崩溃的另一个症状是我在从工作队伍中做i2c时看到scheduling while atomic
(当然不应该是原子的,对吧?)。可能导致这种情况的原因是什么?
我认为这篇文章是一个很长的镜头,但我真的只是在寻找任何可以解决的问题。
答案 0 :(得分:4)
刚才从头顶回答:“preempt_count”是一个32位字段,为了各种目的,它们被分成子位字段。 O'Reilly的了解Linux内核详细介绍了子位字段。再一次,在我的头顶,我不知道“c0340000”代表什么。但是既然你开始使用“0000010d”,并且应该以“0000010d”结束,那么无论你的定时器代码做了什么都搞砸了。
一个常见的原因是你的计时器代码做了类似spin_lock_bh()的事情,但是忘了做一个spin_unlock_bh()。但这通常会导致起始和结束preempt_count值之间只有1位差异。但在您的情况下,您的起始值和结束值会发生巨大变化。
迈克尔