reboot or shutdown not working with -current

Nate Lawson nate at root.org
Fri Jun 4 19:47:08 GMT 2004


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
> > > @@ -376,8 +376,7 @@
> > >
> > >      /* 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.

-Nate


More information about the freebsd-current mailing list