style(9) rules for nested includes

John Baldwin jhb at freebsd.org
Thu Mar 10 20:28:20 UTC 2011


On Thursday, March 10, 2011 3:10:58 pm mdf at freebsd.org wrote:
> On Thu, Mar 10, 2011 at 11:46 AM, John Baldwin <jhb at freebsd.org> wrote:
> > On Thursday, March 10, 2011 12:17:28 pm mdf at freebsd.org wrote:
> >> I recall a recent discussion/PR about nested includes in the context
> >> of <sys/linker_set.h> and <sys/queue.h> being a few of the only ones
> >> allowed.  However, I don't see anything in style(9) about this.
> >
> > bde@ is probably the most authoritative.  My understanding is that the only
> > nested includes allowed in sys/sys/*.h are the two listed above and any header
> > that starts with an underscore (sys/_mutex.h, etc.).  The underscore variants
> > were added to allow nested includes when absolutely necessary, but those
> > includes are the bare minimum required to define structures, etc.
> >
> >> Now we come to the reason I ask.  I'm working on a patch to change the
> >> static sysctl code to use the standard SYSININT/SYSUNINIT code rather
> >> than have special treatment in kern_linker.c, but to do this I need to
> >> either change quite a few places that include <sys/sysctl.h>, or
> >> include <sys/kernel.h> instead of <sys/linker_set.h> in sysctl.h, as
> >> the SI_SUB_SYSCTLS value isn't visible otherwise.
> >
> > Hmm, what is the reason to use SYSINIT's instead of a dedicated linker set?
> 
> Mostly for consistency.  The DB_COMMAND linker set was changed to use
> SYSINITs for version 8, and AFIAK SYSCTL is the only global kernel
> thing using a separate linker set.

That was because DB commands in modules just didn't work at all before. :)

> There's also a minor bug in initialization ordering where a static
> SYSCTL_PROC could use a lock initialized by SX_SYSINIT or MTX_SYSINIT,
> but at runtime module load the sysctl is exposed before the
> SI_SUB_LOCK stage has run, so in theory someone doing sysctl -a would
> crash the kernel on an attempt to lock an uninitialized mtx/sx.  We
> saw this happen once at Isilon.

Hmm, this is a legitimate reason, though I'd be tempted to fix that by just
registering sysctls after sysinit's have been invoked and vice versa on
unload.  It seems that would be a simpler fix with far less code churn and
not having to deal with the nested include mess, etc.

One thing I often do, btw when dealing these sorts of interdependencies in a
loadable module, is to use a single SYSINIT or module event handler to do all
the setup and teardown of a single kld.  This lets you handle errors far
better (SYSINIT's don't allow for that at all) and more explicitly order the
set of operations.

-- 
John Baldwin


More information about the freebsd-arch mailing list