Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 05 Oct 2001 02:43:21 -0700
From:      Terry Lambert <tlambert2@mindspring.com>
To:        Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
Cc:        smp@freebsd.org
Subject:   Re: How to distinguish the SMP kernel and the UP kernel
Message-ID:  <3BBD80B9.4191B288@mindspring.com>
References:  <200110030310.MAA13836@zodiac.mech.utsunomiya-u.ac.jp>  <3BBB6757.9A668E99@mindspring.com> <200110041211.VAA24646@zodiac.mech.utsunomiya-u.ac.jp>

next in thread | previous in thread | raw e-mail | index | archive | help
Kazutaka YOKOTA wrote:
> >> Is there any way for the loadable module to detect if
> >> the kernel is configured for SMP or UP?
> >
> >There is a global variable, "ncpu".  Its name may have changed
> >recently, so you will want to look at the SYSCTL() stuff in
> >/sys/i386/i386 to be sure.
> 
> The sysctl variable hw.ncpu returns 1 in the UP kernel,
> and returns the number of active CPUs in the SMP kernel.
> 
> When hw.ncpu == 1, it doesn't necessarily signifies the kernel
> is configured for UP. Because it is perfectly permissible
> to run the SMP kernel on the multi-CPU motherboard with only one
> CPU installed...
> 
> Am I wrong?

No.

I assumed you wanted the information to determine how many
kernel threads, etc., to run in order to ensure that your
code would operate optimally to take advantage of the extra
hardware.  As you note, however, !SMP does not equal UP,
even though !UP equals SMP.

If the reason is for locking or structure sizes, then you
will have to create two modules: one for SMP, and one for
non-SMP.

I hesistate to tell you how to tell the difference, since I
would prefer that you not be able to write code that cares,
yet is able to run, since it sets a bad example, and is a
really, really ugly hack.  But...

A really ugly way to check would be to use the non-recursive
locking functions, create a lock, lock it, and then try a
non-blocking lock against yourself.  If it fails, then you
know you are SMP (the lock functions are defined), otherwise
you know you are compiled UP.

This doesn't really help with a loaded module, though, as
it will have the lock macros from when it was compiled, not
when it was loaded.

For a loaded module, you could look for a symbol that only
exists in the SMP case -- look for them in the mp_machdep.c
code -- they're there.

The problem with doing this is that, if you needed to care,
then you would have different structure sizes and macros in
scope at compilation time, and then you're still out of luck,
unless you are very, very careful, and drag along your own
copies of the code, as well as duplicate copies for struct
references, where SMP specific things are not all stored at
the end (arrays of structs would cause you trouble, too).
Even so, without this, you'll get undefined symbols when you
try to load the module, so the carting around your own code
is mandatory.  To find the symbol, you'll need to follow the
variable containing the booted kernel, open the file from
the kernel, and read the symbol table (ugh!), or some similar
approach: not pretty.

My advice: compile two versions of the module, and if you
have to do it, write a loader that does the symbol checking,
preferrably in user space.

Of course, you could always add a sysctl oid for "kern.smp"
to indicate whether or not it's compiled SMP -- but as I
said earlier, this would encourage what I personally would
consider really bad practice.

-- Terry

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-smp" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3BBD80B9.4191B288>