Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Apr 2011 14:42:49 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-stable@freebsd.org
Cc:        Daniel Gerzo <danger@freebsd.org>, Alexander Motin <mav@freebsd.org>, Ian Smith <smithi@nimnet.asn.au>
Subject:   Re: kern.smp.maxid error on i386 UP [was: powerd / cpufreq question]
Message-ID:  <201104251442.49926.jhb@freebsd.org>
In-Reply-To: <20110420164100.Y43371@sola.nimnet.asn.au>
References:  <4D9EEDAF.3020803@rulez.sk> <20110413024230.Y35056@sola.nimnet.asn.au> <20110420164100.Y43371@sola.nimnet.asn.au>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wednesday, April 20, 2011 1:02:09 pm Ian Smith wrote:
> On Wed, 13 Apr 2011, Ian Smith wrote:
>  > On Tue, 12 Apr 2011, Daniel Gerzo wrote:
>  >  > On 11.4.2011 6:08, Ian Smith wrote:
> [..]
>  >  > > Are those kern.cp_times values as they came, or did you remove trailing
>  >  > > zeroes?  Reason I ask is that on my Thinkpad T23, single-core 1133/733
>  >  > > MHz, sysctl kern.cp_time shows the usual 5 values, but kern.cp_times has
>  >  > > the same 5 values for cpu0, but then 5 zeroes for each of cpu1 through
>  >  > > cpu31, on 8.2-PRE about early January.  I need to update the script to
>  >  > > remove surplus data for non-existing cpus, but wonder if the extra data
>  >  > > also appeared on your 12 core box?
>  >  > 
>  >  > I haven't removed anything, it's a pure copy&paste.
>  > 
>  > Thanks.  I'll check the single-cpu case again after updating to 8.2-R
> 
> Ok, still a problem on at least my i386 single core Thinkpad T23 at 
> 8.2-R, since 8.0 I think, certainly evident in a sysctl -a at 8.1-R
> 
> FreeBSD t23.smithi.id.au 8.2-RELEASE FreeBSD 8.2-RELEASE #1: Thu Apr 14 
> 21:45:47 EST 2011 root@t23.smithi.id.au:/usr/obj/usr/src/sys/GENERIC i386
> 
> Verbose dmesg: http://smithi.id.au/t23_dmesg_boot-v.8.2-R.txt 
> sysctl -a:     http://smithi.id.au/t23_sysctl-a_8.2-R.txt
> 
> kern.ccpu: 0
>   <cpu count="1" mask="0x1">0</cpu>
> kern.smp.forward_signal_enabled: 1
> kern.smp.topology: 0
> kern.smp.cpus: 1
> kern.smp.disabled: 0
> kern.smp.active: 0
> kern.smp.maxcpus: 32
> kern.smp.maxid: 31	<<<<<<<
> hw.ncpu: 1
> 
> kern.cp_times: 38548 1 120437 195677 9660939 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> 
> /usr/src/sys/kern/kern_clock.c:
> return SYSCTL_OUT(req, 0, sizeof(long) * CPUSTATES * (mp_maxid + 1));
> 
> Consumers of kern.cp_times like powerd, top, dtrace? and others have to 
> loop over 32 cpus, all but one non-existent, and there seem to be many 
> places in the kernel doing eg: for (cpu = 0; cpu <= mp_maxid; cpu++) { 
> and while CPU_FOREACH / CPU_ABSENT will skip over them, seems wasteful 
> at best on machines least likely to have cycles to spare.
> 
> eg: powerd parses kern.cp_times to count cpus, wasting cycles adding 
> up the 31 'empty' cpus.  I haven't explored other userland consumers.
> 
> Clearly kern.smp.maxid (ie mp_maxid) should be 0, not 31.  On i386, 
> non-APIC i386 at least, mp_maxid is not set to (mp_ncpus - 1) as on some 
> other archs .. after having being initialised to (MAXCPU - 1) in 
> /sys/i386/i386/mp_machdep.c it's never updated for non-smp machines.

No, and your patch would break many things.

The existence of mp_maxid is to allow very early kernel startup to know the
largest possible CPU ID it has to contend with.  Specifically, this is used
by UMA to size an array of per-CPU bucket lists in UMA zones.  However,
this must be done before SI_SUB_KLD.  The i386 platform in 8.x and earlier
cannot enumerate CPUs until after SI_SUB_KLD in order to support having
ACPI in a kernel module (as acpi.ko).  For that reason, i386 cannot set
mp_maxid optimally.

Note that the only guarantee made with regards to mp_maxid is that all
CPU IDs for all active CPUs in the system will be <= mp_maxid.  There is
no guarantee of denseness of CPU IDs (there can be holes), or even that
the CPUs start at 0 (ACPI does require the BSP to be CPU 0 in its shutdown
code, but that requirement only applies to x86 and ia64).

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104251442.49926.jhb>