新闻| 论坛| 博客| 在线研讨会
Linux-2.6.21 S3c6400中断剖析之六 (原创)-上海嵌入式索漫科技培训教材
xiajiashan| 2012-10-10 14:35:50 阅读:2723 发布文章

作者:下家山(请尊重原创,转载请注明) http://www.xiajiashan.com

五.客户出现的问题 5.1 现象(软件锁和网络超时)

客户在用我们发布的驱动测试时出现

“BUG: soft lockup detected on CPU#0!”并伴随有“NETDEV WATCHDOG: eth0: transmit timed out”现象出现

我们拿到客户的板子后测试发现,在ping的时候很难出现上述问题,而在用iperf工具测试时,马上就会出现(几秒钟),而且是在TX时候出现(RX正常)。

虽然出现两个现象,大部分是先出现“BUG: soft lockup detected on CPU#0!”,再出现“NETDEV WATCHDOG: eth0: transmit timed out”。(有时候是先出现“NETDEV WATCHDOG: eth0: transmit timed out”再出现“BUG: soft lockup detected on CPU#0!”)

5.2 什么是软件锁和网络超时

先来说说“BUG: soft lockup detected on CPU#0!”。

网上有人说这个不算bug,只要你的系统io,或者某个服务10秒内都没反应,就会出

现这个信息。而且这个信息是可忽略的,它只是提醒你某个地方占用CPU时间太长,需要注意。但是,我们这里却不可忽略,因为OS都down掉了。

在我看来“NETDEV WATCHDOG: eth0: transmit timed out”这个错误还是“BUG: soft lockup detected on CPU#0!”带来的(即使是“NETDEV WATCHDOG: eth0: transmit timed out”这个错误先出现)。因为,当CPU检测到某个线程占用CPU时间超过10秒并报告“BUG: soft lockup detected on CPU#0!”时,那么网络传输肯定会超时即会报告“NETDEV WATCHDOG: eth0: transmit timed out”(因为网络传输超时时间设置的是20ms)。

疑问:既然网络超时时间比软件锁(soft lockup)要短,为什么大部分时间是先出现软件锁错误信息再出现网络超时信息呢?

5.3 问题是由什么引起的

这样两个问题,也许都是因为系统阻塞造成的。

最初,我们一直怀疑我们的驱动有问题,因为我们的kernel是客户提供的,6400的BSP也是客户提供的,我们没有理由去怀疑linux-2.6.21不够稳定,也没有理由去怀疑samsung的BSP有问题,因为6400已经用到了ipone 上面,更让我们肯定的是ping正常。

既然是系统阻塞,我们最先怀疑是我们驱动中,特别是在IO部分的while 语句造成

(因为做实验发现while(1)也会出现“BUG: soft lockup detected on CPU#0!”)。

取消一切while等语句,用if else delay()语句组合来取代。经调试,问题依然。

我们针对驱动 一条一条语句的查,反复配置各个SPI寄存器,但并无改善。因问题只在发送部分,所以我们又怀疑我们的发送进程和队列有问题。于是,我们换到

驱动版本,这个版本不涉及到队列问题,也不行。

驱动中用到了很多自旋锁spin_lock_init,这也是容易发生阻塞的地方,但屏蔽驱动中所有的自旋锁语句,情况并无改善。

最后出问题的地方似乎只有发送进程方面了。

驱动发送进程有两条线:

我们分别在进出两个进程的地方加了定时器,看这两个进程执行的时间。但并没有规律,即很短的时候也会出现问题而很长的时候却没有问题。

上面的调试,我们都是用的polling 方式,但在这种方式下各种可能性都调试并没有找到问题的原因。

于是,我们想到换成 DMA或interrupt方式。

但是,在用DMA调试时总是提示client already has channel,因为客户之前给我们的内核DMA部分没有基于2410,引入了subchannel,但跟到内核里面去,感觉其DMA对subchannel的计算上好像有问题,因此也没有调下去。

再后来,改到interrupt方式。

但是,中断方式调试驱动出现下面的现象:

如不注册外部中断,驱动下载正常,反之,下载出问题。

到了这里,感觉应该是中断之间干扰(因为SPI采用中断方式后,就注册了SPI中断和外部中断两个中断)。

但是,我们的驱动代码已经应用在几个客户上,改动的地方只是跟SPI有关的几个寄存器。况且我们也实在查不到我们驱动的问题。似乎不跳出原来的思维很难找到问题所在。后来跟到内核中断部分去了,发现其代码好像有点问题(主要参考2410部分的中断),于是对其进行了改动,并在polling上再次调试,发现问题解决了,后来,用interrupt方式调试也没有问题了。

5.4当外部中断发生后samsung bsp是怎么处理的?

当外部中断发生后,OS是这样做的:

linux-interrupt.jpg

5.5这样做会有什么问题?

当中断发生后,samsung首先是清pending位(同时打开中断),然后又打开中断,再执行中断服务程序,最后又清pending位(同时打开中断)。这样做会有什么问题呢?

要回答这个问题首先要搞清楚pending的意义。

S3c6400中有个寄存器叫EINT0PEND(这里只针对外部中断):

linux-interrupt1.jpg

按照字面的理解,是悬而未决的意思。每个外部中断对应到这个寄存器中的一位:

linux-interrupt2.jpg

当这个寄存器某个位为1表示,该位对应的外部中断发生。更准确的说是当某个外部中断发生,该外部中断对应的EXTPEND位会置1。CPU 则根据这个位去处理对应的中断函数(或者说OS通过某种机制去处理对应的中断函数,我感觉这样描述也不够准确,OS是怎么去排队这些中断的呢?是根据优先级还是中断发生的先后顺序?),处理完后就清0(表示悬而已决)。

再来看中断发生后,OS的执行流程:

Pending->执行中断服务函数->Pending。这里在中断服务程序执行前就清掉了EXTPEND位。问题就出在这里。

中断服务函数还未执行,其EXTPEND相关位就被清掉了,这会让CPU(或者说OS)误以为中断服务函数已处理完毕,可以执行下一个中断服务程序。但,实际上不是这样。

所以,只要把中断服务程序执行前的那个pending动作去掉就OK了。

5.6 ping为什么没有问题

要解释这个问题还得接着刚才的分析。

Ping和iperf的本质区别是:ping程序发送的数据量小(确切的说是中断频率小);而iperf程序发送的数据量大(更确切的说是中断频率快)。

Pending->执行中断服务函数->Pending

当ping开始->外部中断发生->EXTPEND相关位置位->pending(清相关位,中断函数并未执行完毕)->执行中断服务函数(因为数据量小,中断函数很快执行完毕,即第二个中断还没来得及发生,明白这点很重要)->pending(清相关位,中断函数真正执行完毕)。

因此,ping程序一般没有什么问题。

5.7 iperf为什么频频出现问题

Pending->执行中断服务函数->Pending

当iperf开始->外部中断发生->EXTPEND相关位置位->pending(清相关位,中断函数并未执行完毕)->执行中断服务函数(因为数据量大,中断函数需要一段时间才能执行完成,即第二个中断已经到来了第一个中断函数还没有执行完毕,明白这点很重要)->pending(清相关位,中断函数真正执行完毕)。

因此,第一个中断函数未执行完毕而又去执行第二个中断函数,更严重的是第二个中断函数未执行完毕第三个中断又来了,这样越积越多,从而让OS感觉CPU一直停留在执行第一中断函数上,于是很快就会出现“BUG: soft lockup detected on CPU#0!”。

5.8 第一中断没有执行完毕第二个中断为什么会发生

因为在第一中断函数执行前,samsung bsp不但清掉了对应中断的EXTPEND位,而且打开了中断(清对应的EXTMASK位)。

5.9 为什么RX没有问题

RX与TX针对外部中断来说,RX是被动的,TX是主动的。TX不管CPU的接受能力。而RX在卡片(首先是卡片接受到数据,然后通过外部中断告诉CPU)端已经把流量降下来了,即根据自身的接受能力进行了调节。

结束

至此,有关Linux-ARM中断介绍完毕,欢迎交流!

2009-2-13 下家山 写于上海.漕河泾

有什么问题可以给我邮件ximenpiaoxue4016@sina.com或加我群198204885

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
02年接触ARM和ucos,开发过有线和无线图像报警器,IPCamera,人脸识别系统,OCR识别系统,指纹识别系统,05年开始从事Linux及Rtems下WiFi,camera,Ethernet等驱动开发工作,专做嵌入式linux培训,致力于把我十年来的研发经验传授给每一个学员,招人的可以找我,ximenpiaoxue4016@sina.com
推荐文章
最近访客