> Date: Tue, 11 Jul 2023 15:28:22 -0500
> From: Scott Cheloha <scottchel...@gmail.com>
> 
> On Mon, Jul 10, 2023 at 10:41:15AM -0500, Scott Cheloha wrote:
> > On Mon, Jul 10, 2023 at 05:19:35PM +0200, Mark Kettenis wrote:
> > > > Date: Mon, 10 Jul 2023 09:57:39 -0500
> > > > From: Scott Cheloha <scottchel...@gmail.com>
> > > > 
> > > > On Mon, Jul 10, 2023 at 07:42:55AM -0600, Theo de Raadt wrote:
> > > > > I dare you to write the simplest fix for this, instead of a diff that
> > > > > scrolls by.
> > > > 
> > > > This patch seems to work.  Will need to bang on it for a few more days.
> > > > 
> > > > 1. Disable gmoninit after sched_stop_scondary_cpus().  The secondary
> > > >    CPUs have halted, so we aren't racing sysctl(2) on a secondary CPU.
> > > > 
> > > > 2. Restore gmoninit between resume_mp() and 
> > > > sched_start_secondary_cpus().
> > > >    The secondary CPUs are out of cpu_hatch(), which is probably where we
> > > >    are crashing during resume.  The secondary CPUs haven't started
> > > >    scheduling yet, so we aren't racing sysctl(2).
> > > 
> > > It is still a bit scary to have cpu_hatch() call _mcount() but I guess
> > > adding __attribute__((no_profile)) to all of the functions called by
> > > cpu_hatch() isn't really workable either.
> > > 
> > > That said...
> > > 
> > > > Index: subr_suspend.c
> > > > ===================================================================
> > > > RCS file: /cvs/src/sys/kern/subr_suspend.c,v
> > > > retrieving revision 1.15
> > > > diff -u -p -r1.15 subr_suspend.c
> > > > --- subr_suspend.c      2 Jul 2023 19:02:27 -0000       1.15
> > > > +++ subr_suspend.c      10 Jul 2023 14:51:01 -0000
> > > > @@ -18,6 +18,7 @@
> > > >  
> > > >  #include <sys/param.h>
> > > >  #include <sys/systm.h>
> > > > +#include <sys/atomic.h>
> > > >  #include <sys/buf.h>
> > > >  #include <sys/clockintr.h>
> > > >  #include <sys/reboot.h>
> > > > @@ -100,6 +101,14 @@ top:
> > > >  #ifdef MULTIPROCESSOR
> > > >         sched_stop_secondary_cpus();
> > > >         KASSERT(CPU_IS_PRIMARY(curcpu()));
> > > > +#endif
> > > > +#ifdef GPROF
> > > > +       extern int gmoninit;
> > > > +       int gmon_state = gmoninit;
> > > 
> > > No variable declarations in the middle of functions please.
> > 
> > Yep, moved up.
> > 
> > > > +       gmoninit = 0;
> > > > +       membar_producer();
> > > 
> > > Why are you messing with memory barriers here?
> > > 
> > > > +#endif
> > > > +#ifdef MULTIPROCESSOR
> > > >         sleep_mp();
> > > >  #endif
> > > >  
> > > > @@ -172,6 +181,12 @@ fail_suspend:
> > > >         resume_randomness(rndbuf, rndbuflen);
> > > >  #ifdef MULTIPROCESSOR
> > > >         resume_mp();
> > > > +#endif
> > > > +#ifdef GPROF
> > > > +       gmoninit = gmon_state;
> > > > +       membar_producer();
> > > 
> > > And here?
> > 
> > gmoninit is not volatile.  I had this idea that I wanted the store to
> > be globally visible before proceeding.  But you and Theo are telling
> > me I don't need the barrier.  I'll take your word for it, dropped.
> 
> ... is this ok or is something still amiss here?

ok kettenis@

> Index: subr_suspend.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/subr_suspend.c,v
> retrieving revision 1.15
> diff -u -p -r1.15 subr_suspend.c
> --- subr_suspend.c    2 Jul 2023 19:02:27 -0000       1.15
> +++ subr_suspend.c    11 Jul 2023 20:27:50 -0000
> @@ -26,6 +26,9 @@
>  #include <sys/mount.h>
>  #include <sys/syscallargs.h>
>  #include <dev/wscons/wsdisplayvar.h>
> +#ifdef GPROF
> +#include <sys/gmon.h>
> +#endif
>  #ifdef HIBERNATE
>  #include <sys/hibernate.h>
>  #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);
> 

Reply via email to