I'm going to break the big statclock() patch on tech@ into smaller chunks that are easier to review.
The goal here is to move control of statclock() out of the clock interrupt subsystem and transform it into a client of that subsystem. I think we can do this in four parts. Part 3 is the most complex. 1. Replace the CL_RNDSTAT flag with a new global variable, "statclock_is_randomized". 2. Add clockintr_advance_random() to the public sys/clockintr.h API so statclock() can use it. 3. Merge the contents of clockintr_statclock() into statclock(); make statclock() a real callback function that reschedules itself and transparently handles multiple expirations. 4. Move control of the statclock clockintr handle from the clock interrupt subsystem to the scheduler. Attached is a patch for step 1. In order to isolate the statclock() from the clock interrupt subsystem we need to replace the CL_RNDSTAT flag with something equivalent. This patch adds a new global variable, "statclock_is_randomized", to kern_clock.c and prototypes it in sys/systm.h. All CL_RNDSTAT checks are replaced with "statclock_is_randomized" checks and instead of passing CL_RNDSTAT to clockintr_init() we set "statclock_is_randomized". ok? Index: kern/kern_clock.c =================================================================== RCS file: /cvs/src/sys/kern/kern_clock.c,v retrieving revision 1.116 diff -u -p -r1.116 kern_clock.c --- kern/kern_clock.c 9 Sep 2023 18:19:03 -0000 1.116 +++ kern/kern_clock.c 9 Sep 2023 19:03:13 -0000 @@ -86,6 +86,8 @@ int ticks = INT_MAX - (15 * 60 * HZ); /* Don't force early wrap around, triggers bug in inteldrm */ volatile unsigned long jiffies; +int statclock_is_randomized; /* [I] fixed or pseudorandom period? */ + /* * Initialize clock frequencies and start both clocks running. */ Index: kern/kern_clockintr.c =================================================================== RCS file: /cvs/src/sys/kern/kern_clockintr.c,v retrieving revision 1.45 diff -u -p -r1.45 kern_clockintr.c --- kern/kern_clockintr.c 9 Sep 2023 17:07:59 -0000 1.45 +++ kern/kern_clockintr.c 9 Sep 2023 19:03:13 -0000 @@ -167,7 +167,7 @@ clockintr_cpu_init(const struct intrcloc * We can always advance the statclock. There is no reason to * stagger a randomized statclock. */ - if (!ISSET(clockintr_flags, CL_RNDSTAT)) { + if (!statclock_is_randomized) { if (cq->cq_statclock->cl_expiration == 0) { clockintr_stagger(cq->cq_statclock, statclock_avg, multiplier, MAXCPUS); @@ -466,7 +466,7 @@ clockintr_statclock(struct clockintr *cl { uint64_t count, i; - if (ISSET(clockintr_flags, CL_RNDSTAT)) { + if (statclock_is_randomized) { count = clockintr_advance_random(cl, statclock_min, statclock_mask); } else { Index: sys/clockintr.h =================================================================== RCS file: /cvs/src/sys/sys/clockintr.h,v retrieving revision 1.12 diff -u -p -r1.12 clockintr.h --- sys/clockintr.h 6 Sep 2023 02:33:18 -0000 1.12 +++ sys/clockintr.h 9 Sep 2023 19:03:14 -0000 @@ -114,8 +114,7 @@ struct clockintr_queue { #define CL_STATE_MASK 0x00000001 /* Global behavior flags. */ -#define CL_RNDSTAT 0x80000000 /* randomized statclock */ -#define CL_FLAG_MASK 0x80000000 +#define CL_FLAG_MASK 0x00000000 void clockintr_cpu_init(const struct intrclock *); int clockintr_dispatch(void *); Index: sys/systm.h =================================================================== RCS file: /cvs/src/sys/sys/systm.h,v retrieving revision 1.165 diff -u -p -r1.165 systm.h --- sys/systm.h 23 Aug 2023 01:55:45 -0000 1.165 +++ sys/systm.h 9 Sep 2023 19:03:14 -0000 @@ -234,6 +234,7 @@ int tstohz(const struct timespec *); void realitexpire(void *); extern uint32_t hardclock_period; +extern int statclock_is_randomized; struct clockframe; void hardclock(struct clockframe *); Index: arch/amd64/amd64/lapic.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/lapic.c,v retrieving revision 1.69 diff -u -p -r1.69 lapic.c --- arch/amd64/amd64/lapic.c 23 Aug 2023 01:55:46 -0000 1.69 +++ arch/amd64/amd64/lapic.c 9 Sep 2023 19:03:14 -0000 @@ -498,7 +498,8 @@ lapic_initclocks(void) stathz = hz; profhz = stathz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); } Index: arch/arm64/dev/agtimer.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/dev/agtimer.c,v retrieving revision 1.26 diff -u -p -r1.26 agtimer.c --- arch/arm64/dev/agtimer.c 23 Aug 2023 01:55:46 -0000 1.26 +++ arch/arm64/dev/agtimer.c 9 Sep 2023 19:03:14 -0000 @@ -293,7 +293,8 @@ agtimer_cpu_initclocks(void) stathz = hz; profhz = stathz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); if (sc->sc_ticks_per_second != agtimer_frequency) { agtimer_set_clockrate(agtimer_frequency); Index: arch/arm/cortex/agtimer.c =================================================================== RCS file: /cvs/src/sys/arch/arm/cortex/agtimer.c,v retrieving revision 1.19 diff -u -p -r1.19 agtimer.c --- arch/arm/cortex/agtimer.c 23 Aug 2023 01:55:46 -0000 1.19 +++ arch/arm/cortex/agtimer.c 9 Sep 2023 19:03:14 -0000 @@ -230,7 +230,8 @@ agtimer_cpu_initclocks(void) stathz = hz; profhz = stathz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); if (sc->sc_ticks_per_second != agtimer_frequency) { agtimer_set_clockrate(agtimer_frequency); Index: arch/arm/cortex/amptimer.c =================================================================== RCS file: /cvs/src/sys/arch/arm/cortex/amptimer.c,v retrieving revision 1.18 diff -u -p -r1.18 amptimer.c --- arch/arm/cortex/amptimer.c 23 Aug 2023 01:55:46 -0000 1.18 +++ arch/arm/cortex/amptimer.c 9 Sep 2023 19:03:14 -0000 @@ -287,7 +287,8 @@ amptimer_cpu_initclocks(void) stathz = hz; profhz = hz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); if (sc->sc_ticks_per_second != amptimer_frequency) { amptimer_set_clockrate(amptimer_frequency); Index: arch/armv7/omap/dmtimer.c =================================================================== RCS file: /cvs/src/sys/arch/armv7/omap/dmtimer.c,v retrieving revision 1.20 diff -u -p -r1.20 dmtimer.c --- arch/armv7/omap/dmtimer.c 23 Aug 2023 01:55:46 -0000 1.20 +++ arch/armv7/omap/dmtimer.c 9 Sep 2023 19:03:14 -0000 @@ -232,7 +232,8 @@ dmtimer_cpu_initclocks(void) stathz = hz; profhz = stathz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); sc->sc_ticks_per_second = TIMER_FREQUENCY; /* 32768 */ sc->sc_nsec_cycle_ratio = Index: arch/armv7/omap/gptimer.c =================================================================== RCS file: /cvs/src/sys/arch/armv7/omap/gptimer.c,v retrieving revision 1.21 diff -u -p -r1.21 gptimer.c --- arch/armv7/omap/gptimer.c 23 Aug 2023 01:55:46 -0000 1.21 +++ arch/armv7/omap/gptimer.c 9 Sep 2023 19:03:14 -0000 @@ -198,7 +198,8 @@ gptimer_cpu_initclocks(void) { stathz = hz; profhz = stathz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); gptimer_nsec_cycle_ratio = TIMER_FREQUENCY * (1ULL << 32) / 1000000000; gptimer_nsec_max = UINT64_MAX / gptimer_nsec_cycle_ratio; Index: arch/armv7/sunxi/sxitimer.c =================================================================== RCS file: /cvs/src/sys/arch/armv7/sunxi/sxitimer.c,v retrieving revision 1.22 diff -u -p -r1.22 sxitimer.c --- arch/armv7/sunxi/sxitimer.c 23 Aug 2023 01:55:46 -0000 1.22 +++ arch/armv7/sunxi/sxitimer.c 9 Sep 2023 19:03:14 -0000 @@ -180,7 +180,8 @@ sxitimer_attach(struct device *parent, s stathz = hz; profhz = stathz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); /* stop timer, and set clk src */ bus_space_write_4(sxitimer_iot, sxitimer_ioh, Index: arch/hppa/dev/clock.c =================================================================== RCS file: /cvs/src/sys/arch/hppa/dev/clock.c,v retrieving revision 1.37 diff -u -p -r1.37 clock.c --- arch/hppa/dev/clock.c 23 Aug 2023 01:55:46 -0000 1.37 +++ arch/hppa/dev/clock.c 9 Sep 2023 19:03:14 -0000 @@ -116,7 +116,8 @@ cpu_initclocks(void) stathz = hz; profhz = stathz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); itmr_nsec_cycle_ratio = itmr_freq * (1ULL << 32) / 1000000000; itmr_nsec_max = UINT64_MAX / itmr_nsec_cycle_ratio; Index: arch/i386/i386/lapic.c =================================================================== RCS file: /cvs/src/sys/arch/i386/i386/lapic.c,v retrieving revision 1.56 diff -u -p -r1.56 lapic.c --- arch/i386/i386/lapic.c 23 Aug 2023 01:55:46 -0000 1.56 +++ arch/i386/i386/lapic.c 9 Sep 2023 19:03:14 -0000 @@ -326,7 +326,8 @@ lapic_initclocks(void) stathz = hz; profhz = stathz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); } extern int gettick(void); /* XXX put in header file */ Index: arch/loongson/dev/glxclk.c =================================================================== RCS file: /cvs/src/sys/arch/loongson/dev/glxclk.c,v retrieving revision 1.9 diff -u -p -r1.9 glxclk.c --- arch/loongson/dev/glxclk.c 26 Aug 2023 09:37:43 -0000 1.9 +++ arch/loongson/dev/glxclk.c 9 Sep 2023 19:03:14 -0000 @@ -189,10 +189,11 @@ glxclk_initclock(void) */ stathz = hz = 128; profhz = hz * 10; + statclock_is_randomized = 1; tick = 1000000 / hz; tick_nsec = 1000000000 / hz; - clockintr_init(CL_RNDSTAT); + clockintr_init(0); } void Index: arch/macppc/macppc/clock.c =================================================================== RCS file: /cvs/src/sys/arch/macppc/macppc/clock.c,v retrieving revision 1.56 diff -u -p -r1.56 clock.c --- arch/macppc/macppc/clock.c 23 Aug 2023 01:55:47 -0000 1.56 +++ arch/macppc/macppc/clock.c 9 Sep 2023 19:03:14 -0000 @@ -195,7 +195,8 @@ cpu_initclocks(void) stathz = hz; profhz = stathz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); dec_nsec_cycle_ratio = ticks_per_sec * (1ULL << 32) / 1000000000; dec_nsec_max = UINT64_MAX / dec_nsec_cycle_ratio; Index: arch/mips64/mips64/clock.c =================================================================== RCS file: /cvs/src/sys/arch/mips64/mips64/clock.c,v retrieving revision 1.51 diff -u -p -r1.51 clock.c --- arch/mips64/mips64/clock.c 23 Aug 2023 01:55:47 -0000 1.51 +++ arch/mips64/mips64/clock.c 9 Sep 2023 19:03:14 -0000 @@ -241,7 +241,8 @@ cp0_initclock(void) stathz = hz; profhz = stathz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); } /* Index: arch/powerpc64/powerpc64/clock.c =================================================================== RCS file: /cvs/src/sys/arch/powerpc64/powerpc64/clock.c,v retrieving revision 1.12 diff -u -p -r1.12 clock.c --- arch/powerpc64/powerpc64/clock.c 23 Aug 2023 01:55:47 -0000 1.12 +++ arch/powerpc64/powerpc64/clock.c 9 Sep 2023 19:03:14 -0000 @@ -94,7 +94,8 @@ cpu_initclocks(void) stathz = hz; profhz = stathz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); evcount_attach(&clock_count, "clock", NULL); } Index: arch/riscv64/riscv64/clock.c =================================================================== RCS file: /cvs/src/sys/arch/riscv64/riscv64/clock.c,v retrieving revision 1.11 diff -u -p -r1.11 clock.c --- arch/riscv64/riscv64/clock.c 23 Aug 2023 01:55:47 -0000 1.11 +++ arch/riscv64/riscv64/clock.c 9 Sep 2023 19:03:14 -0000 @@ -92,7 +92,8 @@ cpu_initclocks(void) stathz = hz; profhz = stathz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); riscv_intc_intr_establish(IRQ_TIMER_SUPERVISOR, 0, clock_intr, NULL, NULL); Index: arch/sparc64/sparc64/clock.c =================================================================== RCS file: /cvs/src/sys/arch/sparc64/sparc64/clock.c,v retrieving revision 1.80 diff -u -p -r1.80 clock.c --- arch/sparc64/sparc64/clock.c 23 Aug 2023 01:55:47 -0000 1.80 +++ arch/sparc64/sparc64/clock.c 9 Sep 2023 19:03:14 -0000 @@ -501,7 +501,8 @@ cpu_initclocks(void) stathz = hz; profhz = stathz * 10; - clockintr_init(CL_RNDSTAT); + statclock_is_randomized = 1; + clockintr_init(0); /* Make sure we have a sane cpu_clockrate -- we'll need it */ if (!cpu_clockrate)