wLiu2007 发表于 2014-08-12 17:57

preempte_count中的HARDIRQ_OFFSET和NMI_OFFSET有什么用

看了一下preempt_count的组成,对其中2个统计不是很清楚:
HARDIRQ_OFFSET(10个bit):统计硬中断嵌套层数
NMI_OFFSET(1个比特):不知道有什么用

想请教一下,这2个有什么用,为什么要统计这2个东西,而且统计嵌套层数为何是放在进程thread_info里面?

super皮波 发表于 2014-08-12 20:03

HARDIRQ_OFFSET:统计硬中断嵌套层数
我知道其中的一个作用,当执行完中断上半部的时候,这时候会去检查是否有中断嵌套,如果有的话就直接返回到被嵌套的中断中,如果没有的话,会去检查软终端是否被pending
NMI_OFFSET好像和抢占有关系,不确定

这种计数信息放在哪我觉得就是实现的问题,只是借用了当前的进程的空间

Tinnal 发表于 2014-08-12 21:02

回复 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         }
   

wLiu2007 发表于 2014-08-12 21:12

回复 3# Tinnal

有个概念想请教一下
NMI 不可屏蔽中断,是指就算通过local_irq_disable手段也不能屏蔽的硬中断吗?它和普通硬中断一样,只不过它不能通过写寄存器方式将它disable掉,只要中断发生了,就会调用相应的中断处理程序;

这个应该需要特定的硬件支持吗? 并不是所有的硬件都有NMI这个东西,对于普通的芯片比如arm9 所有的中断都是可以屏蔽的,不存在NMI?
   

Tinnal 发表于 2014-08-12 21:25

回复 4# wLiu2007

对的。ARM没有真正意义的NMI,X86有。不过ARM有两种中断类型,IRQ或FIQ,他们两个的屏蔽位是不同的,而Linux只用户的IRQ,因此可以拿FIQ当NMI来用。我们公司就拿FIQ作咬狗后的临终遗言收集,以定位咬狗原因。
   

wLiu2007 发表于 2014-08-13 12:39

回复 5# Tinnal

谢谢!

NMI为什么只有1个bit,这种中断不能中断嵌套吗?

   

humjb_1983 发表于 2014-08-13 12:51

Tinnal 发表于 2014-08-12 21:25 static/image/common/back.gif
回复 4# wLiu2007

对的。ARM没有真正意义的NMI,X86有。不过ARM有两种中断类型,IRQ或FIQ,他们两个的屏 ...
请问Tinnal兄:“我们公司就拿FIQ作咬狗后的临终遗言收集,以定位咬狗原因。”
这个是个啥思路,FIQ由谁来触发?

humjb_1983 发表于 2014-08-13 12:52

wLiu2007 发表于 2014-08-13 12:39 static/image/common/back.gif
回复 5# Tinnal

谢谢!

NMI是硬件上提供的独立中断,不能屏蔽由硬件实现。
Linux中中断默认不嵌套。。。

Tinnal 发表于 2014-08-13 20:28

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标准内核是不会用的,因此是不会被屏蔽的。

Tinnal 发表于 2014-08-13 20:38

回复 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
查看完整版本: preempte_count中的HARDIRQ_OFFSET和NMI_OFFSET有什么用