dual core laptop running unbearably hot

Matthew Dillon dillon at apollo.backplane.com
Mon Dec 25 15:36:31 PST 2006


:% sysctl -a | grep -E 'cpu_idle|mplock_contention' && sleep 10 && sysctl -a | grep -E 'cpu_idle|mplock_contention'
:machdep.cpu_idle_hlt: 1
:machdep.cpu_idle_hltcnt: 6555821
:machdep.cpu_idle_spincnt: 42581416
:lwkt.mplock_contention_count: 51898977
:machdep.cpu_idle_hlt: 1
:machdep.cpu_idle_hltcnt: 6566696
:machdep.cpu_idle_spincnt: 42693684
:lwkt.mplock_contention_count: 52016936
:
:that's 1087 idle hlts, 11226 idle spins and 11795 mplock contentions.  this is on a mostly idle system.  mplock contention and idle spin counts correlate pretty well.  HLTs are executed much too seldom, though.

    On a mostly idle cpu HLT will be run approximately at some multiple of
    the clock interrupt rate (since that will be the only thing interrupting
    the HLT).  So.  10875 (not 1087, you missed a digit) over 10 seconds
    is about 1000/sec.  Sounds about right.

:>     We can't HLT when spinning on the MP lock because there will be no event
:>     to 'wake up' the cpu when the MP lock is released.
:
:i guess broadcasting an IPI is too slow or resource intensive.  but what i read MONITOR/MWAIT should be a possiblity to put the CPU to sleep and wake up on release (write) to the (MP)lock.  I'm not sure if MONITOR/MWAIT actually exists for dual core cpus or if it is exclusively for hyperthreading.

    I'd love an instruction like that.  I would assume that it would work for
    multi-core cpus too since it is probably based on monitoring the cache
    management bus.

:>     IPI operations only spin if the IPI software FIFO is full, and in that
:>     case they have to spin to avoid a livelock with another cpu.  But this
:>     case almost never happens.
:> 
:>     The scheduler doesn't really spin if it detects a pending IPI, it just
:>     loops up and calls splz() again to process the IPI.
:> 
:>     In the case of an interrupt being queued, its the same deal... it isn't
:>     really spinning.  It is detecting an unprocessed interrupt flag and
:>     then processing it.
:
:then i must misinterpret these lines (lwkt_thread.c):
:
:        } else {
:            /*
:             * We have nothing to run but only let the idle loop halt
:             * the cpu if there are no pending interrupts.
:             */
:            ntd = &gd->gd_idlethread;
:            if (gd->gd_reqflags & RQF_IDLECHECK_MASK)
:                ntd->td_flags |= TDF_IDLE_NOHLT;
:
:with (globaldata.h):
:#define RQF_IDLECHECK_MASK      (RQF_IPIQ|RQF_INTPEND)

    This won't get hit very often.  The case occurs to address a race
    between the idle thread being switched to and a new interrupt becoming
    pending.  It basically just causes the idle thread to immediately switch
    out again so the pending events can be processed.  The flag is cleared
    by the idle thread itself.

    We could probably streamline the check and put it in the core of the
    idle loop itself (after the CLI instruction).  In fact, this wouldn't
    be a bad idea.  These two pieces of code (the NOHLT hack and the idle
    thread procedure) have diverged a bit from their original intent.

    It is always possible that I made a mistake in the coding, too, but
    if cpu_idle_hltcnt is being incremented it is almost certain that 
    cpu_idle_hook() is being called which means HLT is being called.

						-Matt





More information about the Kernel mailing list