DDD 2010年01月04日 星期一 16:02 | 2347次浏览 | 6条评论
为解决这个
比如说
A: BUG现象 & 重现步骤
mti_malta32_34k(mips) 在使用kgdboe连接后,系统就给挂住了.
System hang when make kgdb connection on mti_malta32_34k target.
1): Using kgdboe connection to target.
2): After connect success, enter "c" to continue system
3): The target have no response and can't ping to it.
B: BUG现场分析 & 查找触发原因
由于系统给挂住了,所以第一步我们需要先弄清楚是什么引起系统悬挂.
有很多原因可以导致系统悬挂比如: cpu在spin_lock锁或者当前cpu中断没有开启等.
B.1: 查找系统悬挂原因
判断当前cpu中断是否被开启,这里我们可以拿timer中断来判断下。如果能响应timer中断,那说明当前cpu的中断没有显示关闭。
由于softlockup是采用timer中断来实现的,所以我就借花献佛,在kernel/softlockup.c里加了一些检测timer中断代码。
经过测试,发现所有的cpu都能正常响应timer中断,并且从dump_stack() 打印的活跃的堆栈信息来看,没有哪个cpu在等待锁。
因此从上面的信息可以推断系统是"正常"的.
通过如上实验,我们可以推测系统"中断"是正常的,cpu也没有spin_lock锁,那系统悬挂原因还得继续深究下去.
B.2: 初步找到系统悬挂 --> 网卡问题
由于target不能被ping通,并target的文件系统是通过nfs mount上的,所以很有可能是网卡的问题,导致没有网络服务,因而系统给hang住了.
我在网卡的中断处理函数里加了一些检测语句,果然,在系统hang后,网卡中断处理函数再也没有被调用,看起来好像是网卡出问题了.
B.3: 网卡出问题了??
mti_malta32_34k 这块板子使用的是AMD pcnet32网卡,这种PCI网卡比较常见的,在普通PC上也用得比较多。
从上面的实验来看,网卡中断没有被发出,所以第一个感觉是程序在哪里设置错了网卡中断控制器。
在去找网卡datasheet之前,我先hack了把代码,使用轮询模式去操纵网卡(简单的采用netpoll的函数),发现网卡能够正常工作的.这也表明网卡硬件是正常的。
确保不是硬件问题后,就放心的去死嗑了pcnet32的datasheet.
datasheet上说: RINT Receive Interrupt 产生要求满足如下条件:
When CSR0:RINT is set, INTA is asserted if CSR0:IENA is 1 and the mask bit RINTM (CSR3, bit 10) is 0.
其中:
CSR0: Controller Status and Control Register:
CSR3: Interrupt Masks and Deferral Control:
从上面可以了解到 INTA 中断触发需要的条件是
CSR0:RINT = 1 && CSR0:IENA = 1 && CSR3:RINTM = 0
既然是这样,由于网卡硬件没问题(轮询模式可以正常工作),所以我们只要满足它触发中断的条件,cpu那边就应该可以响应的。
所以又hack了把网卡驱动代码,强制的设置了那几个寄存器的值,然后静静的等待网卡中断的发生.
很可惜,还是没有发生.理论上说网络已经是可以正常的了,如果是硬件问题,这也不应该,pcnet32网卡是比较常用的,
现在只能把问题转移到中断控制器,很有可能是中断控制器没有把网卡中断传递给cpu,要真是这样的话,那麻烦可就大了...
头晕中...
B.4: mti_malta的中断控制器
由于与中断控制器相关的代码太偏底层了,看得我头晕呼呼的,看了半天也没头绪,以我目前的水平和知识面,要去真的弄懂这些,可得要一段时间。
但一般像这样的代码改动是比较少的,我对比了下代码,从2.6.21-2.6.27,mti_malta的i8259a的中断控制器的代码基本就没怎么真正改动过。
我随即编译了一个2.6.27的mti_malta内核,发现这个问题已经解决了,这可让我抓喜若狂。
我查看了一下2.6.21到2.6.27的i8259a的补丁.终于找到了问题的root cause.
具体原因我就不在写了,况且这和kgdb关系貌似不大了.
PS:我现在也还不是很懂那个什么smtc的..所以就不好在写下去了
C: BUG解决方法
root cause:
The system hanged due to the subsidiary device interrupts via i8259A
couldn't pass to system in some special causes on SMTC.
fix:
This patch was backported from mainline.
The commit is: c3a005f4b6a7752608e75d016ef8d07c55285e48
[MIPS] SMTC: Safety net for i8259A interrupts.
It will restore the Status.IM value associated with the i8259A
to ensure that the system could get always the subsidiary device
interrupts coing in via the i8259A.
--- a/arch/mips/mips-boards/malta/malta_int.c
+++ b/arch/mips/mips-boards/malta/malta_int.c
@@ -330,6 +330,18 @@ void __init arch_init_irq(void)
(0x100 << MIPSCPU_INT_I8259A));
setup_irq_smtc (MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
&corehi_irqaction, (0x100 << MIPSCPU_INT_COREHI));
+ /*
+ * Temporary hack to ensure that the subsidiary device
+ * interrupts coing in via the i8259A, but associated
+ * with low IRQ numbers, will restore the Status.IM
+ * value associated with the i8259A.
+ */
+ {
+ int i;
+
+ for (i = 0; i < 16; i++)
+ irq_hwmask[i] = (0x100 << MIPSCPU_INT_I8259A);
+ }
#else /* Not SMTC */
setup_irq (MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
setup_irq (MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
D: Others
为解决这个bug,前前后后忙了我整整一个星期。虽然最终的问题和kgdb关系不大,但我学到了不少东西, 比如说加深了系统中断的处理实现和mips的很多东西。 最重要的是我得到了我同事x.zhang大牛的指导和帮忙,在他的帮助下,我才得以如此顺利,站在巨人的肩膀上的感觉真好...
Zeuux © 2024
京ICP备05028076号
回复 劳永超 2010年01月09日 星期六 14:48
我
回复 DDD 2010年01月11日 星期一 14:41