Subject: Re: dynamic configuration (was Re: PR#4094)
To: Noriyuki Soda <soda@sra.co.jp>
From: Chris G. Demetriou <cgd@sibyte.com>
List: tech-kern
Date: 08/10/2000 13:43:43
soda@sra.co.jp (Noriyuki Soda) writes:
> > (4) there are workarounds even if none of the above can work for a
> >     specific case.
> 
> If there are other ways to do this, why don't you use the way ALWAYS?

Why use a shovel when you can use your hands?  If you use your hands,
you always have exact control of where the dirt goes, and better you
don't have to pay the cost to buy the shovel.  You don't have to carry
the shovel to and from your work site, either.

like it or not, we use the GNU toolchain.  there is no reasonable
alternative, nor is there now or really ever was there a credible
alternative which we could consider using, immediately or at any time
in the near future.  One of the big tasks on porters' lists of things
to do is bring up the tools if they don't work already, and so they
must already bear the cost of making the GNU tools go.  Once they're
up, we should bloody well use them (but, to be sure, we should be sure
to provide a hook by which their features aren't used for people with
problems bootstrapping).

(It's one thing to solve the problem for a kernel that you have full
source for, e.g. when you're developing a new port, and it's another
to solve the problem in the general case, e.g. when you want people to
be able to distribute .o files usable with a kernel.  My claim is that
with a workaroudn you can do the former, I don't think you can do the
latter.  I'm sure you could do either with config files, but the basic
issue of it being desirable to do math on the major numbers (i.e. my
comment about how to keep the numbers stable, in my response to mcr)
to provide some form of stability is still there i think, and you
can't get that unless you add a lot of hair to the config file syntax.
I think any solution which uses such workarounds should be intended
for bootstrapping only, just like e.g. it's OK to avoid using shared
libraries while you're bootstrapping, but not considered OK to avoid
them when your port is considered ready for general use.)

(Further, to repeat, the ability to put things in arbitrary sections
and aggregate them is pretty much a standard thing in any set of tools
which sanely support the ELF object format, and we're fairly committed
to that for new ports as well.)


> But there is one benefit in the way of "files.*" files.
> If a user do not need dynamic configuration (e.g. embeded application,
> for example), the way of "files.*" file works almost completely same
> with current way of conf.c (Only difference is that conf.c is 
> automatically generated.)
> In other words, "files.*" has less overhead in completely static
> configuration case.

run-time overhead at startup is not worth speaking of, in this case; a
few pointer derefs and function calls, etc.

run-time overhead in terms of memory _is_ worth talking about, and in
this case i'll concede that the cost of the few data structures that
are kept in memory and no longer used after init time may be
significant in some applications.

however, the same is true of a whole bunch of things, including but
not limited to all of the system init code and the vast majority of
device attach functions.

In general, a solution is needed for reclaiming _all_ of this memory.
(and, in fact, it's not even particularly difficult to do...  but it
requires use of some of those much-abhored compiler and linker
features.)


> Extracting major number from "files" files is far more easier than
> extracting it from C header files.

oh, really?

Every solution i've seen regarding the former involves a
custom-compiled tool, e.g. config, that's not always easy to make work
on a host system.  it may be part of config proper, which you're
assumed to already need, but the issue of then re-porting config at
least still remains.

On the other hand, the latter is simply a matter of feeding, e.g.:

	#include "foo.h"
	FOO_BAR

into cpp.

further, extracting the numbers is a relatively infrequent operation,
and, better than that, in the fullness of time should go the way of
the dodo in preference to a devfs anyway (at which time the hacks to
config should be _removed_ if they are made).  Seems to me that
modifying config to add more support re: devsw and major numbers is a
_negative_ change from a strategic point of view.


> Since configuration framework should know the major number (and bus
> locater informations and other informations in "files.*" files),
> describing it in "files.*" file is natural way.

But in fact, that's not true.

Locators and attachments and attributes, etc., are fundamentally
properties of devices and the busses they live on.

Major numbers are fundamentally properties of particular ports which
happen to include support for the devices.

you end up with a MD list of major numbers either way, and the only
real question is then is it best to encode it in an ill-defined
configuration language, or put it in a C header (knowing full well
that you'll actually need it in a C header for some purposes anyway).

You also then need to create the distinction in the config file
between 'devices which need major numbers specified' and those which
do not -- and you need to do more cross-checking at config time.

Finally, there's still all of the garbage around the device inits and
decls which still ends up being scattered across the tree, unless you
at minimum move those into the drivers.


> We don't have to use the linkerset feature of GNU toolchain for this.
> For example, we can simply use string address as malloc type.
> 	In <sys/malloc.h>:
> 		extern char M_FREE[];
> 		extern char M_MBUF[];
> 		extern char M_DEVBUF[];
> 			:
> 	In <kern/malloc.h>:
> 		char M_FREE[] = "free";
> 		char M_MBUF[] = "mbuf";
> 		char M_DEVBUF[] = "devbuf";
> 			:
> In this way, AFS source can define M_AFS by itself like follows:
> 		char M_AFS[] = "afs";
>
> Why do we have to depend on the linkerset feature of GNU toolchain,
> even if there is trivial (and simple, and less overhead) way to do it?

Because there are other issues around those constants that that
"scheme" -- i hesitate to call it even an attempt at a real solution
-- completely ignore.

e.g. the collection of statistics, the linking of those stastics into
a kernel global statistics list, etc.

You really have two choices about how to do the initalization of such
a list:

* do it automatically, perhaps using a list collected by config or a
linker feature.

* do it manually as part of an init function in every module that
might want such a thing.

You certainly could do the latter, but it's inarguably more
error-prone and fragile than doing it automatically, once you have the
basic list aggregation mechanism in place and functional.



cgd