[Bug 298245] `shutdown -h now' use 100% CPU time

From: <bugzilla-noreply_at_freebsd.org>
Date: Sun, 06 Sep 2026 20:23:14 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=298245

Michael Osipov <michaelo@FreeBSD.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |michaelo@FreeBSD.org

--- Comment #1 from Michael Osipov <michaelo@FreeBSD.org> ---
(In reply to Wolfram Schneider from comment #0)

  Root cause (from source)

  shutdown -h triggers shutdown_halt() in sys/kern/kern_shutdown.c:638-657,
which prints "Please press any key to reboot" and then calls cngetc().

  cngetc() in sys/kern/kern_cons.c:441-452:
  while ((c = cncheckc()) == -1)
      cpu_spinwait();

  cncheckc() just polls the console driver for a character; if none is ready it
returns -1 immediately. So this is a tight busy-poll loop, not a blocking wait.
cpu_spinwait() on amd64
  (sys/amd64/include/cpu.h:49) expands to ia32_pause() — the PAUSE instruction,
which is only a pipeline hint to reduce power/contention on real, modern
silicon. It does not actually halt the CPU or yield to
  the scheduler — the core keeps executing the poll loop as fast as possible,
hence 100% usage.

  This differs from the panic-reboot-wait path (kern_shutdown.c:674-680), which
polls cncheckc() inside a loop that calls DELAY(1000*100) (100ms) between
checks — a much cheaper poll. The halt path skips that
  pattern entirely and just spins raw.

  Why Debian doesn't show this: Linux's halt path parks the CPU with hlt/idle
states (interrupt-driven wakeup) rather than busy-polling for console input, so
it draws no CPU while waiting for a keypress.

  Likely fix direction: make cngetc()'s wait loop (or at least the one used
from shutdown_halt()) sleep/DELAY between polls, or place the CPU in a real
idle state and rely on a console interrupt to wake it,
  instead of a raw PAUSE-spin — consistent with what shutdown_panic() already
does for its post-panic key-wait.

-- 
You are receiving this mail because:
You are the assignee for the bug.