How time is updated when tick interrupts are disabled

In Understanding the Linux Kernel, there is paragram pasted below. It states why jiffies_64 is correct in long run even several timer interrupt are lost.

However, no tick is definitively lost, and in the long run, xtime
stores the correct system time. The check for lost timer interrupts is done in the
mark_offset method of cur_timer; (P240)

cur_timer points to the timer_hpet object: in this case, the HPET chip is the
source of timer interrupts. The mark_offset method checks that no timer
interrupt has been lost since the last tick; in this unlikely case, it updates
jiffies_64 accordingly. Next, the method records the current value of the
periodic HPET counter. (P237)

jiffies_64 is increased by one for each timer interrupt (a tick). So if timer interrupt is disabled for several ticks, jiffies_64 would not be able to increase for several times, thus lost track the time. So how to keep jiffies_64 updated while timer interrupt is disabled?

It's for sure jiffies_64 is not be updated when timer interrupt is disabled. So it may lost a few ticks temporarily.

But it will be corrected at next timer interrupt and it's done by cur_timer->mark_offset(). Remember mark_offset() records the *exact time* of last tick. It's worth to note that the *exact time* is not the time maintained by kernel, but it is maintained by timer chip. A timer chip is an *independent* chip which has a counter driven by its OWN clock and increase by one each clock. The chip's timer interrupt may be disabled, its counter keep increasing. And the *exact time* is not really a time, but the chip's *counter*! So in each timer interrupt, mark_offset() save timer chip's counter. Before saving counter, mark_offset() compare last time saved counter with current timer chip's counter to see if there is timer interrupt has been lost.

Suppose timer chip's counter is increased by one each time a timer interrupt is generated. So if no timer interrupt is lost, mark_offset() saved counter plus 1 should equal to current timer's counter at the time mark_offset() try to save chip's counter in timer interrupt handler. If not equal, then timer interrupt is lost, by comparing the difference between saved counter and chip's counter, we will know how many interrupts are lost. Since jiffies_64 is increased by one for each timer interrupt, we know how much need to be added to jiffies_64, thus updates jiffies_64 accordingly.

Please note the lost timer interrupt can only be found if timer chip has a counter. This is true for HPET but not true for PIT chip. For PIT chip, I guess it's lost.

reference in Understanding the Linux Kernel.
mark_offset() P233
jiffies_64 P234
xtime P235
mark_offset() in interrupt handler P237

also update it on stackoverflow.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章