Naturally, the kernel is interested in providing good latency times even if kernel preemption is not
enabled. This can, for instance, be important in network servers. While the overhead introduced by
kernel preemption is not desired in such an environment, the kernel should nevertheless respond to
important events with reasonable speed. If, for example, a network request comes in that needs to be
serviced by a daemon, then this should not be overly long delayed by some database doing heavy I/O
operations. I have already discussed a number of measures offered by the kernel to reduce this problem:
scheduling latency in CFS and kernel preemption. Real-time mutexes as discussed in Chapter 5 also aid
in solving the problem, but there is one more scheduling-related action that can help.
Basically, long operations in the kernel should not occupy the system completely. Instead, they should
check from time to time if another process has become ready to run, and thus call the scheduler to select
the process. This mechanism is independent of kernel preemption and will reduce latency also if the
kernel is built without explicit preemption support.
The kernel has been carefully audited to find the longest-running functions, and calls to cond_resched
have been put in the appropriate places. This ensures higher responsiveness even without explicit kernel
preemption.
Following a long-time tradition for Unix kernels, Linux has supported task states for both interruptible
and uninterruptible sleeps. During the 2.6.25 development cycle, however, another state was added:
TASK_KILLABLE.35 Tasks in this state are sleeping and do not react to non-fatal signals, but can — in
contrast to TASK_UNINTERRUPTIBLE— be killed by fatal signals. At the time of writing, almost all places
in the kernel that would provide apt possibilities for killable sleeps are still waiting to be converted to the
new form.