forked from illumos/illumos-gate
-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
OS-6364 lx: USER_HZ of 1000 breaks broken code which assumes 100 HZ
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com> Approved by: Patrick Mooney <patrick.mooney@joyent.com>
- Loading branch information
Showing
11 changed files
with
170 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* This file and its contents are supplied under the terms of the | ||
* Common Development and Distribution License ("CDDL"), version 1.0. | ||
* You may only use this file in accordance with the terms of version | ||
* 1.0 of the CDDL. | ||
* | ||
* A full copy of the text of the CDDL should have accompanied this | ||
* source. A copy of the CDDL is also available via the Internet at | ||
* http://www.illumos.org/license/CDDL. | ||
*/ | ||
|
||
/* | ||
* Copyright 2017 Joyent, Inc. | ||
*/ | ||
|
||
#ifndef _LX_USERHZ_H | ||
#define _LX_USERHZ_H | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/* | ||
* Within the kernel, Linux implements an internal hz that they refer to as a | ||
* "jiffy". Linux can be built with different hz, but on modern kernels | ||
* it is frequently 250. However, Linux has a separate concept for the hz | ||
* that is visible outside the kernel. This is called "USER_HZ" and is the | ||
* value returned by 'sysconf(_SC_CLK_TCK)'. This is almost universally set to | ||
* 100hz. Some (lazy) applications just hardcode 100hz instead of checking. | ||
* To accommodate these broken applications, we always work with a USER_HZ of | ||
* 100 and scale accordingly. See the Linux time(7) man page for a more | ||
* detailed discussion of their behavior. See the comment in our | ||
* uts/common/conf/param.c for a discussion of valid native hz values. | ||
* | ||
* There are a few interfaces which expose a clock_t to user-land and which | ||
* need to be considered for USER_HZ adjustment. | ||
* 1) The times(2) syscall. This is handled correctly. | ||
* 2) The waitid(2) syscall passes a siginfo_t which contains si_stime and | ||
* si_utime. Testing waitid(2) on various Linux distributions shows that the | ||
* these fields are garbage. This aligns with the Linux waitid(2) man page, | ||
* which describes the subset of the siginfo_t structure that is populated. | ||
* Neither si_stime or si_utime are listed. | ||
* 3) A sigaction(2) handler can pass a siginfo_t. This is only documented to | ||
* occur when the sa_flags is SA_SIGINFO. The si_stime and si_utime are | ||
* documented to only be populated when the signal is SIGCHLD. However, | ||
* testing on Linux seems to show that these fields are not consistent | ||
* with the corresponding times(2) data for the process, even for the | ||
* SIGCHLD sigaction handler case. | ||
* | ||
* Although the siginfo_t si_stime and si_utime data for cases #2 and #3 is not | ||
* consistent on Linux, we populate these fields correctly to be on the safe | ||
* side. | ||
*/ | ||
extern uint_t lx_hz_scale; | ||
#define LX_USERHZ 100 | ||
#define HZ_TO_LX_USERHZ(x) ((x) / lx_hz_scale) | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* _LX_USERHZ_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* | ||
* This file and its contents are supplied under the terms of the | ||
* Common Development and Distribution License ("CDDL"), version 1.0. | ||
* You may only use this file in accordance with the terms of version | ||
* 1.0 of the CDDL. | ||
* | ||
* A full copy of the text of the CDDL should have accompanied this | ||
* source. A copy of the CDDL is also available via the Internet at | ||
* http://www.illumos.org/license/CDDL. | ||
*/ | ||
|
||
/* | ||
* Copyright 2017, Joyent, Inc. | ||
*/ | ||
|
||
#include <sys/types.h> | ||
#include <sys/systm.h> | ||
#include <sys/thread.h> | ||
#include <sys/proc.h> | ||
#include <sys/times.h> | ||
#include <sys/msacct.h> | ||
#include <sys/lx_userhz.h> | ||
|
||
/* See the comment on LX_USERHZ for more details. */ | ||
#define LX_NSEC_PER_USERHZ (NANOSEC / LX_USERHZ) | ||
#define NSEC_TO_LX_USERHZ(nsec) ((nsec) / LX_NSEC_PER_USERHZ) | ||
|
||
/* | ||
* Our times(2) implementation is based on the native times(2), but with | ||
* the necessary scaling to adjust to USER_HZ. Also, Linux avoids writing | ||
* to a NULL tp, whereas our native code returns EFAULT. | ||
*/ | ||
long | ||
lx_times(struct tms *tp) | ||
{ | ||
proc_t *p = curproc; | ||
struct tms p_time; | ||
clock_t ret_lbolt; | ||
|
||
mutex_enter(&p->p_lock); | ||
p_time.tms_utime = | ||
(clock_t)NSEC_TO_LX_USERHZ(mstate_aggr_state(p, LMS_USER)); | ||
p_time.tms_stime = | ||
(clock_t)NSEC_TO_LX_USERHZ(mstate_aggr_state(p, LMS_SYSTEM)); | ||
p_time.tms_cutime = HZ_TO_LX_USERHZ(p->p_cutime); | ||
p_time.tms_cstime = HZ_TO_LX_USERHZ(p->p_cstime); | ||
mutex_exit(&p->p_lock); | ||
|
||
#ifdef _SYSCALL32_IMPL | ||
if (get_udatamodel() != DATAMODEL_NATIVE) { | ||
struct tms32 t32; | ||
|
||
t32.tms_utime = p_time.tms_utime; | ||
t32.tms_stime = p_time.tms_stime; | ||
t32.tms_cutime = p_time.tms_cutime; | ||
t32.tms_cstime = p_time.tms_cstime; | ||
|
||
if (tp != NULL && copyout(&t32, tp, sizeof (t32)) != 0) | ||
return (set_errno(EFAULT)); | ||
|
||
ret_lbolt = ddi_get_lbolt(); | ||
return ((clock32_t)HZ_TO_LX_USERHZ(ret_lbolt)); | ||
} else | ||
#endif /* _SYSCALL32_IMPL */ | ||
{ | ||
if (tp != NULL && copyout(&p_time, tp, sizeof (p_time)) != 0) | ||
return (set_errno(EFAULT)); | ||
|
||
ret_lbolt = ddi_get_lbolt(); | ||
return (HZ_TO_LX_USERHZ(ret_lbolt)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters