From 671537bfe8bfe713871272c2b93cc174a388053e Mon Sep 17 00:00:00 2001 From: cheloha Date: Tue, 25 Jul 2023 18:16:19 +0000 Subject: [PATCH] statclock: move profil(2), GPROF code to profclock(), gmonclock() This patch isolates profil(2) and GPROF from statclock(). Currently, statclock() implements both profil(2) and GPROF through a complex mechanism involving both platform code (setstatclockrate) and the scheduler (pscnt, psdiv, and psratio). We have a machine-independent interface to the clock interrupt hardware now, so we no longer need to do it this way. - Move profil(2)-specific code from statclock() to a new clock interrupt callback, profclock(), in subr_prof.c. Each schedstate_percpu has its own profclock handle. The profclock is enabled/disabled for a given CPU when it is needed by the running thread during mi_switch() and sched_exit(). - Move GPROF-specific code from statclock() to a new clock interrupt callback, gmonclock(), in subr_prof.c. Where available, each cpu_info has its own gmonclock handle . The gmonclock is enabled/disabled for a given CPU via sysctl(2) in prof_state_toggle(). - Both profclock() and gmonclock() have a fixed period, profclock_period, that is initialized during initclocks(). - Export clockintr_advance(), clockintr_cancel(), clockintr_establish(), and clockintr_stagger() via . They have external callers now. - Delete pscnt, psdiv, psratio. From schedstate_percpu, also delete spc_pscnt and spc_psdiv. The statclock frequency is not dynamic anymore so these variables are now useless. - Delete code/state related to the dynamic statclock frequency from kern_clockintr.c. The statclock frequency can still be pseudo-random, so move the contents of clockintr_statvar_init() into clockintr_init(). With input from miod@, deraadt@, and claudio@. Early revisions cleaned up by claudio. Early revisions tested by claudio@. Tested by cheloha@ on amd64, arm64, macppc, octeon, and sparc64 (sun4v). Compile- and boot- tested on i386 by mlarkin@. riscv64 compilation bugs found by mlarkin@. Tested on riscv64 by jca@. Tested on powerpc64 by gkoehler@. --- sys/arch/alpha/alpha/clock.c | 3 +- sys/arch/alpha/include/cpu.h | 3 +- sys/arch/amd64/include/cpu.h | 3 +- sys/arch/amd64/isa/clock.c | 3 +- sys/arch/arm/cortex/agtimer.c | 3 +- sys/arch/arm/cortex/amptimer.c | 3 +- sys/arch/arm/include/cpu.h | 3 +- sys/arch/arm64/dev/agtimer.c | 3 +- sys/arch/arm64/include/cpu.h | 3 +- sys/arch/armv7/omap/dmtimer.c | 3 +- sys/arch/armv7/omap/gptimer.c | 3 +- sys/arch/armv7/sunxi/sxitimer.c | 3 +- sys/arch/hppa/dev/clock.c | 3 +- sys/arch/hppa/include/cpu.h | 3 +- sys/arch/i386/include/cpu.h | 3 +- sys/arch/i386/isa/clock.c | 3 +- sys/arch/luna88k/luna88k/clock.c | 3 +- sys/arch/m88k/include/cpu.h | 3 +- sys/arch/macppc/macppc/clock.c | 3 +- sys/arch/mips64/include/cpu.h | 3 +- sys/arch/mips64/mips64/mips64_machdep.c | 3 +- sys/arch/powerpc/include/cpu.h | 3 +- sys/arch/powerpc64/powerpc64/clock.c | 3 +- sys/arch/riscv64/include/cpu.h | 3 +- sys/arch/riscv64/riscv64/clock.c | 3 +- sys/arch/sh/include/cpu.h | 3 +- sys/arch/sh/sh/clock.c | 3 +- sys/arch/sparc64/include/cpu.h | 3 +- sys/arch/sparc64/sparc64/clock.c | 3 +- sys/kern/kern_clock.c | 61 +---------- sys/kern/kern_clockintr.c | 128 +++++------------------- sys/kern/kern_sched.c | 18 +++- sys/kern/sched_bsd.c | 17 +++- sys/kern/subr_prof.c | 70 ++++++++++++- sys/sys/clockintr.h | 11 +- sys/sys/resourcevar.h | 7 +- sys/sys/sched.h | 8 +- 37 files changed, 190 insertions(+), 217 deletions(-) diff --git a/sys/arch/alpha/alpha/clock.c b/sys/arch/alpha/alpha/clock.c index 6943160dc89..dc86c35c542 100644 --- a/sys/arch/alpha/alpha/clock.c +++ b/sys/arch/alpha/alpha/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.27 2023/02/04 19:19:36 cheloha Exp $ */ +/* $OpenBSD: clock.c,v 1.28 2023/07/25 18:16:19 cheloha Exp $ */ /* $NetBSD: clock.c,v 1.29 2000/06/05 21:47:10 thorpej Exp $ */ /* @@ -218,7 +218,6 @@ cpu_initclocks(void) void setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } u_int diff --git a/sys/arch/alpha/include/cpu.h b/sys/arch/alpha/include/cpu.h index 4a89c7969fc..b2a438f69e7 100644 --- a/sys/arch/alpha/include/cpu.h +++ b/sys/arch/alpha/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.69 2023/01/31 15:18:53 deraadt Exp $ */ +/* $OpenBSD: cpu.h,v 1.70 2023/07/25 18:16:19 cheloha Exp $ */ /* $NetBSD: cpu.h,v 1.45 2000/08/21 02:03:12 thorpej Exp $ */ /*- @@ -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]; diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index 1975c874aad..b5784abe689 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.156 2023/07/25 06:48:37 guenther Exp $ */ +/* $OpenBSD: cpu.h,v 1.157 2023/07/25 18:16:19 cheloha Exp $ */ /* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */ /*- @@ -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) diff --git a/sys/arch/amd64/isa/clock.c b/sys/arch/amd64/isa/clock.c index 44b221a11e2..019259ffdff 100644 --- a/sys/arch/amd64/isa/clock.c +++ b/sys/arch/amd64/isa/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.39 2023/02/04 19:19:36 cheloha Exp $ */ +/* $OpenBSD: clock.c,v 1.40 2023/07/25 18:16:19 cheloha Exp $ */ /* $NetBSD: clock.c,v 1.1 2003/04/26 18:39:50 fvdl Exp $ */ /*- @@ -519,7 +519,6 @@ setstatclockrate(int arg) mc146818_write(NULL, MC_REGA, MC_BASE_32_KHz | MC_RATE_1024_Hz); } - clockintr_setstatclockrate(arg); } void diff --git a/sys/arch/arm/cortex/agtimer.c b/sys/arch/arm/cortex/agtimer.c index 9ccf56fc3bf..13b0af6f8e1 100644 --- a/sys/arch/arm/cortex/agtimer.c +++ b/sys/arch/arm/cortex/agtimer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agtimer.c,v 1.17 2023/02/04 19:19:36 cheloha Exp $ */ +/* $OpenBSD: agtimer.c,v 1.18 2023/07/25 18:16:19 cheloha Exp $ */ /* * Copyright (c) 2011 Dale Rahn * Copyright (c) 2013 Patrick Wildt @@ -288,7 +288,6 @@ agtimer_delay(u_int usecs) void agtimer_setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } void diff --git a/sys/arch/arm/cortex/amptimer.c b/sys/arch/arm/cortex/amptimer.c index 455d75e2aeb..6fcf495791c 100644 --- a/sys/arch/arm/cortex/amptimer.c +++ b/sys/arch/arm/cortex/amptimer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: amptimer.c,v 1.16 2023/02/04 19:19:36 cheloha Exp $ */ +/* $OpenBSD: amptimer.c,v 1.17 2023/07/25 18:16:19 cheloha Exp $ */ /* * Copyright (c) 2011 Dale Rahn * @@ -343,7 +343,6 @@ amptimer_delay(u_int usecs) void amptimer_setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } void diff --git a/sys/arch/arm/include/cpu.h b/sys/arch/arm/include/cpu.h index 7f6b95ccf92..986e1798cb9 100644 --- a/sys/arch/arm/include/cpu.h +++ b/sys/arch/arm/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.62 2023/01/17 02:27:14 cheloha Exp $ */ +/* $OpenBSD: cpu.h,v 1.63 2023/07/25 18:16:19 cheloha Exp $ */ /* $NetBSD: cpu.h,v 1.34 2003/06/23 11:01:08 martin Exp $ */ /* @@ -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]; diff --git a/sys/arch/arm64/dev/agtimer.c b/sys/arch/arm64/dev/agtimer.c index d7909051dfe..08e93b4b080 100644 --- a/sys/arch/arm64/dev/agtimer.c +++ b/sys/arch/arm64/dev/agtimer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agtimer.c,v 1.22 2023/02/04 19:19:36 cheloha Exp $ */ +/* $OpenBSD: agtimer.c,v 1.23 2023/07/25 18:16:19 cheloha Exp $ */ /* * Copyright (c) 2011 Dale Rahn * Copyright (c) 2013 Patrick Wildt @@ -354,7 +354,6 @@ agtimer_delay(u_int usecs) void agtimer_setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } void diff --git a/sys/arch/arm64/include/cpu.h b/sys/arch/arm64/include/cpu.h index 36d2d40ac8c..ab9fdcb3758 100644 --- a/sys/arch/arm64/include/cpu.h +++ b/sys/arch/arm64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.37 2023/07/13 08:33:36 kettenis Exp $ */ +/* $OpenBSD: cpu.h,v 1.38 2023/07/25 18:16:20 cheloha Exp $ */ /* * Copyright (c) 2016 Dale Rahn * @@ -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]; diff --git a/sys/arch/armv7/omap/dmtimer.c b/sys/arch/armv7/omap/dmtimer.c index 753e49badc3..2d0995112c3 100644 --- a/sys/arch/armv7/omap/dmtimer.c +++ b/sys/arch/armv7/omap/dmtimer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dmtimer.c,v 1.18 2023/02/04 19:19:36 cheloha Exp $ */ +/* $OpenBSD: dmtimer.c,v 1.19 2023/07/25 18:16:19 cheloha Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn * Copyright (c) 2013 Raphael Graf @@ -317,7 +317,6 @@ dmtimer_delay(u_int usecs) void dmtimer_setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } diff --git a/sys/arch/armv7/omap/gptimer.c b/sys/arch/armv7/omap/gptimer.c index 28ad42bb8a3..6cac9de9461 100644 --- a/sys/arch/armv7/omap/gptimer.c +++ b/sys/arch/armv7/omap/gptimer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gptimer.c,v 1.19 2023/02/04 19:19:36 cheloha Exp $ */ +/* $OpenBSD: gptimer.c,v 1.20 2023/07/25 18:16:19 cheloha Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn * @@ -326,7 +326,6 @@ gptimer_delay(u_int usecs) void gptimer_setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } diff --git a/sys/arch/armv7/sunxi/sxitimer.c b/sys/arch/armv7/sunxi/sxitimer.c index d547e014b4a..9383282e440 100644 --- a/sys/arch/armv7/sunxi/sxitimer.c +++ b/sys/arch/armv7/sunxi/sxitimer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sxitimer.c,v 1.20 2023/02/04 19:19:36 cheloha Exp $ */ +/* $OpenBSD: sxitimer.c,v 1.21 2023/07/25 18:16:19 cheloha Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn * Copyright (c) 2013 Raphael Graf @@ -299,7 +299,6 @@ sxitimer_delay(u_int usecs) void sxitimer_setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } u_int diff --git a/sys/arch/hppa/dev/clock.c b/sys/arch/hppa/dev/clock.c index f0ebd389204..8e5a10eb147 100644 --- a/sys/arch/hppa/dev/clock.c +++ b/sys/arch/hppa/dev/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.35 2023/02/04 19:19:36 cheloha Exp $ */ +/* $OpenBSD: clock.c,v 1.36 2023/07/25 18:16:20 cheloha Exp $ */ /* * Copyright (c) 1998-2003 Michael Shalayeff @@ -141,7 +141,6 @@ itmr_intr(void *v) void setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } u_int diff --git a/sys/arch/hppa/include/cpu.h b/sys/arch/hppa/include/cpu.h index 5ccc82f4890..91b7de98af8 100644 --- a/sys/arch/hppa/include/cpu.h +++ b/sys/arch/hppa/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.99 2023/01/31 15:18:54 deraadt Exp $ */ +/* $OpenBSD: cpu.h,v 1.100 2023/07/25 18:16:20 cheloha Exp $ */ /* * Copyright (c) 2000-2004 Michael Shalayeff @@ -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]; diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h index 10f5f3e086c..2496ba30140 100644 --- a/sys/arch/i386/include/cpu.h +++ b/sys/arch/i386/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.181 2022/12/06 01:56:44 cheloha Exp $ */ +/* $OpenBSD: cpu.h,v 1.182 2023/07/25 18:16:20 cheloha Exp $ */ /* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */ /*- @@ -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]; diff --git a/sys/arch/i386/isa/clock.c b/sys/arch/i386/isa/clock.c index 4c3f402272d..48d96756ab3 100644 --- a/sys/arch/i386/isa/clock.c +++ b/sys/arch/i386/isa/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.64 2023/02/04 19:19:36 cheloha Exp $ */ +/* $OpenBSD: clock.c,v 1.65 2023/07/25 18:16:20 cheloha Exp $ */ /* $NetBSD: clock.c,v 1.39 1996/05/12 23:11:54 mycroft Exp $ */ /*- @@ -663,7 +663,6 @@ setstatclockrate(int arg) mc146818_write(NULL, MC_REGA, MC_BASE_32_KHz | MC_RATE_1024_Hz); } - clockintr_setstatclockrate(arg); } void diff --git a/sys/arch/luna88k/luna88k/clock.c b/sys/arch/luna88k/luna88k/clock.c index 2a298aea4c3..479bf89770d 100644 --- a/sys/arch/luna88k/luna88k/clock.c +++ b/sys/arch/luna88k/luna88k/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.16 2022/12/06 00:56:52 cheloha Exp $ */ +/* $OpenBSD: clock.c,v 1.17 2023/07/25 18:16:20 cheloha Exp $ */ /* $NetBSD: clock.c,v 1.2 2000/01/11 10:29:35 nisimura Exp $ */ /* @@ -152,7 +152,6 @@ cpu_initclocks() void setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } /* diff --git a/sys/arch/m88k/include/cpu.h b/sys/arch/m88k/include/cpu.h index ad2864e16cf..578e71414d1 100644 --- a/sys/arch/m88k/include/cpu.h +++ b/sys/arch/m88k/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.72 2023/01/31 15:18:54 deraadt Exp $ */ +/* $OpenBSD: cpu.h,v 1.73 2023/07/25 18:16:20 cheloha Exp $ */ /* * Copyright (c) 1996 Nivas Madhur * Copyright (c) 1992, 1993 @@ -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]; diff --git a/sys/arch/macppc/macppc/clock.c b/sys/arch/macppc/macppc/clock.c index cbffc4a1d72..5edfb978eb2 100644 --- a/sys/arch/macppc/macppc/clock.c +++ b/sys/arch/macppc/macppc/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.54 2023/02/04 23:17:05 cheloha Exp $ */ +/* $OpenBSD: clock.c,v 1.55 2023/07/25 18:16:20 cheloha Exp $ */ /* $NetBSD: clock.c,v 1.1 1996/09/30 16:34:40 ws Exp $ */ /* @@ -234,7 +234,6 @@ delay(unsigned n) void setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } u_int diff --git a/sys/arch/mips64/include/cpu.h b/sys/arch/mips64/include/cpu.h index c71b25646ca..3a1ca4191e9 100644 --- a/sys/arch/mips64/include/cpu.h +++ b/sys/arch/mips64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.141 2023/01/11 03:19:52 visa Exp $ */ +/* $OpenBSD: cpu.h,v 1.142 2023/07/25 18:16:20 cheloha Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -200,6 +200,7 @@ struct cpu_info { #endif #ifdef GPROF struct gmonparam *ci_gmon; + struct clockintr *ci_gmonclock; #endif char ci_panicbuf[512]; }; diff --git a/sys/arch/mips64/mips64/mips64_machdep.c b/sys/arch/mips64/mips64/mips64_machdep.c index 27d1e442158..aaa7a04a234 100644 --- a/sys/arch/mips64/mips64/mips64_machdep.c +++ b/sys/arch/mips64/mips64/mips64_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mips64_machdep.c,v 1.41 2023/02/04 19:19:36 cheloha Exp $ */ +/* $OpenBSD: mips64_machdep.c,v 1.42 2023/07/25 18:16:20 cheloha Exp $ */ /* * Copyright (c) 2009, 2010, 2012 Miodrag Vallat. @@ -333,7 +333,6 @@ cpu_initclocks(void) void setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } /* diff --git a/sys/arch/powerpc/include/cpu.h b/sys/arch/powerpc/include/cpu.h index e80d74e059f..4eee78a2af3 100644 --- a/sys/arch/powerpc/include/cpu.h +++ b/sys/arch/powerpc/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.74 2022/11/29 00:58:05 cheloha Exp $ */ +/* $OpenBSD: cpu.h,v 1.75 2023/07/25 18:16:20 cheloha Exp $ */ /* $NetBSD: cpu.h,v 1.1 1996/09/30 16:34:21 ws Exp $ */ /* @@ -89,6 +89,7 @@ struct cpu_info { #endif #ifdef GPROF struct gmonparam *ci_gmon; + struct clockintr *ci_gmonclock; #endif char ci_panicbuf[512]; }; diff --git a/sys/arch/powerpc64/powerpc64/clock.c b/sys/arch/powerpc64/powerpc64/clock.c index e9e111de040..e17cdacaf1e 100644 --- a/sys/arch/powerpc64/powerpc64/clock.c +++ b/sys/arch/powerpc64/powerpc64/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.10 2023/02/04 23:20:54 cheloha Exp $ */ +/* $OpenBSD: clock.c,v 1.11 2023/07/25 18:16:21 cheloha Exp $ */ /* * Copyright (c) 2020 Mark Kettenis @@ -141,7 +141,6 @@ decr_intr(struct trapframe *frame) void setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } void diff --git a/sys/arch/riscv64/include/cpu.h b/sys/arch/riscv64/include/cpu.h index 4d0aca11991..89ae2951620 100644 --- a/sys/arch/riscv64/include/cpu.h +++ b/sys/arch/riscv64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.15 2022/11/19 16:02:37 cheloha Exp $ */ +/* $OpenBSD: cpu.h,v 1.16 2023/07/25 18:16:21 cheloha Exp $ */ /* * Copyright (c) 2019 Mike Larkin @@ -119,6 +119,7 @@ struct cpu_info { #ifdef GPROF struct gmonparam *ci_gmon; + struct clockintr *ci_gmonclock; #endif char ci_panicbuf[512]; diff --git a/sys/arch/riscv64/riscv64/clock.c b/sys/arch/riscv64/riscv64/clock.c index 9c66f41fa8f..0648a744179 100644 --- a/sys/arch/riscv64/riscv64/clock.c +++ b/sys/arch/riscv64/riscv64/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.9 2023/02/04 19:19:37 cheloha Exp $ */ +/* $OpenBSD: clock.c,v 1.10 2023/07/25 18:16:21 cheloha Exp $ */ /* * Copyright (c) 2020 Mark Kettenis @@ -144,7 +144,6 @@ clock_intr(void *frame) void setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } void diff --git a/sys/arch/sh/include/cpu.h b/sys/arch/sh/include/cpu.h index 8bd445f1737..a080751e833 100644 --- a/sys/arch/sh/include/cpu.h +++ b/sys/arch/sh/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.34 2022/12/06 01:19:35 cheloha Exp $ */ +/* $OpenBSD: cpu.h,v 1.35 2023/07/25 18:16:21 cheloha Exp $ */ /* $NetBSD: cpu.h,v 1.41 2006/01/21 04:24:12 uwe Exp $ */ /*- @@ -68,6 +68,7 @@ struct cpu_info { #endif #ifdef GPROF struct gmonparam *ci_gmon; + struct clockintr *ci_gmonclock; #endif int ci_want_resched; diff --git a/sys/arch/sh/sh/clock.c b/sys/arch/sh/sh/clock.c index 409a1833482..2e3a8b62ee3 100644 --- a/sys/arch/sh/sh/clock.c +++ b/sys/arch/sh/sh/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.14 2023/04/10 04:21:20 jsg Exp $ */ +/* $OpenBSD: clock.c,v 1.15 2023/07/25 18:16:21 cheloha Exp $ */ /* $NetBSD: clock.c,v 1.32 2006/09/05 11:09:36 uwe Exp $ */ /*- @@ -203,7 +203,6 @@ sh_clock_get_pclock(void) void setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } u_int diff --git a/sys/arch/sparc64/include/cpu.h b/sys/arch/sparc64/include/cpu.h index 6656e84af92..995203c5633 100644 --- a/sys/arch/sparc64/include/cpu.h +++ b/sys/arch/sparc64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.101 2023/01/13 03:22:18 cheloha Exp $ */ +/* $OpenBSD: cpu.h,v 1.102 2023/07/25 18:16:21 cheloha Exp $ */ /* $NetBSD: cpu.h,v 1.28 2001/06/14 22:56:58 thorpej Exp $ */ /* @@ -165,6 +165,7 @@ struct cpu_info { #endif #ifdef GPROF struct gmonparam *ci_gmon; + struct clockintr *ci_gmonclock; #endif char ci_panicbuf[512]; }; diff --git a/sys/arch/sparc64/sparc64/clock.c b/sys/arch/sparc64/sparc64/clock.c index fcb0075e88e..64635f6f025 100644 --- a/sys/arch/sparc64/sparc64/clock.c +++ b/sys/arch/sparc64/sparc64/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.77 2023/04/28 18:27:55 cheloha Exp $ */ +/* $OpenBSD: clock.c,v 1.78 2023/07/25 18:16:21 cheloha Exp $ */ /* $NetBSD: clock.c,v 1.41 2001/07/24 19:29:25 eeh Exp $ */ /* @@ -576,7 +576,6 @@ cpu_initclocks(void) void setstatclockrate(int newhz) { - clockintr_setstatclockrate(newhz); } /* diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 4bc588d03ba..dfe8dbe7494 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_clock.c,v 1.108 2023/04/25 00:58:47 cheloha Exp $ */ +/* $OpenBSD: kern_clock.c,v 1.109 2023/07/25 18:16:19 cheloha Exp $ */ /* $NetBSD: kern_clock.c,v 1.34 1996/06/09 04:51:03 briggs Exp $ */ /*- @@ -49,10 +49,6 @@ #include #include -#if defined(GPROF) || defined(DDBPROF) -#include -#endif - #include "dt.h" #if NDT > 0 #include @@ -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++; diff --git a/sys/kern/kern_clockintr.c b/sys/kern/kern_clockintr.c index ee66e4f4ac5..9a9d912f109 100644 --- a/sys/kern/kern_clockintr.c +++ b/sys/kern/kern_clockintr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_clockintr.c,v 1.27 2023/07/02 19:02:27 cheloha Exp $ */ +/* $OpenBSD: kern_clockintr.c,v 1.28 2023/07/25 18:16:19 cheloha Exp $ */ /* * Copyright (c) 2003 Dale Rahn * Copyright (c) 2020 Mark Kettenis @@ -32,39 +32,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 */ - -uint64_t clockintr_advance(struct clockintr *, uint64_t); -void clockintr_cancel(struct clockintr *); +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 */ + 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 +59,8 @@ uint64_t nsec_advance(uint64_t *, uint64_t, uint64_t); 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 +69,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 +475,6 @@ clockintr_stagger(struct clockintr *cl, uint64_t period, u_int n, u_int count) 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 +509,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); diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index f4ac3817711..064195995b6 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sched.c,v 1.79 2023/07/14 07:07:08 claudio Exp $ */ +/* $OpenBSD: kern_sched.c,v 1.80 2023/07/25 18:16:19 cheloha Exp $ */ /* * Copyright (c) 2007, 2008 Artur Grabowski * @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include @@ -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); @@ -214,6 +225,11 @@ sched_exit(struct proc *p) 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); #ifdef MULTIPROCESSOR diff --git a/sys/kern/sched_bsd.c b/sys/kern/sched_bsd.c index cdb2082729c..784e7fde933 100644 --- a/sys/kern/sched_bsd.c +++ b/sys/kern/sched_bsd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sched_bsd.c,v 1.77 2023/07/11 07:02:43 claudio Exp $ */ +/* $OpenBSD: sched_bsd.c,v 1.78 2023/07/25 18:16:19 cheloha Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /*- @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -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. @@ -393,6 +400,14 @@ mi_switch(void) */ 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); #ifdef MULTIPROCESSOR diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c index a93b6df9887..850e0fb3b09 100644 --- a/sys/kern/subr_prof.c +++ b/sys/kern/subr_prof.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_prof.c,v 1.35 2023/06/02 17:44:29 cheloha Exp $ */ +/* $OpenBSD: subr_prof.c,v 1.36 2023/07/25 18:16:19 cheloha Exp $ */ /* $NetBSD: subr_prof.c,v 1.12 1996/04/22 01:38:50 christos Exp $ */ /*- @@ -34,13 +34,17 @@ #include #include +#include +#include #include #include #include #include #include #include +#include +uint32_t profclock_period; #if defined(GPROF) || defined(DDBPROF) #include @@ -60,6 +64,8 @@ u_int gmon_cpu_count; /* [K] number of CPUs with profiling enabled */ extern char etext[]; +void gmonclock(struct clockintr *, void *); + void prof_init(void) { @@ -95,6 +101,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 +138,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 +160,7 @@ prof_state_toggle(struct gmonparam *gp, int oldstate) if (error == 0) { if (++gmon_cpu_count == 1) startprofclock(&process0); + clockintr_advance(ci->ci_gmonclock, profclock_period); } break; default: @@ -152,6 +168,7 @@ prof_state_toggle(struct gmonparam *gp, int oldstate) 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 +218,7 @@ sysctl_doprof(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 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 +235,31 @@ sysctl_doprof(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, } /* 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 +289,7 @@ sys_profil(struct proc *p, void *v, register_t *retval) return (EINVAL); if (SCARG(uap, scale) == 0) { stopprofclock(pr); + need_resched(curcpu()); return (0); } upp = &pr->ps_prof; @@ -259,10 +302,31 @@ sys_profil(struct proc *p, void *v, register_t *retval) 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); + } +} + /* * Scale is a fixed-point number with the binary point 16 bits * into the value, and is <= 1.0. pc is at most 32 bits, so the diff --git a/sys/sys/clockintr.h b/sys/sys/clockintr.h index c6e3659d0af..a46a3114462 100644 --- a/sys/sys/clockintr.h +++ b/sys/sys/clockintr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: clockintr.h,v 1.8 2023/06/15 22:18:06 cheloha Exp $ */ +/* $OpenBSD: clockintr.h,v 1.9 2023/07/25 18:16:19 cheloha Exp $ */ /* * Copyright (c) 2020-2022 Scott Cheloha * @@ -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); diff --git a/sys/sys/resourcevar.h b/sys/sys/resourcevar.h index a17302d9338..d25840445a6 100644 --- a/sys/sys/resourcevar.h +++ b/sys/sys/resourcevar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: resourcevar.h,v 1.26 2023/04/25 00:58:47 cheloha Exp $ */ +/* $OpenBSD: resourcevar.h,v 1.27 2023/07/25 18:16:19 cheloha Exp $ */ /* $NetBSD: resourcevar.h,v 1.12 1995/11/22 23:01:53 cgd Exp $ */ /* @@ -60,8 +60,13 @@ do { \ #include /* 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; diff --git a/sys/sys/sched.h b/sys/sys/sched.h index e5d461dcf81..8673205dc7c 100644 --- a/sys/sys/sched.h +++ b/sys/sys/sched.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sched.h,v 1.57 2020/12/25 12:49:31 visa Exp $ */ +/* $OpenBSD: sched.h,v 1.58 2023/07/25 18:16:19 cheloha Exp $ */ /* $NetBSD: sched.h,v 1.2 1999/02/28 18:14:58 ross Exp $ */ /*- @@ -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 */ -- 2.20.1