From 0c617055fdbf512b216ce7871dd551e09333098d Mon Sep 17 00:00:00 2001 From: cheloha Date: Tue, 25 Apr 2023 01:32:36 +0000 Subject: [PATCH] prof_state_toggle: keep a count of CPUs with profiling enabled On MULTIPROCESSOR systems, the following sequence of kgmon(8) invocations leaves the statclock() frequency at stathz when there is still a CPU on the system where the gmon state is GMON_PROF_ON: # kgmon -c 0 -b # kgmon -c 1 -b # kgmon -c 0 -h The problem is that we aren't counting CPUs with profiling enabled. Add "gmon_cpu_count" to keep a count. Call startprofclock() for the first CPU to enable profiling and stopprofclock() for the last CPU to disable profiling. --- sys/kern/subr_prof.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c index 5f944cf6a4e..c578c937094 100644 --- a/sys/kern/subr_prof.c +++ b/sys/kern/subr_prof.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_prof.c,v 1.32 2023/04/25 00:58:47 cheloha Exp $ */ +/* $OpenBSD: subr_prof.c,v 1.33 2023/04/25 01:32:36 cheloha Exp $ */ /* $NetBSD: subr_prof.c,v 1.12 1996/04/22 01:38:50 christos Exp $ */ /*- @@ -55,6 +55,7 @@ * until we're sure they are in a sane state. */ int gmoninit = 0; +u_int gmon_cpu_count; /* [K] number of CPUs with profiling enabled */ extern char etext[]; @@ -126,6 +127,8 @@ prof_state_toggle(struct gmonparam *gp, int oldstate) { int error = 0; + KERNEL_ASSERT_LOCKED(); + if (gp->state == oldstate) return (0); @@ -138,15 +141,18 @@ prof_state_toggle(struct gmonparam *gp, int oldstate) */ error = db_prof_enable(); #endif - if (error == 0) - startprofclock(&process0); + if (error == 0) { + if (++gmon_cpu_count == 1) + startprofclock(&process0); + } break; default: error = EINVAL; gp->state = GMON_PROF_OFF; /* FALLTHROUGH */ case GMON_PROF_OFF: - stopprofclock(&process0); + if (--gmon_cpu_count == 0) + stopprofclock(&process0); #if !defined(GPROF) db_prof_disable(); #endif -- 2.20.1