From 3772e814e0ead154912b1426b780015a463af85c Mon Sep 17 00:00:00 2001 From: cheloha Date: Wed, 12 Jul 2023 18:40:06 +0000 Subject: [PATCH] GPROF: sleep_state: disable _mcount() across suspend/resume Something in the amd64 resume path doesn't agree with _mcount(), so suspend/resume always fails if gmoninit is non-zero. It would be nice if GPROF kernels didn't crash during resume. In sleep_state(), (1) clear gmoninit after sched_stop_secondary_cpus() so the primary CPU isn't racing sysctl(2) on another CPU, and (2) restore gmoninit just after resume_mp() so the secondary CPUs are out of cpu_hatch() and away from whatever is causing the crash before _mcount() is reenabled. Lots of input from claudio@, deraadt@, and kettenis@. Thread 1: https://marc.info/?l=openbsd-tech&m=168721453821801&w=2 Thread 2: https://marc.info/?l=openbsd-tech&m=168892518722935&w=2 ok kettenis@ deraadt@ --- sys/kern/subr_suspend.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/sys/kern/subr_suspend.c b/sys/kern/subr_suspend.c index 833c918d9f0..1b4f4062918 100644 --- a/sys/kern/subr_suspend.c +++ b/sys/kern/subr_suspend.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_suspend.c,v 1.15 2023/07/02 19:02:27 cheloha Exp $ */ +/* $OpenBSD: subr_suspend.c,v 1.16 2023/07/12 18:40:06 cheloha Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert * Copyright (c) 2005 Jordan Hargrave @@ -26,6 +26,9 @@ #include #include #include +#ifdef GPROF +#include +#endif #ifdef HIBERNATE #include #endif @@ -49,6 +52,9 @@ sleep_state(void *v, int sleepmode) extern int perflevel; size_t rndbuflen; char *rndbuf; +#ifdef GPROF + int gmon_state; +#endif #if NSOFTRAID > 0 extern void sr_quiesce(void); #endif @@ -100,6 +106,12 @@ top: #ifdef MULTIPROCESSOR sched_stop_secondary_cpus(); KASSERT(CPU_IS_PRIMARY(curcpu())); +#endif +#ifdef GPROF + gmon_state = gmoninit; + gmoninit = 0; +#endif +#ifdef MULTIPROCESSOR sleep_mp(); #endif @@ -172,6 +184,11 @@ fail_suspend: resume_randomness(rndbuf, rndbuflen); #ifdef MULTIPROCESSOR resume_mp(); +#endif +#ifdef GPROF + gmoninit = gmon_state; +#endif +#ifdef MULTIPROCESSOR sched_start_secondary_cpus(); #endif vfs_stall(curproc, 0); -- 2.20.1