On Tue, Jul 18, 2023 at 08:21:41AM -0500, Scott Cheloha wrote:
> This patch moves the profil(2)- and GPROF-specific parts of
> statclock() out into into separate clock interrupt routines.  The
> profil(2) part moves into profclock() and is enabled/disabled as
> needed during mi_switch().  The GPROF part moves into gmonclock() and
> is enabled/disabled as needed via sysctl(2).
>
> Moving those parts out of statclock() eliminates the need for an
> effective statclock frequency and we can delete all the junk related
> to that: psratio/psdiv/pscnt and corresponding members of
> schedstate_percpu, clockintr_setstatclockrate(), a bunch of other
> clockintr-internal code
>
> In separate commits I have addressed:
>
> - General GPROF instability on amd64
> - GPROF causing a crash during suspend/resume
> - CTASSERT breakage on amd64 related to schedstate_percpu
>   changes in this patch
>
> This has been kicking around for over two months.  Personally, I have
> tested it on amd64, arm64, macppc, octeon, and sparc64.
>
> Compile- and boot-tests on other platforms (alpha, i386, luna88k,
> riscv64, sh) would be appreciated, but the last time I asked for tests
> I got zero reports back.

i386 compiles and boots. as reported in separate mail, riscv64 doesn't
compile.

>
> I don't know how to proceed.
>
> FWIW, GPROF is not enabled in any default kernel configurations and
> profil(2) is more-or-less useless (and painful to test) until I finish
> changing the libc gmon code and gprof(1).  So, the patch is low-risk.
>
> v1: https://marc.info/?l=openbsd-tech&m=168721453821801&w=2
>
> Index: kern/kern_clock.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_clock.c,v
> retrieving revision 1.108
> diff -u -p -r1.108 kern_clock.c
> --- kern/kern_clock.c 25 Apr 2023 00:58:47 -0000      1.108
> +++ kern/kern_clock.c 18 Jul 2023 13:14:27 -0000
> @@ -49,10 +49,6 @@
>  #include <sys/sched.h>
>  #include <sys/timetc.h>
>
> -#if defined(GPROF) || defined(DDBPROF)
> -#include <sys/gmon.h>
> -#endif
> -
>  #include "dt.h"
>  #if NDT > 0
>  #include <dev/dt/dtvar.h>
> @@ -87,8 +83,6 @@ int schedhz;
>  int  profhz;
>  int  profprocs;
>  int  ticks = INT_MAX - (15 * 60 * HZ);
> -static int psdiv, pscnt;             /* prof => stat divider */
> -int  psratio;                        /* ratio: prof / stat */
>
>  volatile unsigned long jiffies = ULONG_MAX - (10 * 60 * HZ);
>
> @@ -99,16 +93,13 @@ void
>  initclocks(void)
>  {
>       /*
> -      * Set divisors to 1 (normal case) and let the machine-specific
> -      * code do its bit.
> +      * Let the machine-specific code do its bit.
>        */
> -     psdiv = pscnt = 1;
>       cpu_initclocks();
>
> -     /*
> -      * Compute profhz/stathz.
> -      */
> -     psratio = profhz / stathz;
> +     KASSERT(profhz >= stathz && profhz <= 1000000000);
> +     KASSERT(profhz % stathz == 0);
> +     profclock_period = 1000000000 / profhz;
>
>       inittimecounter();
>  }
> @@ -256,7 +247,6 @@ startprofclock(struct process *pr)
>               atomic_setbits_int(&pr->ps_flags, PS_PROFIL);
>               if (++profprocs == 1) {
>                       s = splstatclock();
> -                     psdiv = pscnt = psratio;
>                       setstatclockrate(profhz);
>                       splx(s);
>               }
> @@ -275,7 +265,6 @@ stopprofclock(struct process *pr)
>               atomic_clearbits_int(&pr->ps_flags, PS_PROFIL);
>               if (--profprocs == 0) {
>                       s = splstatclock();
> -                     psdiv = pscnt = 1;
>                       setstatclockrate(stathz);
>                       splx(s);
>               }
> @@ -289,35 +278,13 @@ stopprofclock(struct process *pr)
>  void
>  statclock(struct clockframe *frame)
>  {
> -#if defined(GPROF) || defined(DDBPROF)
> -     struct gmonparam *g;
> -     u_long i;
> -#endif
>       struct cpu_info *ci = curcpu();
>       struct schedstate_percpu *spc = &ci->ci_schedstate;
>       struct proc *p = curproc;
>       struct process *pr;
>
> -     /*
> -      * Notice changes in divisor frequency, and adjust clock
> -      * frequency accordingly.
> -      */
> -     if (spc->spc_psdiv != psdiv) {
> -             spc->spc_psdiv = psdiv;
> -             spc->spc_pscnt = psdiv;
> -             if (psdiv == 1) {
> -                     setstatclockrate(stathz);
> -             } else {
> -                     setstatclockrate(profhz);
> -             }
> -     }
> -
>       if (CLKF_USERMODE(frame)) {
>               pr = p->p_p;
> -             if (pr->ps_flags & PS_PROFIL)
> -                     addupc_intr(p, CLKF_PC(frame), 1);
> -             if (--spc->spc_pscnt > 0)
> -                     return;
>               /*
>                * Came from user mode; CPU was in user state.
>                * If this process is being profiled record the tick.
> @@ -328,23 +295,6 @@ statclock(struct clockframe *frame)
>               else
>                       spc->spc_cp_time[CP_USER]++;
>       } else {
> -#if defined(GPROF) || defined(DDBPROF)
> -             /*
> -              * Kernel statistics are just like addupc_intr, only easier.
> -              */
> -             g = ci->ci_gmon;
> -             if (g != NULL && g->state == GMON_PROF_ON) {
> -                     i = CLKF_PC(frame) - g->lowpc;
> -                     if (i < g->textsize) {
> -                             i /= HISTFRACTION * sizeof(*g->kcount);
> -                             g->kcount[i]++;
> -                     }
> -             }
> -#endif
> -             if (p != NULL && p->p_p->ps_flags & PS_PROFIL)
> -                     addupc_intr(p, PROC_PC(p), 1);
> -             if (--spc->spc_pscnt > 0)
> -                     return;
>               /*
>                * Came from kernel mode, so we were:
>                * - spinning on a lock
> @@ -371,7 +321,6 @@ statclock(struct clockframe *frame)
>                       spc->spc_cp_time[spc->spc_spinning ?
>                           CP_SPIN : CP_IDLE]++;
>       }
> -     spc->spc_pscnt = psdiv;
>
>       if (p != NULL) {
>               p->p_cpticks++;
> Index: kern/subr_prof.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/subr_prof.c,v
> retrieving revision 1.35
> diff -u -p -r1.35 subr_prof.c
> --- kern/subr_prof.c  2 Jun 2023 17:44:29 -0000       1.35
> +++ kern/subr_prof.c  18 Jul 2023 13:14:27 -0000
> @@ -34,6 +34,7 @@
>
>  #include <sys/param.h>
>  #include <sys/systm.h>
> +#include <sys/atomic.h>
>  #include <sys/pledge.h>
>  #include <sys/proc.h>
>  #include <sys/resourcevar.h>
> @@ -41,6 +42,7 @@
>  #include <sys/sysctl.h>
>  #include <sys/syscallargs.h>
>
> +uint32_t profclock_period;
>
>  #if defined(GPROF) || defined(DDBPROF)
>  #include <sys/malloc.h>
> @@ -60,6 +62,8 @@ u_int gmon_cpu_count;               /* [K] number of
>
>  extern char etext[];
>
> +void gmonclock(struct clockintr *, void *);
> +
>  void
>  prof_init(void)
>  {
> @@ -95,6 +99,14 @@ prof_init(void)
>
>       /* Allocate and initialize one profiling buffer per CPU. */
>       CPU_INFO_FOREACH(cii, ci) {
> +             ci->ci_gmonclock = clockintr_establish(&ci->ci_queue,
> +                 gmonclock);
> +             if (ci->ci_gmonclock == NULL) {
> +                     printf("%s: clockintr_establish gmonclock\n", __func__);
> +                     return;
> +             }
> +             clockintr_stagger(ci->ci_gmonclock, profclock_period,
> +                 CPU_INFO_UNIT(ci), MAXCPUS);
>               cp = km_alloc(round_page(size), &kv_any, &kp_zero, &kd_nowait);
>               if (cp == NULL) {
>                       printf("No memory for profiling.\n");
> @@ -124,8 +136,9 @@ prof_init(void)
>  }
>
>  int
> -prof_state_toggle(struct gmonparam *gp, int oldstate)
> +prof_state_toggle(struct cpu_info *ci, int oldstate)
>  {
> +     struct gmonparam *gp = ci->ci_gmon;
>       int error = 0;
>
>       KERNEL_ASSERT_LOCKED();
> @@ -145,6 +158,7 @@ prof_state_toggle(struct gmonparam *gp,
>               if (error == 0) {
>                       if (++gmon_cpu_count == 1)
>                               startprofclock(&process0);
> +                     clockintr_advance(ci->ci_gmonclock, profclock_period);
>               }
>               break;
>       default:
> @@ -152,6 +166,7 @@ prof_state_toggle(struct gmonparam *gp,
>               gp->state = GMON_PROF_OFF;
>               /* FALLTHROUGH */
>       case GMON_PROF_OFF:
> +             clockintr_cancel(ci->ci_gmonclock);
>               if (--gmon_cpu_count == 0)
>                       stopprofclock(&process0);
>  #if !defined(GPROF)
> @@ -201,7 +216,7 @@ sysctl_doprof(int *name, u_int namelen,
>               error = sysctl_int(oldp, oldlenp, newp, newlen, &gp->state);
>               if (error)
>                       return (error);
> -             return (prof_state_toggle(gp, state));
> +             return prof_state_toggle(ci, state);
>       case GPROF_COUNT:
>               return (sysctl_struct(oldp, oldlenp, newp, newlen,
>                   gp->kcount, gp->kcountsize));
> @@ -218,6 +233,31 @@ sysctl_doprof(int *name, u_int namelen,
>       }
>       /* NOTREACHED */
>  }
> +
> +void
> +gmonclock(struct clockintr *cl, void *cf)
> +{
> +     uint64_t count;
> +     struct clockframe *frame = cf;
> +     struct gmonparam *g = curcpu()->ci_gmon;
> +     u_long i;
> +
> +     count = clockintr_advance(cl, profclock_period);
> +     if (count > ULONG_MAX)
> +             count = ULONG_MAX;
> +
> +     /*
> +      * Kernel statistics are just like addupc_intr(), only easier.
> +      */
> +     if (!CLKF_USERMODE(frame) && g != NULL && g->state == GMON_PROF_ON) {
> +             i = CLKF_PC(frame) - g->lowpc;
> +             if (i < g->textsize) {
> +                     i /= HISTFRACTION * sizeof(*g->kcount);
> +                     g->kcount[i] += (u_long)count;
> +             }
> +     }
> +}
> +
>  #endif /* GPROF || DDBPROF */
>
>  /*
> @@ -247,6 +287,7 @@ sys_profil(struct proc *p, void *v, regi
>               return (EINVAL);
>       if (SCARG(uap, scale) == 0) {
>               stopprofclock(pr);
> +             need_resched(curcpu());
>               return (0);
>       }
>       upp = &pr->ps_prof;
> @@ -259,8 +300,29 @@ sys_profil(struct proc *p, void *v, regi
>       upp->pr_size = SCARG(uap, size);
>       startprofclock(pr);
>       splx(s);
> +     need_resched(curcpu());
>
>       return (0);
> +}
> +
> +void
> +profclock(struct clockintr *cl, void *cf)
> +{
> +     uint64_t count;
> +     struct clockframe *frame = cf;
> +     struct proc *p = curproc;
> +
> +     count = clockintr_advance(cl, profclock_period);
> +     if (count > ULONG_MAX)
> +             count = ULONG_MAX;
> +
> +     if (CLKF_USERMODE(frame)) {
> +             if (ISSET(p->p_p->ps_flags, PS_PROFIL))
> +                     addupc_intr(p, CLKF_PC(frame), (u_long)count);
> +     } else {
> +             if (p != NULL && ISSET(p->p_p->ps_flags, PS_PROFIL))
> +                     addupc_intr(p, PROC_PC(p), (u_long)count);
> +     }
>  }
>
>  /*
> Index: kern/kern_sched.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_sched.c,v
> retrieving revision 1.79
> diff -u -p -r1.79 kern_sched.c
> --- kern/kern_sched.c 14 Jul 2023 07:07:08 -0000      1.79
> +++ kern/kern_sched.c 18 Jul 2023 13:14:27 -0000
> @@ -21,6 +21,8 @@
>  #include <sys/proc.h>
>  #include <sys/kthread.h>
>  #include <sys/systm.h>
> +#include <sys/clockintr.h>
> +#include <sys/resourcevar.h>
>  #include <sys/task.h>
>  #include <sys/smr.h>
>  #include <sys/tracepoint.h>
> @@ -85,6 +87,15 @@ sched_init_cpu(struct cpu_info *ci)
>
>       spc->spc_idleproc = NULL;
>
> +     if (spc->spc_profclock == NULL) {
> +             spc->spc_profclock = clockintr_establish(&ci->ci_queue,
> +                 profclock);
> +             if (spc->spc_profclock == NULL)
> +                     panic("%s: clockintr_establish profclock", __func__);
> +             clockintr_stagger(spc->spc_profclock, profclock_period,
> +                 CPU_INFO_UNIT(ci), MAXCPUS);
> +     }
> +
>       kthread_create_deferred(sched_kthreads_create, ci);
>
>       LIST_INIT(&spc->spc_deadproc);
> @@ -213,6 +224,11 @@ sched_exit(struct proc *p)
>       nanouptime(&ts);
>       timespecsub(&ts, &spc->spc_runtime, &ts);
>       timespecadd(&p->p_rtime, &ts, &p->p_rtime);
> +
> +     if (ISSET(spc->spc_schedflags, SPCF_PROFCLOCK)) {
> +             atomic_clearbits_int(&spc->spc_schedflags, SPCF_PROFCLOCK);
> +             clockintr_cancel(spc->spc_profclock);
> +     }
>
>       LIST_INSERT_HEAD(&spc->spc_deadproc, p, p_hash);
>
> Index: kern/sched_bsd.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/sched_bsd.c,v
> retrieving revision 1.77
> diff -u -p -r1.77 sched_bsd.c
> --- kern/sched_bsd.c  11 Jul 2023 07:02:43 -0000      1.77
> +++ kern/sched_bsd.c  18 Jul 2023 13:14:27 -0000
> @@ -39,6 +39,7 @@
>
>  #include <sys/param.h>
>  #include <sys/systm.h>
> +#include <sys/clockintr.h>
>  #include <sys/proc.h>
>  #include <sys/kernel.h>
>  #include <sys/malloc.h>
> @@ -349,6 +350,12 @@ mi_switch(void)
>       /* add the time counts for this thread to the process's total */
>       tuagg_unlocked(pr, p);
>
> +     /* Stop the profclock if it's running. */
> +     if (ISSET(spc->spc_schedflags, SPCF_PROFCLOCK)) {
> +             atomic_clearbits_int(&spc->spc_schedflags, SPCF_PROFCLOCK);
> +             clockintr_cancel(spc->spc_profclock);
> +     }
> +
>       /*
>        * Process is about to yield the CPU; clear the appropriate
>        * scheduling flags.
> @@ -392,6 +399,14 @@ mi_switch(void)
>        * schedstate_percpu pointer.
>        */
>       KASSERT(p->p_cpu == curcpu());
> +
> +     /* Start the profclock if profil(2) is enabled. */
> +     if (ISSET(p->p_p->ps_flags, PS_PROFIL)) {
> +             atomic_setbits_int(&p->p_cpu->ci_schedstate.spc_schedflags,
> +                 SPCF_PROFCLOCK);
> +             clockintr_advance(p->p_cpu->ci_schedstate.spc_profclock,
> +                 profclock_period);
> +     }
>
>       nanouptime(&p->p_cpu->ci_schedstate.spc_runtime);
>
> Index: kern/kern_clockintr.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_clockintr.c,v
> retrieving revision 1.27
> diff -u -p -r1.27 kern_clockintr.c
> --- kern/kern_clockintr.c     2 Jul 2023 19:02:27 -0000       1.27
> +++ kern/kern_clockintr.c     18 Jul 2023 13:14:28 -0000
> @@ -25,6 +25,7 @@
>  #include <sys/malloc.h>
>  #include <sys/mutex.h>
>  #include <sys/queue.h>
> +#include <sys/resourcevar.h>
>  #include <sys/stdint.h>
>  #include <sys/sysctl.h>
>  #include <sys/time.h>
> @@ -32,39 +33,23 @@
>  /*
>   * Protection for global variables in this file:
>   *
> - *   C       Global clockintr configuration mutex (clockintr_mtx).
>   *   I       Immutable after initialization.
>   */
> -struct mutex clockintr_mtx = MUTEX_INITIALIZER(IPL_CLOCK);
> -
>  u_int clockintr_flags;                       /* [I] global state + behavior 
> flags */
>  uint32_t hardclock_period;           /* [I] hardclock period (ns) */
>  uint32_t schedclock_period;          /* [I] schedclock period (ns) */
> -volatile u_int statclock_gen = 1;    /* [C] statclock update generation */
> -volatile uint32_t statclock_avg;     /* [C] average statclock period (ns) */
> -uint32_t statclock_min;                      /* [C] minimum statclock period 
> (ns) */
> -uint32_t statclock_mask;             /* [C] set of allowed offsets */
> -uint32_t stat_avg;                   /* [I] average stathz period (ns) */
> -uint32_t stat_min;                   /* [I] set of allowed offsets */
> -uint32_t stat_mask;                  /* [I] max offset from minimum (ns) */
> -uint32_t prof_avg;                   /* [I] average profhz period (ns) */
> -uint32_t prof_min;                   /* [I] minimum profhz period (ns) */
> -uint32_t prof_mask;                  /* [I] set of allowed offsets */
> +uint32_t statclock_avg;                      /* [I] average statclock period 
> (ns) */
> +uint32_t statclock_min;                      /* [I] minimum statclock period 
> (ns) */
> +uint32_t statclock_mask;             /* [I] set of allowed offsets */
>
> -uint64_t clockintr_advance(struct clockintr *, uint64_t);
> -void clockintr_cancel(struct clockintr *);
>  void clockintr_cancel_locked(struct clockintr *);
> -struct clockintr *clockintr_establish(struct clockintr_queue *,
> -    void (*)(struct clockintr *, void *));
>  uint64_t clockintr_expiration(const struct clockintr *);
>  void clockintr_hardclock(struct clockintr *, void *);
>  uint64_t clockintr_nsecuptime(const struct clockintr *);
>  void clockintr_schedclock(struct clockintr *, void *);
>  void clockintr_schedule(struct clockintr *, uint64_t);
>  void clockintr_schedule_locked(struct clockintr *, uint64_t);
> -void clockintr_stagger(struct clockintr *, uint64_t, u_int, u_int);
>  void clockintr_statclock(struct clockintr *, void *);
> -void clockintr_statvar_init(int, uint32_t *, uint32_t *, uint32_t *);
>  uint64_t clockqueue_next(const struct clockintr_queue *);
>  void clockqueue_reset_intrclock(struct clockintr_queue *);
>  uint64_t nsec_advance(uint64_t *, uint64_t, uint64_t);
> @@ -75,6 +60,8 @@ uint64_t nsec_advance(uint64_t *, uint64
>  void
>  clockintr_init(u_int flags)
>  {
> +     uint32_t half_avg, var;
> +
>       KASSERT(CPU_IS_PRIMARY(curcpu()));
>       KASSERT(clockintr_flags == 0);
>       KASSERT(!ISSET(flags, ~CL_FLAG_MASK));
> @@ -83,12 +70,22 @@ clockintr_init(u_int flags)
>       hardclock_period = 1000000000 / hz;
>
>       KASSERT(stathz >= 1 && stathz <= 1000000000);
> -     KASSERT(profhz >= stathz && profhz <= 1000000000);
> -     KASSERT(profhz % stathz == 0);
> -     clockintr_statvar_init(stathz, &stat_avg, &stat_min, &stat_mask);
> -     clockintr_statvar_init(profhz, &prof_avg, &prof_min, &prof_mask);
> -     SET(clockintr_flags, CL_STATCLOCK);
> -     clockintr_setstatclockrate(stathz);
> +
> +     /*
> +      * Compute the average statclock() period.  Then find var, the
> +      * largest power of two such that var <= statclock_avg / 2.
> +      */
> +     statclock_avg = 1000000000 / stathz;
> +     half_avg = statclock_avg / 2;
> +     for (var = 1U << 31; var > half_avg; var /= 2)
> +             continue;
> +
> +     /*
> +      * Set a lower bound for the range using statclock_avg and var.
> +      * The mask for that range is just (var - 1).
> +      */
> +     statclock_min = statclock_avg - (var / 2);
> +     statclock_mask = var - 1;
>
>       KASSERT(schedhz >= 0 && schedhz <= 1000000000);
>       if (schedhz != 0)
> @@ -479,70 +476,6 @@ clockintr_stagger(struct clockintr *cl,
>       mtx_leave(&cq->cq_mtx);
>  }
>
> -/*
> - * Compute the period (avg) for the given frequency and a range around
> - * that period.  The range is [min + 1, min + mask].  The range is used
> - * during dispatch to choose a new pseudorandom deadline for each statclock
> - * event.
> - */
> -void
> -clockintr_statvar_init(int freq, uint32_t *avg, uint32_t *min, uint32_t 
> *mask)
> -{
> -     uint32_t half_avg, var;
> -
> -     KASSERT(!ISSET(clockintr_flags, CL_INIT | CL_STATCLOCK));
> -     KASSERT(freq > 0 && freq <= 1000000000);
> -
> -     /* Compute avg, the average period. */
> -     *avg = 1000000000 / freq;
> -
> -     /* Find var, the largest power of two such that var <= avg / 2. */
> -     half_avg = *avg / 2;
> -     for (var = 1U << 31; var > half_avg; var /= 2)
> -             continue;
> -
> -     /* Using avg and var, set a lower bound for the range. */
> -     *min = *avg - (var / 2);
> -
> -     /* The mask is just (var - 1). */
> -     *mask = var - 1;
> -}
> -
> -/*
> - * Update the statclock_* variables according to the given frequency.
> - * Must only be called after clockintr_statvar_init() initializes both
> - * stathz_* and profhz_*.
> - */
> -void
> -clockintr_setstatclockrate(int freq)
> -{
> -     u_int ogen;
> -
> -     KASSERT(ISSET(clockintr_flags, CL_STATCLOCK));
> -
> -     mtx_enter(&clockintr_mtx);
> -
> -     ogen = statclock_gen;
> -     statclock_gen = 0;
> -     membar_producer();
> -     if (freq == stathz) {
> -             statclock_avg = stat_avg;
> -             statclock_min = stat_min;
> -             statclock_mask = stat_mask;
> -     } else if (freq == profhz) {
> -             statclock_avg = prof_avg;
> -             statclock_min = prof_min;
> -             statclock_mask = prof_mask;
> -     } else {
> -             panic("%s: frequency is not stathz (%d) or profhz (%d): %d",
> -                 __func__, stathz, profhz, freq);
> -     }
> -     membar_producer();
> -     statclock_gen = MAX(1, ogen + 1);
> -
> -     mtx_leave(&clockintr_mtx);
> -}
> -
>  uint64_t
>  clockintr_nsecuptime(const struct clockintr *cl)
>  {
> @@ -577,24 +510,16 @@ void
>  clockintr_statclock(struct clockintr *cl, void *frame)
>  {
>       uint64_t count, expiration, i, uptime;
> -     uint32_t mask, min, off;
> -     u_int gen;
> +     uint32_t off;
>
>       if (ISSET(clockintr_flags, CL_RNDSTAT)) {
> -             do {
> -                     gen = statclock_gen;
> -                     membar_consumer();
> -                     min = statclock_min;
> -                     mask = statclock_mask;
> -                     membar_consumer();
> -             } while (gen == 0 || gen != statclock_gen);
>               count = 0;
>               expiration = clockintr_expiration(cl);
>               uptime = clockintr_nsecuptime(cl);
>               while (expiration <= uptime) {
> -                     while ((off = (random() & mask)) == 0)
> +                     while ((off = (random() & statclock_mask)) == 0)
>                               continue;
> -                     expiration += min + off;
> +                     expiration += statclock_min + off;
>                       count++;
>               }
>               clockintr_schedule(cl, expiration);
> Index: sys/resourcevar.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/resourcevar.h,v
> retrieving revision 1.26
> diff -u -p -r1.26 resourcevar.h
> --- sys/resourcevar.h 25 Apr 2023 00:58:47 -0000      1.26
> +++ sys/resourcevar.h 18 Jul 2023 13:14:28 -0000
> @@ -60,8 +60,13 @@ do {                                                       
>                 \
>
>  #include <lib/libkern/libkern.h>     /* for KASSERT() */
>
> +struct clockintr;
> +
> +extern uint32_t profclock_period;
> +
>  void  addupc_intr(struct proc *, u_long, u_long);
>  void  addupc_task(struct proc *, u_long, u_int);
> +void  profclock(struct clockintr *, void *);
>  void  tuagg_unlocked(struct process *, struct proc *);
>  void  tuagg(struct process *, struct proc *);
>  struct tusage;
> Index: sys/sched.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/sched.h,v
> retrieving revision 1.57
> diff -u -p -r1.57 sched.h
> --- sys/sched.h       25 Dec 2020 12:49:31 -0000      1.57
> +++ sys/sched.h       18 Jul 2023 13:14:28 -0000
> @@ -90,6 +90,7 @@
>
>  #define      SCHED_NQS       32                      /* 32 run queues. */
>
> +struct clockintr;
>  struct smr_entry;
>
>  /*
> @@ -105,8 +106,8 @@ struct schedstate_percpu {
>       u_int64_t spc_cp_time[CPUSTATES]; /* CPU state statistics */
>       u_char spc_curpriority;         /* usrpri of curproc */
>       int spc_rrticks;                /* ticks until roundrobin() */
> -     int spc_pscnt;                  /* prof/stat counter */
> -     int spc_psdiv;                  /* prof/stat divisor */
> +
> +     struct clockintr *spc_profclock; /* [o] profclock handle */
>
>       u_int spc_nrun;                 /* procs on the run queues */
>       fixpt_t spc_ldavg;              /* shortest load avg. for this cpu */
> @@ -137,6 +138,7 @@ struct cpustats {
>  #define SPCF_SWITCHCLEAR        (SPCF_SEENRR|SPCF_SHOULDYIELD)
>  #define SPCF_SHOULDHALT              0x0004  /* CPU should be vacated */
>  #define SPCF_HALTED          0x0008  /* CPU has been halted */
> +#define SPCF_PROFCLOCK               0x0010  /* profclock() was started */
>
>  #define      SCHED_PPQ       (128 / SCHED_NQS)       /* priorities per queue 
> */
>  #define NICE_WEIGHT 2                        /* priorities per nice level */
> Index: sys/clockintr.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/clockintr.h,v
> retrieving revision 1.8
> diff -u -p -r1.8 clockintr.h
> --- sys/clockintr.h   15 Jun 2023 22:18:06 -0000      1.8
> +++ sys/clockintr.h   18 Jul 2023 13:14:28 -0000
> @@ -112,8 +112,7 @@ struct clockintr_queue {
>
>  /* Global state flags. */
>  #define CL_INIT                      0x00000001      /* global init done */
> -#define CL_STATCLOCK         0x00000002      /* statclock variables set */
> -#define CL_STATE_MASK                0x00000003
> +#define CL_STATE_MASK                0x00000001
>
>  /* Global behavior flags. */
>  #define CL_RNDSTAT           0x80000000      /* randomized statclock */
> @@ -122,13 +121,17 @@ struct clockintr_queue {
>  void clockintr_cpu_init(const struct intrclock *);
>  int clockintr_dispatch(void *);
>  void clockintr_init(u_int);
> -void clockintr_setstatclockrate(int);
>  void clockintr_trigger(void);
>
>  /*
>   * Kernel API
>   */
>
> +uint64_t clockintr_advance(struct clockintr *, uint64_t);
> +void clockintr_cancel(struct clockintr *);
> +struct clockintr *clockintr_establish(struct clockintr_queue *,
> +    void (*)(struct clockintr *, void *));
> +void clockintr_stagger(struct clockintr *, uint64_t, u_int, u_int);
>  void clockqueue_init(struct clockintr_queue *);
>  int sysctl_clockintr(int *, u_int, void *, size_t *, void *, size_t);
>
> Index: arch/alpha/alpha/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/alpha/alpha/clock.c,v
> retrieving revision 1.27
> diff -u -p -r1.27 clock.c
> --- arch/alpha/alpha/clock.c  4 Feb 2023 19:19:36 -0000       1.27
> +++ arch/alpha/alpha/clock.c  18 Jul 2023 13:14:28 -0000
> @@ -218,7 +218,6 @@ cpu_initclocks(void)
>  void
>  setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>  u_int
> Index: arch/alpha/include/cpu.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/alpha/include/cpu.h,v
> retrieving revision 1.69
> diff -u -p -r1.69 cpu.h
> --- arch/alpha/include/cpu.h  31 Jan 2023 15:18:53 -0000      1.69
> +++ arch/alpha/include/cpu.h  18 Jul 2023 13:14:28 -0000
> @@ -212,6 +212,7 @@ struct cpu_info {
>  #endif
>  #ifdef GPROF
>       struct gmonparam *ci_gmon;
> +     struct clockintr *ci_gmonclock;
>  #endif
>       struct clockintr_queue ci_queue;
>       char ci_panicbuf[512];
> Index: arch/amd64/isa/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/isa/clock.c,v
> retrieving revision 1.39
> diff -u -p -r1.39 clock.c
> --- arch/amd64/isa/clock.c    4 Feb 2023 19:19:36 -0000       1.39
> +++ arch/amd64/isa/clock.c    18 Jul 2023 13:14:28 -0000
> @@ -519,7 +519,6 @@ setstatclockrate(int arg)
>                       mc146818_write(NULL, MC_REGA,
>                           MC_BASE_32_KHz | MC_RATE_1024_Hz);
>       }
> -     clockintr_setstatclockrate(arg);
>  }
>
>  void
> Index: arch/amd64/include/cpu.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/include/cpu.h,v
> retrieving revision 1.155
> diff -u -p -r1.155 cpu.h
> --- arch/amd64/include/cpu.h  4 Jul 2023 17:29:32 -0000       1.155
> +++ arch/amd64/include/cpu.h  18 Jul 2023 13:14:28 -0000
> @@ -208,6 +208,7 @@ struct cpu_info {
>       u_int64_t               ci_hz_aperf;
>  #if defined(GPROF) || defined(DDBPROF)
>       struct gmonparam        *ci_gmon;
> +     struct clockintr        *ci_gmonclock;
>  #endif
>       u_int32_t       ci_vmm_flags;
>  #define      CI_VMM_VMX      (1 << 0)
> Index: arch/arm/include/cpu.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/arm/include/cpu.h,v
> retrieving revision 1.62
> diff -u -p -r1.62 cpu.h
> --- arch/arm/include/cpu.h    17 Jan 2023 02:27:14 -0000      1.62
> +++ arch/arm/include/cpu.h    18 Jul 2023 13:14:28 -0000
> @@ -198,6 +198,7 @@ struct cpu_info {
>
>  #ifdef GPROF
>       struct gmonparam *ci_gmon;
> +     struct clockintr *ci_gmonclock;
>  #endif
>       struct clockintr_queue  ci_queue;
>       char                    ci_panicbuf[512];
> Index: arch/arm/cortex/agtimer.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/arm/cortex/agtimer.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 agtimer.c
> --- arch/arm/cortex/agtimer.c 4 Feb 2023 19:19:36 -0000       1.17
> +++ arch/arm/cortex/agtimer.c 18 Jul 2023 13:14:28 -0000
> @@ -288,7 +288,6 @@ agtimer_delay(u_int usecs)
>  void
>  agtimer_setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>  void
> Index: arch/arm/cortex/amptimer.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/arm/cortex/amptimer.c,v
> retrieving revision 1.16
> diff -u -p -r1.16 amptimer.c
> --- arch/arm/cortex/amptimer.c        4 Feb 2023 19:19:36 -0000       1.16
> +++ arch/arm/cortex/amptimer.c        18 Jul 2023 13:14:28 -0000
> @@ -343,7 +343,6 @@ amptimer_delay(u_int usecs)
>  void
>  amptimer_setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>  void
> Index: arch/armv7/omap/dmtimer.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/armv7/omap/dmtimer.c,v
> retrieving revision 1.18
> diff -u -p -r1.18 dmtimer.c
> --- arch/armv7/omap/dmtimer.c 4 Feb 2023 19:19:36 -0000       1.18
> +++ arch/armv7/omap/dmtimer.c 18 Jul 2023 13:14:28 -0000
> @@ -317,7 +317,6 @@ dmtimer_delay(u_int usecs)
>  void
>  dmtimer_setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>
> Index: arch/armv7/omap/gptimer.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/armv7/omap/gptimer.c,v
> retrieving revision 1.19
> diff -u -p -r1.19 gptimer.c
> --- arch/armv7/omap/gptimer.c 4 Feb 2023 19:19:36 -0000       1.19
> +++ arch/armv7/omap/gptimer.c 18 Jul 2023 13:14:28 -0000
> @@ -326,7 +326,6 @@ gptimer_delay(u_int usecs)
>  void
>  gptimer_setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>
> Index: arch/armv7/sunxi/sxitimer.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/armv7/sunxi/sxitimer.c,v
> retrieving revision 1.20
> diff -u -p -r1.20 sxitimer.c
> --- arch/armv7/sunxi/sxitimer.c       4 Feb 2023 19:19:36 -0000       1.20
> +++ arch/armv7/sunxi/sxitimer.c       18 Jul 2023 13:14:28 -0000
> @@ -299,7 +299,6 @@ sxitimer_delay(u_int usecs)
>  void
>  sxitimer_setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>  u_int
> Index: arch/arm64/dev/agtimer.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/arm64/dev/agtimer.c,v
> retrieving revision 1.22
> diff -u -p -r1.22 agtimer.c
> --- arch/arm64/dev/agtimer.c  4 Feb 2023 19:19:36 -0000       1.22
> +++ arch/arm64/dev/agtimer.c  18 Jul 2023 13:14:28 -0000
> @@ -354,7 +354,6 @@ agtimer_delay(u_int usecs)
>  void
>  agtimer_setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>  void
> Index: arch/arm64/include/cpu.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/arm64/include/cpu.h,v
> retrieving revision 1.37
> diff -u -p -r1.37 cpu.h
> --- arch/arm64/include/cpu.h  13 Jul 2023 08:33:36 -0000      1.37
> +++ arch/arm64/include/cpu.h  18 Jul 2023 13:14:28 -0000
> @@ -172,6 +172,7 @@ struct cpu_info {
>
>  #ifdef GPROF
>       struct gmonparam        *ci_gmon;
> +     struct clockintr        *ci_gmonclock;
>  #endif
>       struct clockintr_queue  ci_queue;
>       char                    ci_panicbuf[512];
> Index: arch/hppa/dev/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/hppa/dev/clock.c,v
> retrieving revision 1.35
> diff -u -p -r1.35 clock.c
> --- arch/hppa/dev/clock.c     4 Feb 2023 19:19:36 -0000       1.35
> +++ arch/hppa/dev/clock.c     18 Jul 2023 13:14:28 -0000
> @@ -141,7 +141,6 @@ itmr_intr(void *v)
>  void
>  setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>  u_int
> Index: arch/hppa/include/cpu.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/hppa/include/cpu.h,v
> retrieving revision 1.99
> diff -u -p -r1.99 cpu.h
> --- arch/hppa/include/cpu.h   31 Jan 2023 15:18:54 -0000      1.99
> +++ arch/hppa/include/cpu.h   18 Jul 2023 13:14:28 -0000
> @@ -113,6 +113,7 @@ struct cpu_info {
>  #endif
>  #ifdef GPROF
>       struct gmonparam *ci_gmon;
> +     struct clockintr *ci_gmonclock;
>  #endif
>       struct clockintr_queue ci_queue;
>       char            ci_panicbuf[512];
> Index: arch/i386/isa/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/i386/isa/clock.c,v
> retrieving revision 1.64
> diff -u -p -r1.64 clock.c
> --- arch/i386/isa/clock.c     4 Feb 2023 19:19:36 -0000       1.64
> +++ arch/i386/isa/clock.c     18 Jul 2023 13:14:28 -0000
> @@ -663,7 +663,6 @@ setstatclockrate(int arg)
>                       mc146818_write(NULL, MC_REGA,
>                           MC_BASE_32_KHz | MC_RATE_1024_Hz);
>       }
> -     clockintr_setstatclockrate(arg);
>  }
>
>  void
> Index: arch/i386/include/cpu.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/i386/include/cpu.h,v
> retrieving revision 1.181
> diff -u -p -r1.181 cpu.h
> --- arch/i386/include/cpu.h   6 Dec 2022 01:56:44 -0000       1.181
> +++ arch/i386/include/cpu.h   18 Jul 2023 13:14:29 -0000
> @@ -168,6 +168,7 @@ struct cpu_info {
>       struct ksensor          ci_sensor;
>  #if defined(GPROF) || defined(DDBPROF)
>       struct gmonparam        *ci_gmon;
> +     struct clockintr        *ci_gmonclock;
>  #endif
>       struct clockintr_queue  ci_queue;
>       char                    ci_panicbuf[512];
> Index: arch/luna88k/luna88k/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/luna88k/luna88k/clock.c,v
> retrieving revision 1.16
> diff -u -p -r1.16 clock.c
> --- arch/luna88k/luna88k/clock.c      6 Dec 2022 00:56:52 -0000       1.16
> +++ arch/luna88k/luna88k/clock.c      18 Jul 2023 13:14:29 -0000
> @@ -152,7 +152,6 @@ cpu_initclocks()
>  void
>  setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>  /*
> Index: arch/m88k/include/cpu.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/m88k/include/cpu.h,v
> retrieving revision 1.72
> diff -u -p -r1.72 cpu.h
> --- arch/m88k/include/cpu.h   31 Jan 2023 15:18:54 -0000      1.72
> +++ arch/m88k/include/cpu.h   18 Jul 2023 13:14:29 -0000
> @@ -177,6 +177,7 @@ struct cpu_info {
>  #endif
>  #ifdef GPROF
>       struct gmonparam *ci_gmon;
> +     struct clockintr *ci_gmonclock;
>  #endif
>       struct clockintr_queue ci_queue;
>       char             ci_panicbuf[512];
> Index: arch/macppc/macppc/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/macppc/macppc/clock.c,v
> retrieving revision 1.54
> diff -u -p -r1.54 clock.c
> --- arch/macppc/macppc/clock.c        4 Feb 2023 23:17:05 -0000       1.54
> +++ arch/macppc/macppc/clock.c        18 Jul 2023 13:14:29 -0000
> @@ -234,7 +234,6 @@ delay(unsigned n)
>  void
>  setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>  u_int
> Index: arch/powerpc/include/cpu.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/powerpc/include/cpu.h,v
> retrieving revision 1.74
> diff -u -p -r1.74 cpu.h
> --- arch/powerpc/include/cpu.h        29 Nov 2022 00:58:05 -0000      1.74
> +++ arch/powerpc/include/cpu.h        18 Jul 2023 13:14:29 -0000
> @@ -89,6 +89,7 @@ struct cpu_info {
>  #endif
>  #ifdef GPROF
>       struct gmonparam *ci_gmon;
> +     struct clockintr *ci_gmonclock;
>  #endif
>       char ci_panicbuf[512];
>  };
> Index: arch/mips64/mips64/mips64_machdep.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/mips64/mips64/mips64_machdep.c,v
> retrieving revision 1.41
> diff -u -p -r1.41 mips64_machdep.c
> --- arch/mips64/mips64/mips64_machdep.c       4 Feb 2023 19:19:36 -0000       
> 1.41
> +++ arch/mips64/mips64/mips64_machdep.c       18 Jul 2023 13:14:29 -0000
> @@ -333,7 +333,6 @@ cpu_initclocks(void)
>  void
>  setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>  /*
> Index: arch/mips64/include/cpu.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/mips64/include/cpu.h,v
> retrieving revision 1.141
> diff -u -p -r1.141 cpu.h
> --- arch/mips64/include/cpu.h 11 Jan 2023 03:19:52 -0000      1.141
> +++ arch/mips64/include/cpu.h 18 Jul 2023 13:14:29 -0000
> @@ -200,6 +200,7 @@ struct cpu_info {
>  #endif
>  #ifdef GPROF
>       struct gmonparam *ci_gmon;
> +     struct clockintr *ci_gmonclock;
>  #endif
>       char            ci_panicbuf[512];
>  };
> Index: arch/powerpc64/powerpc64/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/powerpc64/powerpc64/clock.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 clock.c
> --- arch/powerpc64/powerpc64/clock.c  4 Feb 2023 23:20:54 -0000       1.10
> +++ arch/powerpc64/powerpc64/clock.c  18 Jul 2023 13:14:29 -0000
> @@ -141,7 +141,6 @@ decr_intr(struct trapframe *frame)
>  void
>  setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>  void
> Index: arch/riscv64/riscv64/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/riscv64/riscv64/clock.c,v
> retrieving revision 1.9
> diff -u -p -r1.9 clock.c
> --- arch/riscv64/riscv64/clock.c      4 Feb 2023 19:19:37 -0000       1.9
> +++ arch/riscv64/riscv64/clock.c      18 Jul 2023 13:14:29 -0000
> @@ -144,7 +144,6 @@ clock_intr(void *frame)
>  void
>  setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>  void
> Index: arch/riscv64/include/cpu.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/riscv64/include/cpu.h,v
> retrieving revision 1.15
> diff -u -p -r1.15 cpu.h
> --- arch/riscv64/include/cpu.h        19 Nov 2022 16:02:37 -0000      1.15
> +++ arch/riscv64/include/cpu.h        18 Jul 2023 13:14:29 -0000
> @@ -119,6 +119,7 @@ struct cpu_info {
>
>  #ifdef GPROF
>       struct gmonparam        *ci_gmon;
> +     struct clockintr        *ci_gmonclock;
>  #endif
>
>       char                    ci_panicbuf[512];
> Index: arch/sh/sh/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/sh/sh/clock.c,v
> retrieving revision 1.14
> diff -u -p -r1.14 clock.c
> --- arch/sh/sh/clock.c        10 Apr 2023 04:21:20 -0000      1.14
> +++ arch/sh/sh/clock.c        18 Jul 2023 13:14:29 -0000
> @@ -203,7 +203,6 @@ sh_clock_get_pclock(void)
>  void
>  setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>  u_int
> Index: arch/sh/include/cpu.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/sh/include/cpu.h,v
> retrieving revision 1.34
> diff -u -p -r1.34 cpu.h
> --- arch/sh/include/cpu.h     6 Dec 2022 01:19:35 -0000       1.34
> +++ arch/sh/include/cpu.h     18 Jul 2023 13:14:29 -0000
> @@ -68,6 +68,7 @@ struct cpu_info {
>  #endif
>  #ifdef GPROF
>       struct gmonparam *ci_gmon;
> +     struct clockintr *ci_gmonclock;
>  #endif
>
>       int     ci_want_resched;
> Index: arch/sparc64/sparc64/clock.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/sparc64/sparc64/clock.c,v
> retrieving revision 1.77
> diff -u -p -r1.77 clock.c
> --- arch/sparc64/sparc64/clock.c      28 Apr 2023 18:27:55 -0000      1.77
> +++ arch/sparc64/sparc64/clock.c      18 Jul 2023 13:14:29 -0000
> @@ -576,7 +576,6 @@ cpu_initclocks(void)
>  void
>  setstatclockrate(int newhz)
>  {
> -     clockintr_setstatclockrate(newhz);
>  }
>
>  /*
> Index: arch/sparc64/include/cpu.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/sparc64/include/cpu.h,v
> retrieving revision 1.101
> diff -u -p -r1.101 cpu.h
> --- arch/sparc64/include/cpu.h        13 Jan 2023 03:22:18 -0000      1.101
> +++ arch/sparc64/include/cpu.h        18 Jul 2023 13:14:29 -0000
> @@ -165,6 +165,7 @@ struct cpu_info {
>  #endif
>  #ifdef GPROF
>       struct gmonparam *ci_gmon;
> +     struct clockintr *ci_gmonclock;
>  #endif
>       char                    ci_panicbuf[512];
>  };
>


Reply via email to