15

据我了解,该USER_HZ常量是在 Linux 2.6 中添加的,以解决对用户空间值的期望引起的问题HZ:在以前的 Linux 版本中,更改HZ值可能会导致用户空间应用程序中的值被无意缩放。

我对USER_HZ常数如何解决这个缩放问题感到困惑。例如,假设用户空间应用程序将 jiffies 转换为秒:

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;

由于用户空间应用程序HZ通过sysconf调用确定值,这不会防止扩展问题吗?

另一方面,如果用户空间应用程序确实将HZ硬编码到其源代码中,那么USER_HZ常量将如何防止缩放问题 - 用户空间应用程序将使用它们的硬编码常量而不是系统的USER_HZ,并且不能保证硬编码的常量匹配USER_HZ

此外,用户空间(例如 )可用的所有时钟刻度值是否/proc已经缩放到USER_HZ?用户空间程序如何知道jiffies中的值是否缩放到HZUSER_HZ

4

2 回答 2

13

USER_HZ被实现为一种折衷方案:尽管用户代码的硬编码值可能与 不同USER_HZ,但 Linux 内核历史上的HZ值是100 ——因此几乎所有HZ现有用户代码中的硬编码值都设置为100

这是发生的事情的本质:

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.

现在,这留下了为什么一些内核 jiffies 暴露于未缩放的用户空间(例如 in /proc/timer_list)的问题。Thomas Gleixner 解释说

事实上的 API、系统调用以及 proc/ 中的各种文件的所有实例都必须在 USER_HZ 中,因为用户空间应用程序依赖于 USER_HZ 值。

proc/timer_list 不受此限制,因为它更像是一个调试接口,而不是严格的内核 API 的一部分。我们真的很想看到真正的值,而不是为了这个目的而缩放的 USER_HZ 值。我希望这能回答你的问题。

因此,作为严格内核 API 一部分的所有实例都旨在USER_HZ在暴露于用户空间之前通过扩展内核 jiffies,其他实例除外。

也可以看看

The Tick Rate:Linux Kernel Development Second Edition的 HZ部分,作者 Robert Love

于 2015-08-24T12:08:04.810 回答
7

来自Linux Kernel Development(或第 2 版的在线版本

在 2.6 之前的内核中,更改 的值会HZ导致用户空间异常。发生这种情况是因为值以每秒滴答数为单位导出到用户空间。随着这些接口成为永久性的,应用程序逐渐依赖于HZ. HZ因此,在用户空间不知道的情况下,更改会按某个常数缩放各种导出的值。正常运行时间为 20 小时,而实际上是 2 小时。

为防止此类问题,内核需要缩放所有导出的 jiffies 值。它通过定义 来做到这一点USER_HZ,这是HZ 用户空间期望的值。在 x86 上,因为HZ历史上是 100,所以USER_HZ是 100。

USER_HZ导出到用户空间时,每秒滴答数总是按比例缩放。

于 2013-07-01T20:42:01.257 回答