preempte_count中的HARDIRQ_OFFSET和NMI_OFFSET有什么用
看了一下preempt_count的组成,对其中2个统计不是很清楚:HARDIRQ_OFFSET(10个bit):统计硬中断嵌套层数
NMI_OFFSET(1个比特):不知道有什么用
想请教一下,这2个有什么用,为什么要统计这2个东西,而且统计嵌套层数为何是放在进程thread_info里面? HARDIRQ_OFFSET:统计硬中断嵌套层数
我知道其中的一个作用,当执行完中断上半部的时候,这时候会去检查是否有中断嵌套,如果有的话就直接返回到被嵌套的中断中,如果没有的话,会去检查软终端是否被pending
NMI_OFFSET好像和抢占有关系,不确定
这种计数信息放在哪我觉得就是实现的问题,只是借用了当前的进程的空间 回复 1# wLiu2007
其实这理解这个事情没有这么难。
首先,从整体来说,preempt_count() 不为零就不允许内核抢占。
其次,每一个字段都有对应的xxx_count和in_xxx函数,要想知到为什么要加这个字段,搜索一下这些函数在那使用,就什么都明白了。
软中断的执行时机有好几个,其中从硬中断去的路径为:irq_exit->invoke_softirq(), 看的是in_interrupt(),也就是说如果在存在硬中断、或软中断中,都不会调用软中段处理函数。
再就是NMI的计数,因为有很多的流程是不能在NMI环境下执行的,所以要进行记录。如
http://lxr.free-electrons.com/source/kernel/trace/trace.c#L568:
562 void tracing_snapshot(void)
563 {
564 struct trace_array *tr = &global_trace;
565 struct tracer *tracer = tr->current_trace;
566 unsigned long flags;
567
568 if (in_nmi()) {
569 internal_trace_puts("*** SNAPSHOT CALLED FROM NMI CONTEXT ***\n");
570 internal_trace_puts("*** snapshot is being ignored ***\n");
571 return;
572 }
回复 3# Tinnal
有个概念想请教一下
NMI 不可屏蔽中断,是指就算通过local_irq_disable手段也不能屏蔽的硬中断吗?它和普通硬中断一样,只不过它不能通过写寄存器方式将它disable掉,只要中断发生了,就会调用相应的中断处理程序;
这个应该需要特定的硬件支持吗? 并不是所有的硬件都有NMI这个东西,对于普通的芯片比如arm9 所有的中断都是可以屏蔽的,不存在NMI?
回复 4# wLiu2007
对的。ARM没有真正意义的NMI,X86有。不过ARM有两种中断类型,IRQ或FIQ,他们两个的屏蔽位是不同的,而Linux只用户的IRQ,因此可以拿FIQ当NMI来用。我们公司就拿FIQ作咬狗后的临终遗言收集,以定位咬狗原因。
回复 5# Tinnal
谢谢!
NMI为什么只有1个bit,这种中断不能中断嵌套吗?
Tinnal 发表于 2014-08-12 21:25 static/image/common/back.gif
回复 4# wLiu2007
对的。ARM没有真正意义的NMI,X86有。不过ARM有两种中断类型,IRQ或FIQ,他们两个的屏 ...
请问Tinnal兄:“我们公司就拿FIQ作咬狗后的临终遗言收集,以定位咬狗原因。”
这个是个啥思路,FIQ由谁来触发? wLiu2007 发表于 2014-08-13 12:39 static/image/common/back.gif
回复 5# Tinnal
谢谢!
NMI是硬件上提供的独立中断,不能屏蔽由硬件实现。
Linux中中断默认不嵌套。。。 humjb_1983 发表于 2014-08-13 12:51 static/image/common/back.gif
请问Tinnal兄:“我们公司就拿FIQ作咬狗后的临终遗言收集,以定位咬狗原因。”
这个是个啥思路,FIQ由谁 ...
由狗来触发,我们的狗是由CPLD在管控的,如果饿狗了,CPLD会等立马给CPU发送一个信号,让CPU收集必要的维测信息,并在100ms后拉低复位线复位CPU。这个信号一定要保证不受软件当前状态影响,因此需要采用NMI的方式进行通告。
而ARM上是没有NMI的,因此采用FIQ代替NMI的功能。因为FIQ标准内核是不会用的,因此是不会被屏蔽的。 回复 6# wLiu2007
humjb_1983对得对,NMI是不允许嵌套的。从内核代码就可以再次认证这一点。
62 #define nmi_enter() \
63 do { \
64 lockdep_off(); \
65 ftrace_nmi_enter(); \
66 BUG_ON(in_nmi()); \
67 preempt_count_add(NMI_OFFSET + HARDIRQ_OFFSET); \
68 rcu_nmi_enter(); \
69 trace_hardirq_enter(); \
70 } while (0)
检测到重入内核就BUG_ON!
页:
[1]
2