In a Linux uni-processor system, is timer interrupt independent of whether system is in kernel mode or user mode?
Is there any different behavior for the timer interrupt while system is in kernel mode?
The simple answer is that neither the execution of the hardware clock interrupt service routine, nor the scheduling of the dynamic timer handlers are affected by the mode the system was in before the hardware clock interrupt. The reason is that the clock timer interrupt is a hardware interrupt that is serviced immediately, regardless of whether the execution is in kernel or user context (assuming that the timer interrupt is enabled that is), and the interrupt service routine for the clock timer interrupt itself raises the software interrupt that runs the dynamic timer handlers.
Caveat: 1) I haven't actually proved this empirically. 2) This does not apply to tickless kernels or highres timers.
The Linux kernel code uses the word "timer" to mean several different things:
The hardware clock or tick timer
On systems that use a hardware clock to provide the "tick", the clock timer interrupt is an architecture dependent hardware interrupt. For example, look for "timer_interrupt" in arch/powerpc/kernel/head_booke.h and then see the interrupt service routine (ISR) timer_interrupt
implementation in arch/powerpc/kernel/time.c. This ISR executes immediately when the timer interrupt occurs, regardless of current execution context. This hardware interrupt differs from other hardware interrupts though, in that when it returns, processing does not return to the prior context. Instead, the scheduler is entered.
For a system that is set to produce 1000 clock interrupts per second, there is a chance that clock interrupts will sometimes be masked when other interrupts are being serviced. This is usually called the "lost ticks" problem. Without compensating for lost ticks, a loaded system could have a slowed sense of time. On some architectures the kernel compensates for lost ticks by using a finer grained hardware increment counter, whose value is read and recorded every clock timer interrupt. By comparing the increment counter value of the current tick against the increment counter value of the previous tick, the kernel can tell if a tick has been lost.
The software timers
The list of dynamic timer handlers (the type you set with the linux/timer.h
) of dynamic timers that have expired is set at the end of the clock timer interrupt, before it returns. The sequence is (approximately):
[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)
I have omitted the initialilzations that set the handler for the timer_interrupt
to tick_handle_periodic
, and the handler for TIMER_SOFTIRQ
.
The call to raise_softirq(TIMER_SOFTIRQ)
generates a software interrupt that is serviced immediately. The ISR for the interrupt runs the dynamic timer queue. The timer handlers run in softirq context, with hardware interrupts enabled. When the ISR returns, the scheduler is called. This means that if there are a lot of timers set, whatever process happens to be next in the run queue will be delayed.
If there were lost ticks, then the execution of the timer handlers could be delayed, however, the delay does not depend on the contect of execution prior to running the clock timer interrupt.
Note about dynamic timer accuracy
"...the kernel cannot ensure that timer functions will start right at their expiration times. It can only ensure that they are executed either at the proper time or after with a delay of up to a few hundred milliseconds." Understanding the Linux Kernel, Bovet and Cesati, 3rd edition, O'reilly.
So, if you need better timer accuracy, you need to use highres timers.
References: Software interrupts and realtime
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With