Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 15: Time Management


The implementation of both functions is purely technical and not very interesting, their code need not be
discussed in detail.

To cancel a scheduled timer, the kernel offershrtimer_cancelandhrtimer_try_to_cancel.Thedif-
ference between both functions is thathrtimer_try_to_cancelprovides the extra return value−1if
the timer if currently executing and thus cannot be stopped anymore.hrtimer_cancelwaits until the
handler has executed in this case. Besides, both functions return 0 if the timer was not active, and 1 if it
was active, that is, if its status is eitherHRTIMER_STATE_ENQUEUEDorHRTIMER_STATE_PENDING.

Restarting a canceled timer is done withhrtimer_restart:

<hrtimer.h>
int hrtimer_cancel(struct hrtimer *timer)
int hrtimer_try_to_cancel(struct hrtimer *timer)
int hrtimer_restart(struct hrtimer *timer)

15.4.3 Implementation


After having introduced all required data structures and components, let’s fill in the last missing pieces
by discussing the mechanisms of how high-resolution timers are expired and their callback function run.

Recall that parts of the high-resolution timer framework are also compiled into the kernel even if explicit
support for them is disabled. Expiring high-resolution timers is in this case driven by a clock with low-
resolution. This avoids code duplication because users of high-resolution timers need not supply an
extra version of their timing-related code for systems that do not have high-resolution capabilities. The
high-resolution framework is employed as usual, but operates with only low resolution.

Even if high-resolution support is compiled into the kernel, only low resolution will be available at boot
time, so the situation is identical to the one described above. Therefore, we need to take two possibili-
ties into account for how high-resolution timers are run: based on a proper clock with high-resolution
capabilities, and based on a low-resolution clock.

High-ResolutionTimers in High-Resolution Mode


Let us first assume that a high-resolution clock is up and running, and that the transition to high-
resolution mode is completely finished. The general situation is depicted in Figure 15-13.

When the clock event device responsible for high-resolution timers raises an interrupt,
hrtimer_interruptis called as event handler. The function is responsible to select all timers
that have expired and either move them to the expiration list (if they may be processed in softIRQ
context) or call the handler function directly. After reprogramming the clock event device so that an
interrupt is raised when the next pending timer expires, the softIRQHRTIMER_SOFTIRQis raised. When
the softIRQ executes,run_hrtimer_softirqtakes care of executing the handler functions of all timers
on the expiration list.

Let’s discuss the code responsible to implement all this. First, consider the interrupt handler
hrtimer_interrupt. Some initialization work is necessary in the beginning:

kernel/hrtimer.c
void hrtimer_interrupt(struct clock_event_device *dev)
{
struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
Free download pdf