【发布时间】:2013-04-07 14:56:39
【问题描述】:
在Linux单处理器系统中,定时器中断是否与系统处于内核模式或用户模式无关?
当系统处于内核模式时,定时器中断有什么不同的行为吗?
【问题讨论】:
标签: linux linux-kernel linux-device-driver
在Linux单处理器系统中,定时器中断是否与系统处于内核模式或用户模式无关?
当系统处于内核模式时,定时器中断有什么不同的行为吗?
【问题讨论】:
标签: linux linux-kernel linux-device-driver
简单的答案是硬件时钟中断服务程序的执行和动态定时器处理程序的调度都不受硬件时钟中断之前系统所处的模式的影响。原因是时钟定时器中断是一个立即服务的硬件中断,不管执行是在内核还是用户上下文(假设定时器中断是启用的),而时钟定时器中断的中断服务程序它本身会引发运行动态计时器处理程序的软件中断。
警告:1)我实际上并没有通过经验证明这一点。 2) 这不适用于无滴答内核或高分辨率计时器。
Linux 内核代码使用“计时器”这个词来表示几个不同的东西:
硬件时钟或滴答计时器
在使用硬件时钟提供“滴答”的系统上,时钟定时器中断是一个依赖于架构的硬件中断。例如,在arch/powerpc/kernel/head_booke.h 中查找“timer_interrupt”,然后在arch/powerpc/kernel/time.c 中查看中断服务例程(ISR)timer_interrupt 实现。此 ISR 在发生定时器中断时立即执行,而与当前执行上下文无关。但是,此硬件中断与其他硬件中断的不同之处在于,当它返回时,处理不会返回到先前的上下文。而是输入调度程序。
对于设置为每秒产生 1000 个时钟中断的系统,在处理其他中断时,有时可能会屏蔽时钟中断。这通常被称为“丢失滴答声”问题。如果不补偿丢失的刻度,加载的系统可能会减慢时间感。在某些架构上,内核通过使用更细粒度的硬件增量计数器来补偿丢失的滴答声,每个时钟定时器中断都会读取并记录其值。通过比较当前tick的增量计数器值和前一个tick的增量计数器值,内核可以判断一个tick是否丢失。
软件计时器
已过期的动态计时器的动态计时器处理程序列表(您使用linux/timer.h 设置的类型)在时钟计时器中断结束时设置,在它返回之前。顺序是(大约):
[arch dependent]:timer_interrupt( )
kernel/time/tick-common.c:tick_handle_periodic( )
kernel/time/tick-common.c:tick_periodic( )
kernel/timer.c:update_process_times( )
kernel/timer.c:run_local_timers( )
kernel/softirq.c:raise_softirq(TIMER_SOFTIRQ)
我省略了将timer_interrupt 的处理程序设置为tick_handle_periodic 和TIMER_SOFTIRQ 的处理程序的初始化。
对raise_softirq(TIMER_SOFTIRQ) 的调用会生成一个立即处理的软件中断。中断的 ISR 运行动态定时器队列。计时器处理程序在 softirq 上下文中运行,并启用了硬件中断。当 ISR 返回时,调度程序被调用。这意味着如果设置了很多计时器,那么运行队列中的下一个进程将被延迟。
如果丢失滴答声,则计时器处理程序的执行可能会延迟,但是,延迟不取决于运行时钟计时器中断之前的执行情况。
关于动态计时器准确性的注意事项
"...内核无法确保计时器函数在其到期时间正确启动。它只能确保它们在适当的时间或延迟最多几百毫秒后执行。" 了解 Linux 内核,Bovet 和 Cesati,第 3 版,O'reilly。
因此,如果您需要更好的计时器精度,则需要使用高分辨率计时器。
【讨论】: