As I understand, the USER_HZ
constant was added in Linux 2.6 to solve the issues arising from the expectations of the HZ
value in user-space: in previous versions of Linux, changing the HZ
value may cause values in user-space applications to be unintentionally scaled.
I'm confused about how the USER_HZ
constant solves this scaling problem. For example, say a user-space application converts jiffies to seconds:
long MY_HZ = sysconf(_SC_CLK_TCK);
/* num_jiffies acquired from /proc but
* simplified to 1000 here for clarity */
long num_jiffies = 1000;
long num_seconds = num_jiffies / MY_HZ;
Since the user-space application is determining the HZ
value via a sysconf
call, wouldn't this prevent a scaling issue?
If on the other hand, the user-space applications did have the HZ
value hard-coded into their source, how would a USER_HZ
constant prevent a scaling issue -- the user-space applications would be using their hard-coded constants rather than the system's USER_HZ
, and there's no guarantee the hard-coded constants matches USER_HZ
?
Furthermore, are all clock tick values available to user-space (e.g. /proc
) already scaled to USER_HZ
? How does a user-space program know whether a value in jiffies is scaled to HZ
or USER_HZ
?
Jiffy values for various Linux versions and platforms have typically varied between about 1 ms and 10 ms, with 10 ms reported as an increasingly common standard in the Jargon File.
A jiffy is a kernel unit of time declared in <linux/jiffies. h> . To understand jiffies, we need to introduce a new constant, HZ, which is the number of times jiffies is incremented in one second. Each increment is called a tick. In other words, HZ represents the size of a jiffy.
In order to keep accurate time, Linux uses two different kinds of clocks : A real-time clock (RTC) or hardware clock integrated into your computer's circuit board which runs independently of the operating system. The clock still runs even when your operating system is shut down, rebooting, or hibernating.
USER_HZ
was implemented as a compromise: although user code could have a hard-coded value different from USER_HZ
, the Linux kernel historically had a HZ
value of 100 -- so virtually all hard-coded HZ
values in existing user code had been set to 100.
Here's the essence of what happened:
The Linux kernel used to have HZ set at a constant 100 for all
architectures. As additional architecture support was added, the HZ
value became variable: e.g. Linux on one machine could have a HZ
value of 1000 while Linux on another machine could have a HZ value
of 100.
This possibility of a variable HZ value caused existing user code,
which had hardcoded an expectation of HZ set to 100, to break due to
the exposure in userspace of kernel jiffies which may have be based
on a HZ value that was not equal to 100.
To prevent the chaos that would occur from years of existing user
code hardcoding a constant HZ value of 100, a compromise was made:
any exposure of kernel jiffies to userspace should be scaled via a
new USER_HZ value -- thus preventing existing user code from
breaking on machines with a different HZ value, while still allowing
the kernel on those machines to have a HZ value different from the
historic 100 value.
Now, this leaves the question of why some kernel jiffies are exposed to userspace unscaled (e.g. in /proc/timer_list
). Thomas Gleixner explains:
All instances which are de facto APIs, syscalls and also various files in proc/ must be in USER_HZ because userspace applications depend on the USER_HZ value.
proc/timer_list is exempt from that because its more a debugging interface which is not part of the strict kernel API. And we really want to see the real values and not the scaled USER_HZ ones for that purpose. I hope that answers your question.
So all instances which are part of the strict kernel API are meant to scale kernel jiffies via USER_HZ
before exposure to userspace, which other instances are exempt.
The Tick Rate: HZ section of Linux Kernel Development Second Edition by Robert Love
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With