Saturday, October 13, 2012

Loops per jiffy

System timer interrupt the CPU at pre-set frequency specified by the variable HZ in Linux. There is trade off in choosing a value for HZ. Too short the interval resulted in excessive switching which means higher overhead and power consumption. Too long the interval reduce the granularity of the scheduler resolution. The value for HZ is hardware architecture dependent. On x86, it used to be 100 in 2.4 kernels by default. It was changed to 1000 in 2.6 kernels but lowered to 250 in 2.6.13.

Jeffies holds the numner of tomes the system timer jas popped since system boot. Jeffies is incremented HZ time by the system every second.

During boot, the Linux kernel calculates the number of times the CPU can execute an internal delay loop in one jiffy (consecutive ticks of the system timer). The result depends on the speed of the CPU and is stored in a variable called loops_per_jiffy. This value is used to delay execution (wait) for a small duration (microseconds).

In kernel, delays in order of jiffies are considered long wait. To ensure sleep-wait for such long duration, use schedule_timeout(), wait_event_timeout() and msleep() functions. These functions cannot be used in interrupt context as interrupt handler cannot issue schedule() or sleep. Busy-wait for short period is possible for interrupt context.

Delays in sub-jiffy duration is considered as short delay. Such delays are common for both process and interrupt contexts. Because it is not possible to use jiffy-based methods to implement sub-jiffy delays, the only way is to use busy-wait. Kernel API for short dalays are mdela(), udelay() and ndelay() (for milli-, micro and nano- durations). These API uses loop_per_jiffy to calculate the number of loop requires to achieve the desired delay duration.