【发布时间】:2017-06-08 16:21:48
【问题描述】:
我正在编写一个使用多个计时器的程序。每 5 秒,他们将使用一个相同的网络链接与用户空间进行通信。
更具体地说,每个计时器每 5 秒调用一次 func(),func() 将执行锁定、发送信息、解锁以及:
delay_us(200);
if(!timer_pending(&timer1)){
mod_timer(&timer1, jiffies+RTL_SECONDS_TO_JIFFIES(5));
}
奇怪的是在极少数情况下,系统会在mod_timer()内部崩溃,我反汇编发现它在tne zero,v0,0xc崩溃
这段代码(MIPS 指令)如下:
/*
* This is a common optimization triggered by the
* networking code - if the timer is re-modified
* to be the same thing then just return:
*/
if (timer_pending(timer) && timer->expires == expires)
800216bc: 8e020000 lw v0,0(s0)
800216c0: 50400005 beqzl v0,800216d8 <mod_timer+0x98>
800216c4: 8e020010 lw v0,16(s0)
800216c8: 8e020008 lw v0,8(s0)
800216cc: 10510042 beq v0,s1,800217d8 <mod_timer+0x198>
800216d0: 24130001 li s3,1
800216d4: 8e020010 lw v0,16(s0)
800216d8: 2c420001 sltiu v0,v0,1
800216dc: 00020336 tne zero,v0,0xc
调试非常痛苦。我怀疑计时器比赛,但从技术上讲,如果是这样,崩溃不应该在mod_timer() 内,对吗?看起来很可能会发生某种比赛,但这超出了我的知识范围。感谢您提出任何调试建议。
编辑:我只是在下面添加一些重要的转储消息:
Call Trace:
[<800243a4>] mod_timer+0x9c/0x1b8
[<8002399c>] call_timer_fn+0x20/0x88
[<80023bd0>] run_timer_softirq+0x1cc/0x244
[<8001de80>] __do_softirq+0x118/0x218
[<8001e05c>] do_softirq+0x58/0x78
[<8001e0e0>] irq_exit+0x64/0x80
[<8000044c>] ret_from_irq+0x0/0x4
[<800036cc>] __copy_user_common+0x44/0x2b8
[<8006701c>] file_read_actor+0x9c/0x114
[<8006a47c>] generic_file_aio_read+0x4f4/0x7f4
[<80092f00>] do_sync_read+0x90/0xd4
[<80093fc8>] vfs_read+0xb0/0x158
[<80094170>] SyS_read+0x60/0x9c
[<800017b0>] stack_done+0x20/0x40
Code: 24130001 8e020010 2c420001 <00020336> 02002021 0c008f12 27a50010 8e030000 10600015
编辑:回调函数如下:
void send_info(unsigned long task_priv)
{
unsigned long flags;
struct target_priv *priv = (struct target_priv *)task_priv;
SMP_LOCK(flags);
construct_netlink_send(priv);
SMP_UNLOCK(flags);
delay_us(200);
if ((!strcmp(priv->name, "timer0")) && (!timer_pending(&priv->timer0))){
mod_timer(&priv->timer0, jiffies+SECONDS_TO_JIFFIES(5));
return;
}
...//do same for the rest 9 timers
}
【问题讨论】:
-
什么是
delay_us? Linux内核中没有这个功能,你的意思是udelay()吗?至于错误调试:如果这是mod_timer中的错误,你应该报告它,而不是在这里发布。但很可能是您的代码中的一个错误(可能是因为种族)损坏计时器结构。几乎有无限种方法可以破坏 Linux 内核中的某些内部结构,因此如果没有完整的代码,我们不可能为您提供帮助。至于可能的调试方向 - 确定(使用崩溃报告)给定指令中的 exact 参数是错误的,并尝试在代码中跟踪它。 -
您好 Tsyvarev,感谢您的回复,代码的其他部分太长且无法发布(并且可能不相关)。 delay_us 是 udelay() ,我对它进行了封装。我知道在这里找到确切的解决方案是不可能的,所以任何猜测都会有很大帮助。从技术上讲,多个计时器可以共享同一个网络链接吗?
-
can multiple timer share same netlink?- 定时器的函数可以做原子上下文中允许的所有事情。由于不同计时器的函数可能并行运行,因此您需要适当的同步才能访问其中的相同对象。any guessing is greatly helping.- 猜猜你没有显示的代码有什么问题?这不是堆栈溢出的工作方式。不是每个编程问题都应该在这里问,有时你只需要调试你的代码。 -
@Tsyvarev 好的,我会记住这一点。谢谢。
标签: c linux-kernel linux-device-driver embedded-linux