USER_HZ如何解决jiffy缩放问题?

据我所知,在Linux 2.6中添加了USER_HZ常数,以解决用户空间中对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; 

由于用户空间应用程序正在通过sysconf调用来确定HZ值,这是否不能防止缩放问题?

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

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

从Linux内核开发 (或第二版的在线版本 )

在早于2.6的内核中,更改HZ的值会导致用户空间异常。 发生这种情况的原因是值以每秒钟的时间单位为单位导出到用户空间。 随着这些界面变得永久,应用程序越来越依赖于HZ的特定价值。 因此,改变HZ可以将不同的导出值按一定的比例缩放,而不需要用户空间的知识。 正常运行时间将是20个小时,实际上是两个小时。

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

当导出到用户空间时,每秒刻度总是缩放到USER_HZ

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: eg 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暴露给用户空间未缩放的问题(例如在/proc/timer_list )。 Thomas Gleixner解释说 :

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

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

因此,所有属于严格内核API的实例都是为了在暴露给用户空间之前通过USER_HZ来扩展内核jiffies,而其他实例是免除的。

也可以看看

Tick Rate: Robert Love的Linux coreel Development第二版HZ部分