Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src clock_gettime(2): Fix CLOCK_PROCESS/THREAD_CPUTIME_ID.



details:   https://anonhg.NetBSD.org/src/rev/a431fe694534
branches:  trunk
changeset: 377361:a431fe694534
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sat Jul 08 20:02:10 2023 +0000

description:
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

diffstat:

 sys/kern/kern_resource.c             |  47 +++++++++++++++++++--------------
 sys/kern/subr_time.c                 |  50 ++++++++++-------------------------
 sys/sys/resourcevar.h                |   5 ++-
 tests/lib/libc/sys/t_clock_gettime.c |   6 +--
 4 files changed, 47 insertions(+), 61 deletions(-)

diffs (241 lines):

diff -r d05f5e62ced4 -r a431fe694534 sys/kern/kern_resource.c
--- a/sys/kern/kern_resource.c  Sat Jul 08 19:10:00 2023 +0000
+++ b/sys/kern/kern_resource.c  Sat Jul 08 20:02:10 2023 +0000
@@ -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
@@ -37,7 +37,7 @@
  */
 
 #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/systm.h>
@@ -478,6 +478,30 @@ sys_getrlimit(struct lwp *l, const struc
        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,
  * system, and interrupt time usage.
@@ -504,24 +528,7 @@ calcru(struct proc *p, struct timeval *u
        tm = p->p_rtime;
 
        LIST_FOREACH(l, &p->p_lwps, l_sibling) {
-               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);
+               addrulwp(l, &tm);
        }
 
        tot = st + ut + it;
diff -r d05f5e62ced4 -r a431fe694534 sys/kern/subr_time.c
--- a/sys/kern/subr_time.c      Sat Jul 08 19:10:00 2023 +0000
+++ b/sys/kern/subr_time.c      Sat Jul 08 20:02:10 2023 +0000
@@ -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
@@ -33,7 +33,7 @@
  */
 
 #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/kernel.h>
@@ -45,12 +45,6 @@
 #include <sys/timetc.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
  * argument to callout_reset() from an absolute time.
@@ -248,32 +242,16 @@ clock_timeleft(clockid_t clockid, struct
        *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
 clock_gettime1(clockid_t clock_id, struct timespec *ts)
 {
        int error;
-       uint64_t ticks;
        struct proc *p;
 
 #define CPUCLOCK_ID_MASK (~(CLOCK_THREAD_CPUTIME_ID|CLOCK_PROCESS_CPUTIME_ID))
        if (clock_id & CLOCK_PROCESS_CPUTIME_ID) {
                pid_t pid = clock_id & CPUCLOCK_ID_MASK;
+               struct timeval cputime;
 
                mutex_enter(&proc_lock);
                p = pid == 0 ? curproc : proc_find(pid);
@@ -281,10 +259,10 @@ clock_gettime1(clockid_t clock_id, struc
                        mutex_exit(&proc_lock);
                        return ESRCH;
                }
-               ticks = p->p_uticks + p->p_sticks + p->p_iticks;
-               DPRINTF(("%s: u=%ju, s=%ju, i=%ju\n", __func__,
-                   (uintmax_t)p->p_uticks, (uintmax_t)p->p_sticks,
-                   (uintmax_t)p->p_iticks));
+               mutex_enter(p->p_lock);
+               calcru(p, /*usertime*/NULL, /*systime*/NULL, /*intrtime*/NULL,
+                   &cputime);
+               mutex_exit(p->p_lock);
                mutex_exit(&proc_lock);
 
                // XXX: Perhaps create a special kauth type
@@ -293,9 +271,14 @@ clock_gettime1(clockid_t clock_id, struc
                    KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL);
                if (error)
                        return error;
+
+               TIMEVAL_TO_TIMESPEC(&cputime, ts);
+               return 0;
        } else if (clock_id & CLOCK_THREAD_CPUTIME_ID) {
                struct lwp *l;
                lwpid_t lid = clock_id & CPUCLOCK_ID_MASK;
+               struct bintime tm = {0, 0};
+
                p = curproc;
                mutex_enter(p->p_lock);
                l = lid == 0 ? curlwp : lwp_find(p, lid);
@@ -303,15 +286,10 @@ clock_gettime1(clockid_t clock_id, struc
                        mutex_exit(p->p_lock);
                        return ESRCH;
                }
-               ticks = l->l_rticksum + l->l_slpticksum;
-               DPRINTF(("%s: r=%ju, s=%ju\n", __func__,
-                   (uintmax_t)l->l_rticksum, (uintmax_t)l->l_slpticksum));
+               addrulwp(l, &tm);
                mutex_exit(p->p_lock);
-       } else
-               ticks = (uint64_t)-1;
 
-       if (ticks != (uint64_t)-1) {
-               ticks2ts(ticks, ts);
+               bintime2timespec(&tm, ts);
                return 0;
        }
 
diff -r d05f5e62ced4 -r a431fe694534 sys/sys/resourcevar.h
--- a/sys/sys/resourcevar.h     Sat Jul 08 19:10:00 2023 +0000
+++ b/sys/sys/resourcevar.h     Sat Jul 08 20:02:10 2023 +0000
@@ -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
@@ -41,6 +41,8 @@
 #include <sys/mutex.h>
 #include <sys/resource.h>
 
+struct bintime;
+
 /*
  * 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   calcru(struct proc *, struct timeval *, struct timeval *,
            struct timeval *, struct timeval *);
+void   addrulwp(struct lwp *, struct bintime *);
 
 struct plimit *lim_copy(struct plimit *);
 void   lim_addref(struct plimit *);
diff -r d05f5e62ced4 -r a431fe694534 tests/lib/libc/sys/t_clock_gettime.c
--- a/tests/lib/libc/sys/t_clock_gettime.c      Sat Jul 08 19:10:00 2023 +0000
+++ b/tests/lib/libc/sys/t_clock_gettime.c      Sat Jul 08 20:02:10 2023 +0000
@@ -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.
@@ -58,7 +58,7 @@
 #include <sys/cdefs.h>
 __COPYRIGHT("@(#) Copyright (c) 2008\
  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>
 
@@ -281,8 +281,6 @@ ATF_TC_HEAD(clock_gettime_thread_cputime
 }
 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",
            CLOCK_THREAD_CPUTIME_ID, &waste_user_time);
 }



Home | Main Index | Thread Index | Old Index