"); //-->
作者:下家山(请尊重原创,转载请注明) 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是这样做的:
5.5这样做会有什么问题?
当中断发生后,samsung首先是清pending位(同时打开中断),然后又打开中断,再执行中断服务程序,最后又清pending位(同时打开中断)。这样做会有什么问题呢?
要回答这个问题首先要搞清楚pending的意义。
S3c6400中有个寄存器叫EINT0PEND(这里只针对外部中断):
按照字面的理解,是悬而未决的意思。每个外部中断对应到这个寄存器中的一位:
当这个寄存器某个位为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
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。
eleaction01 阅读:4490