Linux kernel system timer & jiffies

A large number of kernel functions are time driven. Time and time measurements are very important for the kernel to manage periodic events.the differences between events that occur periodically and events the kernel schedules for a fixed point in the future. Events that occur periodically say, every 10 milliseconds are driven by the system timer. The system timer is a programmable piece of hardware that issues an interrupt at a fixed frequency. The interrupt handler for this timer called the timer interrupt updates the system time and performs periodic work.

The hardware provides a system timer that the kernel uses to gauge the passing of time. This system timer works off of an electronic time source, such as a digital clock or the frequency of the processor. The system timer goes off (often called hitting or popping) at a pre-programmed frequency, called the tick rate. When the system timer goes off, it issues an interrupt that the kernel handles via a special interrupt handler.

Because the kernel knows the preprogrammed tick rate, it knows the time between any two successive timer interrupts. This period is called a tick and equals one-over-the-tick-rate seconds. This is how the kernel keeps track of both wall time and system uptime. Wall time the actual time of day is of most importance to user-space applications. The kernel keeps track of it simply because the kernel controls the timer interrupt. A family of system calls provide the date and time of day to user-space. The system uptime the relative time since the system booted is useful to both kernel-space and user-space. A lot of code must be aware of the passing of time. The difference between two uptime readings now and thesis a simple measure of this relativity.

The Tick Rate: HZ

The frequency of the system timer (the tick rate) is programmed on system boot based on a static preprocessor define, HZ. The value of HZ differs for each supported architecture. In fact, on some supported architectures, it even differs between machine types.

The kernel defines the value in <asm/param.h>. The tick rate has a frequency of HZ hertz and a period of 1/HZ seconds. For example, in include/asm-i386/param.h, the i386 architecture defines:

#define HZ 1000       /* internal kernel time frequency *

  Jiffies

The global variable “jiffies” holds the number of ticks that have occurred since the system booted. On boot, the kernel initializes the variable to zero, and it is incremented by one during each timer interrupt. Thus, because there are HZ timer interrupts in a second, there are HZ jiffies in a second. The system uptime is therefore jiffies/HZ seconds.

The jiffies variable is declared in <linux/jiffies.h> as

extern unsigned long volatile jiffies;

jiffies = (seconds * HZ)  

seconds = (jiffies / Hz)

The jiffies variable is declared in <linux/jiffies.h> as

extern unsigned long volatile jiffies;

The jiffies variable has always been an unsigned long, and therefore 32 bits in size on 32-bit architectures and 64-bits on 64-bit architectures. With a tick rate of 100, a 32-bit jiffies variable would overflow in about 497 days. With HZ increased to 1000, however, that overflow now occurs in just 49.7 days! If jiffies were stored in a 64-bit variable on all architectures, then for any reasonable HZ value the jiffies variable would never overflow in anyone's lifetime.

For performance and historical reasons mainly compatibility with existing kernel code the kernel developers wanted to keep jiffies an unsigned long. Some smart thinking and a little linker magic saved that day.

As you previously saw, jiffies is defined as an unsigned long:

extern unsigned long volatile jiffies;

A second variable is also defined in <linux/jiffies.h>:

extern u64 jiffies_64;

The ld(1) script used to link the main kernel image (arch/i386/kernel/vmlinux.lds.S on x86) then overlays the jiffies variable over the start of the jiffies_64 variable:

jiffies = jiffies_64;

Thus, jiffies is the lower 32 bits of the full 64-bit jiffies_64 variable. Code can continue to access the jiffies variable exactly as before. Because most code uses jiffies simply to measure elapses in time, most code cares about only the lower 32 bits. The time management code uses the entire 64 bits, however, and thus prevents overflow of the full 64-bit value. Code that accesses jiffies simply reads the lower 32 bits of jiffies_64. The function get_jiffies_64() can be used to read the full 64-bit value. Such a need is rare; consequently, most code simply continues to read the lower 32 bits directly via the jiffies variable.

On 64-bit architectures, jiffies_64 and jiffies refer to the same thing. Code can either read jiffies or call get_jiffies_64() because both actions have the same effect.

要查看或添加评论,请登录

Mohammed Yasser的更多文章

  • Watchdog Manager WdgM "From Functional safety and AUTOSAR Prescriptives" - Part 1

    Watchdog Manager WdgM "From Functional safety and AUTOSAR Prescriptives" - Part 1

    Introduction Modern ECUs contain highly modular embedded software, which can consist of both non-trusted and trusted…

  • Fee Address Translation

    Fee Address Translation

    In Classical AUTOSAR, There is a dedicated stack used to persist data in the non-volatile memory and It is called…

  • End To End Protection E2E

    End To End Protection E2E

    Introduction Behind the visible parts, a modern car is an electronic network of up to 100 electronic control units…

    4 条评论
  • Extended Page Table

    Extended Page Table

    Second Level Address Translation SLAT / Nested Paging It is extended layer in paging mechanism it is used to map from…

    1 条评论

社区洞察

其他会员也浏览了