Re: reboot or shutdown not working with -current

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Fri, 4 Jun 2004 16:46:23 -0400
On Friday 04 June 2004 03:46 pm, Nate Lawson wrote:
> On Fri, 4 Jun 2004, John Baldwin wrote:
> > > > Index: acpi_cpu.c
> > > > ===================================================================
> > > > RCS file: /usr/cvs/src/sys/dev/acpica/acpi_cpu.c,v
> > > > retrieving revision 1.36
> > > > diff -u -r1.36 acpi_cpu.c
> > > > --- acpi_cpu.c  7 May 2004 05:22:37 -0000       1.36
> > > > +++ acpi_cpu.c  4 Jun 2004 14:44:33 -0000
> > > > _at__at_ -376,8 +376,7 _at__at_
> > > >
> > > >      /* Wait for all processors to exit acpi_cpu_idle(). */
> > > >      smp_rendezvous(NULL, NULL, NULL, NULL);
> > > > -    while (cpu_idle_busy > 0)
> > > > -       DELAY(1);
> > > > +    DELAY(1);
> > > >
> > > >      return_VALUE (0);
> > > >  }
> >
> > Yes, because the real bug is above.  Disabling interrupt preemption just
> > masks it.  The gory details are that almost all (in fact on UP, 100%) of
> > context switches away from the idlethread are due to interrupts.  When
> > interrupt preemption is enabled, this means that idle threads are
> > switched away from before they've had a chance to decrement the
> > cpu_idle_busy counter in acpi_cpu_idle().  Thus, when the thread doing
> > shutdown gets to this loop, it never terminates because the idlethread of
> > the CPU executing the shutdown request never gets a chance to go back and
> > decrement its idle_busy count.  In truth, you don't actually need the
> > loop, once you do the rendezvous, any other CPUs that are idle will wake
> > up, exit acpi_cpu_idle() and re-enter after finding no runnable jobs.  I
> > tracked this down after a couple of hours on Wednesday but was very busy
> > with ${REALJOB} work yesterday and haven't had a chance to send an e-mail
> > out about this.
>
> My goal with this originally was to drain all threads out of the idle
> handler before continuing the shutdown process.  The assumption that
> changed with the ithread commit was that the idle thread gets to run
> sometime after an interrupt occurs.  It's actually kind of tough to have
> a sched switch before any instructions get to execute after the "go to
> sleep" one since I profile the length of the sleep to figure out how deep
> a sleep to use the next cycle.  This is to keep sporadically loaded
> machines responsive.  So if a preemption can happen every sleep, I'll have
> to redo this approach and go with one that doesn't require profiling and
> executes no code after the sleep.

I think your current code is fine though.  As soon as you send out the IPI, 
any CPUs that are idle will bounce.  Is there anything dangerous after you 
enable interrupts again on the processor?  For C1, you don't seem to go near 
any ACPI-specific code after resume, and for C2/C3 you seem to defer enabling 
interrupts until you have read the counters (and I assume that C2/C3 resume 
doesn't actually handle the interrupt until you do sti) so you shouldn't have 
to worry about the CPU doing the shutdown since if it ever returns to the 
idlethread it will already be out of the critical section.  Thus, I don't 
think you need the while loop or busy counter at all.

-- 
John Baldwin <jhb_at_FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org
Received on Fri Jun 04 2004 - 11:45:53 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:56 UTC