clock_gettime(2): Fix CLOCK_PROCESS/THREAD_CPUTIME_ID.
Use same calculation as getrusage, not some ad-hoc arithmetic of internal scheduler parameters that are periodically rewound. PR kern/57512 XXX pullup-8 XXX pullup-9 XXX pullup-10
This commit is contained in:
parent
4fb0058c93
commit
42ba7a81e2
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: kern_resource.c,v 1.190 2023/07/08 11:42:03 riastradh Exp $ */
|
/* $NetBSD: kern_resource.c,v 1.191 2023/07/08 20:02:10 riastradh Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1982, 1986, 1991, 1993
|
* Copyright (c) 1982, 1986, 1991, 1993
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.190 2023/07/08 11:42:03 riastradh Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.191 2023/07/08 20:02:10 riastradh Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -478,6 +478,30 @@ sys_getrlimit(struct lwp *l, const struct sys_getrlimit_args *uap,
|
||||||
return copyout(&rl, SCARG(uap, rlp), sizeof(rl));
|
return copyout(&rl, SCARG(uap, rlp), sizeof(rl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
addrulwp(struct lwp *l, struct bintime *tm)
|
||||||
|
{
|
||||||
|
|
||||||
|
lwp_lock(l);
|
||||||
|
bintime_add(tm, &l->l_rtime);
|
||||||
|
if ((l->l_pflag & LP_RUNNING) != 0 &&
|
||||||
|
(l->l_pflag & (LP_INTR | LP_TIMEINTR)) != LP_INTR) {
|
||||||
|
struct bintime diff;
|
||||||
|
/*
|
||||||
|
* Adjust for the current time slice. This is
|
||||||
|
* actually fairly important since the error
|
||||||
|
* here is on the order of a time quantum,
|
||||||
|
* which is much greater than the sampling
|
||||||
|
* error.
|
||||||
|
*/
|
||||||
|
binuptime(&diff);
|
||||||
|
membar_consumer(); /* for softint_dispatch() */
|
||||||
|
bintime_sub(&diff, &l->l_stime);
|
||||||
|
bintime_add(tm, &diff);
|
||||||
|
}
|
||||||
|
lwp_unlock(l);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transform the running time and tick information in proc p into user,
|
* Transform the running time and tick information in proc p into user,
|
||||||
* system, and interrupt time usage.
|
* system, and interrupt time usage.
|
||||||
|
@ -504,24 +528,7 @@ calcru(struct proc *p, struct timeval *up, struct timeval *sp,
|
||||||
tm = p->p_rtime;
|
tm = p->p_rtime;
|
||||||
|
|
||||||
LIST_FOREACH(l, &p->p_lwps, l_sibling) {
|
LIST_FOREACH(l, &p->p_lwps, l_sibling) {
|
||||||
lwp_lock(l);
|
addrulwp(l, &tm);
|
||||||
bintime_add(&tm, &l->l_rtime);
|
|
||||||
if ((l->l_pflag & LP_RUNNING) != 0 &&
|
|
||||||
(l->l_pflag & (LP_INTR | LP_TIMEINTR)) != LP_INTR) {
|
|
||||||
struct bintime diff;
|
|
||||||
/*
|
|
||||||
* Adjust for the current time slice. This is
|
|
||||||
* actually fairly important since the error
|
|
||||||
* here is on the order of a time quantum,
|
|
||||||
* which is much greater than the sampling
|
|
||||||
* error.
|
|
||||||
*/
|
|
||||||
binuptime(&diff);
|
|
||||||
membar_consumer(); /* for softint_dispatch() */
|
|
||||||
bintime_sub(&diff, &l->l_stime);
|
|
||||||
bintime_add(&tm, &diff);
|
|
||||||
}
|
|
||||||
lwp_unlock(l);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tot = st + ut + it;
|
tot = st + ut + it;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: subr_time.c,v 1.37 2023/04/29 03:36:55 isaki Exp $ */
|
/* $NetBSD: subr_time.c,v 1.38 2023/07/08 20:02:10 riastradh Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1982, 1986, 1989, 1993
|
* Copyright (c) 1982, 1986, 1989, 1993
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.37 2023/04/29 03:36:55 isaki Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.38 2023/07/08 20:02:10 riastradh Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
|
@ -45,12 +45,6 @@ __KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.37 2023/04/29 03:36:55 isaki Exp $")
|
||||||
#include <sys/timetc.h>
|
#include <sys/timetc.h>
|
||||||
#include <sys/intr.h>
|
#include <sys/intr.h>
|
||||||
|
|
||||||
#ifdef DEBUG_STICKS
|
|
||||||
#define DPRINTF(a) uprintf a
|
|
||||||
#else
|
|
||||||
#define DPRINTF(a)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute number of hz until specified time. Used to compute second
|
* Compute number of hz until specified time. Used to compute second
|
||||||
* argument to callout_reset() from an absolute time.
|
* argument to callout_reset() from an absolute time.
|
||||||
|
@ -248,32 +242,16 @@ clock_timeleft(clockid_t clockid, struct timespec *ts, struct timespec *sleepts)
|
||||||
*sleepts = sleptts;
|
*sleepts = sleptts;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ticks2ts(uint64_t ticks, struct timespec *ts)
|
|
||||||
{
|
|
||||||
ts->tv_sec = ticks / hz;
|
|
||||||
uint64_t sticks = ticks - ts->tv_sec * hz;
|
|
||||||
if (sticks > BINTIME_SCALE_MS) /* floor(2^64 / 1000) */
|
|
||||||
ts->tv_nsec = sticks / hz * 1000000000LL;
|
|
||||||
else if (sticks > BINTIME_SCALE_US) /* floor(2^64 / 1000000) */
|
|
||||||
ts->tv_nsec = sticks * 1000LL / hz * 1000000LL;
|
|
||||||
else
|
|
||||||
ts->tv_nsec = sticks * 1000000000LL / hz;
|
|
||||||
DPRINTF(("%s: %ju/%ju -> %ju.%ju\n", __func__,
|
|
||||||
(uintmax_t)ticks, (uintmax_t)sticks,
|
|
||||||
(uintmax_t)ts->tv_sec, (uintmax_t)ts->tv_nsec));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
clock_gettime1(clockid_t clock_id, struct timespec *ts)
|
clock_gettime1(clockid_t clock_id, struct timespec *ts)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
uint64_t ticks;
|
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
|
||||||
#define CPUCLOCK_ID_MASK (~(CLOCK_THREAD_CPUTIME_ID|CLOCK_PROCESS_CPUTIME_ID))
|
#define CPUCLOCK_ID_MASK (~(CLOCK_THREAD_CPUTIME_ID|CLOCK_PROCESS_CPUTIME_ID))
|
||||||
if (clock_id & CLOCK_PROCESS_CPUTIME_ID) {
|
if (clock_id & CLOCK_PROCESS_CPUTIME_ID) {
|
||||||
pid_t pid = clock_id & CPUCLOCK_ID_MASK;
|
pid_t pid = clock_id & CPUCLOCK_ID_MASK;
|
||||||
|
struct timeval cputime;
|
||||||
|
|
||||||
mutex_enter(&proc_lock);
|
mutex_enter(&proc_lock);
|
||||||
p = pid == 0 ? curproc : proc_find(pid);
|
p = pid == 0 ? curproc : proc_find(pid);
|
||||||
|
@ -281,10 +259,10 @@ clock_gettime1(clockid_t clock_id, struct timespec *ts)
|
||||||
mutex_exit(&proc_lock);
|
mutex_exit(&proc_lock);
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
}
|
}
|
||||||
ticks = p->p_uticks + p->p_sticks + p->p_iticks;
|
mutex_enter(p->p_lock);
|
||||||
DPRINTF(("%s: u=%ju, s=%ju, i=%ju\n", __func__,
|
calcru(p, /*usertime*/NULL, /*systime*/NULL, /*intrtime*/NULL,
|
||||||
(uintmax_t)p->p_uticks, (uintmax_t)p->p_sticks,
|
&cputime);
|
||||||
(uintmax_t)p->p_iticks));
|
mutex_exit(p->p_lock);
|
||||||
mutex_exit(&proc_lock);
|
mutex_exit(&proc_lock);
|
||||||
|
|
||||||
// XXX: Perhaps create a special kauth type
|
// XXX: Perhaps create a special kauth type
|
||||||
|
@ -293,9 +271,14 @@ clock_gettime1(clockid_t clock_id, struct timespec *ts)
|
||||||
KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL);
|
KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
TIMEVAL_TO_TIMESPEC(&cputime, ts);
|
||||||
|
return 0;
|
||||||
} else if (clock_id & CLOCK_THREAD_CPUTIME_ID) {
|
} else if (clock_id & CLOCK_THREAD_CPUTIME_ID) {
|
||||||
struct lwp *l;
|
struct lwp *l;
|
||||||
lwpid_t lid = clock_id & CPUCLOCK_ID_MASK;
|
lwpid_t lid = clock_id & CPUCLOCK_ID_MASK;
|
||||||
|
struct bintime tm = {0, 0};
|
||||||
|
|
||||||
p = curproc;
|
p = curproc;
|
||||||
mutex_enter(p->p_lock);
|
mutex_enter(p->p_lock);
|
||||||
l = lid == 0 ? curlwp : lwp_find(p, lid);
|
l = lid == 0 ? curlwp : lwp_find(p, lid);
|
||||||
|
@ -303,15 +286,10 @@ clock_gettime1(clockid_t clock_id, struct timespec *ts)
|
||||||
mutex_exit(p->p_lock);
|
mutex_exit(p->p_lock);
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
}
|
}
|
||||||
ticks = l->l_rticksum + l->l_slpticksum;
|
addrulwp(l, &tm);
|
||||||
DPRINTF(("%s: r=%ju, s=%ju\n", __func__,
|
|
||||||
(uintmax_t)l->l_rticksum, (uintmax_t)l->l_slpticksum));
|
|
||||||
mutex_exit(p->p_lock);
|
mutex_exit(p->p_lock);
|
||||||
} else
|
|
||||||
ticks = (uint64_t)-1;
|
|
||||||
|
|
||||||
if (ticks != (uint64_t)-1) {
|
bintime2timespec(&tm, ts);
|
||||||
ticks2ts(ticks, ts);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: resourcevar.h,v 1.57 2018/05/07 21:03:45 christos Exp $ */
|
/* $NetBSD: resourcevar.h,v 1.58 2023/07/08 20:02:10 riastradh Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1991, 1993
|
* Copyright (c) 1991, 1993
|
||||||
|
@ -41,6 +41,8 @@
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
|
||||||
|
struct bintime;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Kernel per-process accounting / statistics
|
* Kernel per-process accounting / statistics
|
||||||
*/
|
*/
|
||||||
|
@ -107,6 +109,7 @@ void addupc_intr(struct lwp *, u_long);
|
||||||
void addupc_task(struct lwp *, u_long, u_int);
|
void addupc_task(struct lwp *, u_long, u_int);
|
||||||
void calcru(struct proc *, struct timeval *, struct timeval *,
|
void calcru(struct proc *, struct timeval *, struct timeval *,
|
||||||
struct timeval *, struct timeval *);
|
struct timeval *, struct timeval *);
|
||||||
|
void addrulwp(struct lwp *, struct bintime *);
|
||||||
|
|
||||||
struct plimit *lim_copy(struct plimit *);
|
struct plimit *lim_copy(struct plimit *);
|
||||||
void lim_addref(struct plimit *);
|
void lim_addref(struct plimit *);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: t_clock_gettime.c,v 1.4 2023/07/08 14:05:51 riastradh Exp $ */
|
/* $NetBSD: t_clock_gettime.c,v 1.5 2023/07/08 20:02:10 riastradh Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__COPYRIGHT("@(#) Copyright (c) 2008\
|
__COPYRIGHT("@(#) Copyright (c) 2008\
|
||||||
The NetBSD Foundation, inc. All rights reserved.");
|
The NetBSD Foundation, inc. All rights reserved.");
|
||||||
__RCSID("$NetBSD: t_clock_gettime.c,v 1.4 2023/07/08 14:05:51 riastradh Exp $");
|
__RCSID("$NetBSD: t_clock_gettime.c,v 1.5 2023/07/08 20:02:10 riastradh Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
@ -281,8 +281,6 @@ ATF_TC_HEAD(clock_gettime_thread_cputime_is_monotonic, tc)
|
||||||
}
|
}
|
||||||
ATF_TC_BODY(clock_gettime_thread_cputime_is_monotonic, tc)
|
ATF_TC_BODY(clock_gettime_thread_cputime_is_monotonic, tc)
|
||||||
{
|
{
|
||||||
atf_tc_expect_fail("PR kern/57512: clock_gettime"
|
|
||||||
"(CLOCK_THREAD_CPUTIME_ID) sometimes goes backwards");
|
|
||||||
check_monotonicity("CLOCK_THREAD_CPUTIME_ID",
|
check_monotonicity("CLOCK_THREAD_CPUTIME_ID",
|
||||||
CLOCK_THREAD_CPUTIME_ID, &waste_user_time);
|
CLOCK_THREAD_CPUTIME_ID, &waste_user_time);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue