首页 > kgdb抓虫日记 > kgdb抓虫日记 – kgdboe 与 system hang

kgdb抓虫日记 – kgdboe 与 system hang

2010年6月28日 发表评论 阅读评论

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 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的补丁.最终找到了解决问题的东西.
具体的我就不在写,况且这和kgdb关系貌似不大了.

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大牛的指导和帮忙,
在他的帮助下,我才得以如此顺利,站在巨人的肩膀上的感觉真好…

本文地址:
http://www.kgdb.info/kgdb-bugs-kgdboe-system-hang/
版权所有 © 转载时必须以链接形式注明作者和原始出处!

  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.