Subject: Re: resource allocation, pcmcia, isapnp, etc.
To: Noriyuki Soda <soda@sra.co.jp>
From: Justin T. Gibbs <gibbs@narnia.plutotech.com>
List: tech-kern
Date: 06/18/1999 21:00:18
>> I'm curious why you find DRIVER_MODULE worse than config.new's meta
>> information storage.  Can you give examples of both?  I don't
>> understand what you are objecting to here.  Can you provide more
>> details?
> 
> As far as you will support static configuration, the information
> represented by DRIVER_MODULE() is also needed for static
> configuration. But because DRIVER_MODULE() is embeded in C source, the
> information cannot be used by static configuration.

The information in DRIVER_MODULE() is available if you are statically
linked or not.  It is equivalent, as I understand the proposed (or
perhaps implemented) changes to config.new, to a binary version of
the 'files' file.  Can you be more specific about why you feel this
mechanism is inadequate for the statically linked case?  I have yet
to dynamically load a single KLD under new-bus, but all of my device
drivers still seem to work just fine. 8-)

> In newconfig, the information is represented by "files*" file,
> thus it can be used by both static configuration and dynamic configuration.

Only once the 'files*' file is presented in a binary format (or converted
to a binary format from the loader, etc.)  From the discussions about this
issue at USENIX, it seemed that both sides realize the requirement for
a binary representation that works for both static and dynamic configuration.
The thought from the new-bus camp has always been that the format for
that data should be the same in all scenarios and be tightly coupled
(i.e. imbedded) to the binary module.  This is the rational behind
DRIVER_MODULE().

>> In the old pccard code for netbsd, if you were to insert and remove
>> the same card multiple times (an ethernet card, for instance), you'd
>> wind up with many instances of that device (eg ed0, ed1, ed2, etc).
>> Is that still the case with the newconfig project?  I'm finding it
>> hard to comment on directly because my experience with config.new have
>> been limited.
> 
> Your requirement is already implemented in com_pcmcia driver of
> NetBSD-1.4. Config.new doesn't have problem about this.
> The reason why it is not implemented in network interface is that
> current implementation of ifnet structure doesn't support this.
> I.e. it is not problem of configuration framework, but problem of
> network stack. And the problem will be fixed by kenh's if_detach
> branch.
> 
> If you have enough knowledge about config.new, you should already
> have known that config.new doesn't have this problem.
>
> Because first implementation of config_detach() has been known since
> 1996. (far before new-bus is started)

Right.  The unit numbering thing is an implementation detail that
can be solved in either framework.  I'm not familiar with how you
plan to remove a driver entry from the cf database under config.new,
but I'm sure it could be done with the appropriate tweaks to the
cf data structures.  Driver instance removal is clearly possible
today.

>> : About "at anytime a device driver may enter or leave the driver tree",
>> : this is one of major target of newconfig project, and it is apparent
>> : that it can be done.
>> 
>> I find it hard to comment on this point because I'm not sure how
>> config.new handles these things.  May I ask for more details on how it 
>> is done, or how you plan to do it?  I'm afraid that I need more
>> details here in order to be able to effectively comment.
> 
> Just like new-bus does. Our plan includes dynamic loading bus code
> and other features of new-bus.
> We will make binary format of "files" file, and make it readable by
> kernel at any time when it is needed.
> This supports on-demand loading of device drivers which cannot be
> implemented by new-bus.

I don't follow your last comment.  Can you describe a scenario where
new-bus would fail?  I understand your concern over the static versus
dynamic module location problem, but this is an implementation flaw,
not a design flaw in new-bus that is being rectified as we speak.

>> While bus_dma isn't part of new-bus, but there are dependencies there.
>> I'm not sure that I understand the issue that you are talking about
>> here.  Can you provide more detail on how FreeBSD's interface bus (or
>> in this case the bus_dma interface) is flawed for dynamic
>> configuration?  I've not run into these problems yet and am interested
>> in correcting them.
> 
> It is problem of FreeBSD's callback interface of bus_dma(9) and it's
> usage. It can be fixed by changing it's usage, but I think NetBSD's
> interface is better than fixing usage.

Is the concern here that a callback could occur after an unload event?
A module with pending callbacks will not unload until all pending
transactions have been cleaned up.  This is at best another
'reference counting' type of issue.  You have to deal with this kinds
of dependencies anyway for things like 'final close' of a driver instance
that has suddenly disappeared in an interrupt context.  There will always
be situations where you will have to defer some amount of cleanup until
it is 'safe' to do so.

>> : DEVMETHOD() is worst way to achieve compatible device drivers.
>> : Any other operating systems which allow dynamic loading device driver
>> : has such feature? No, there isn't. It is not needed. It is slow.

Actually yes.  Win9X exports several interfaces using a similar method.

>> I think that we disagree on this, except for the slight performance
>> penalty (which I agree is present, but likely not a significant source
>> of slowdown).  The DEVMETHOD stuff insultates changes to the interface
>> (specifically additions) from the drivers.
> 
> There is no problem about the interface additions in simple function
> vector without DEVMETHOD().

And how do you safely determine at run time that a module you interface
with supports a particular method?  For instance, I'm a 3rd party vendor
of an in-kernel module that needs to talk to several ethernet drivers.
Some of these drivers may have been compiled before certain features
were added to the 'ethernet driver' interface.  As a good vendor,
I want to deal with both 'old' ethernet drivers and new ones, but I need
to know which ones provide the new functionality.  This is part of 
what DEVMOTHOD() hopes to achieve.

> In other words, DEVMETHODS() adds no meaningful feature.
> 
>> If one wanted to add a parameter to foo, a new function (say
>> foo_20) can be added with the "default implementation" being to call
>> foo() without the parameters.  More work could be put into the method
>> generator to allow for effective versioning.  It is not there today.
> 
> This can be done easily without DEVMETHOD().

Certainly, if you want to do it all by hand, then so be it.  The
whole point of the interface files is to automate the process of
defining interfaces that provide binary compatibility, some amount
of safety for interface version missmatch between modules and, with
just a bit of tweaking to the interface generator, can add interface
versioning without touching any clients of the code.  It doesn't
sound like you are arguing that the things the interface generator
is providing are unnecessary in all cases, but you are unhappy with
the implementation.

>> bus_if.m is still evolving and the interface to it hasn't been
>> finalized yet.
> 
> In other words, bus_if.m increase possibility of a incompatible change.

No.  Once the interfaces have stabilized, we will commit to binary and
interface backwards compatibility so that 3rd parties can rely on our
interfaces.  Committing to this today would cause us to needlessly bloat
our interfaces with backwards compatibility functions during an
integration period where we know our interfaces will rapidly change.

>> : There is no way to tell a dynamic loaded frontend driver about whether 
>> : it's backend part is statically linked or not.

We currently have a namespace problem that can cause a statically linked
module to be re-loaded, but this is easy to solve.  It is not a problem
inherent to new-bus, the first implementation just missed a few bits
of data that should be imbedded in the DRIVER_MODULE() linker set.

> That's wrong.
> In dynamic configuration of config.new, bus independent part of aic
> driver can be linked statically or dynamically. And bus dependent part
> doesn't have to know about whether bus independent part is statically
> linked or not.
> New-bus lacks this feature, new-bus doesn't have ability to describe
> whether bus independent part is linked statically or dynamically.

This is simply not true.  The modules do not need to know the static
or dynamic nature of a module in new-bus either.  It is only a module
naming issue that is easy to solve.

>> At present this bug precludes having a single dynamic frontend that
>> can work with both the dynamicly loaded backend and a statically
>> linked backend, optimally.
> 
> This is one of bugs of new-bus design.

Not design, current implementation.

> Newconfig supports this in it's design.
> 
>> One could not place the dependency in the aic_pccard.ko file. 
> 
> This is worse than the newconfig way.
> 
> For example, if you will change the name of the backend driver, or
> if you will split backend driver into two part, aic_pccard.ko will 
> no longer work.
> Newconfig doesn't have this problem.

File based dependencies don't work for lots of reasons.  This is
why you can't use file names for dependencies (think single .ko that
holds several related but independent 'modules').  If you change the
*dependency* name in either scheme, you are screwed.

> How does KLD know that aic backend is already statically linked?

It looks up the module name in a linker set list of modules already
present in-core.  KLD knows how to dynamically add entries to linker
sets during a dynamic load, so this just falls out.  The current problem
is that the module name is based on the file where it came from (e.g.
'kernel' for a statically linked object) and it's quite obvious why
this currently loses.

>> While this is a problem, I would argue that this is an edge case
>> that few people would run into.
> 
> Edge case? No, This is so common for properly separated frontend
> and backend. Why doesn't new-bus people ever think about this?

I agree, this is not an edge case, but it is already covered by
new-bus/KLD.

>> One problem that I've seen in all the instances of this discussion is
>> a lack of clear documentation for both new-bus and config.new (as
>> modified by the FreeBSD newconfig project).  I'm not sure how to
>> rectify this problem.
> 
> I don't think so.
> Config.new(8) is available for many years. And red daemon book
> explicitly said that
> 	after the system is completely booted, 4.4BSD
> 	(i.e. config.new) cannot load device drivers....
> 	These problems are all well understood and 
> 	EASY TO FIX.
> in it's page 502.
> (and red daemon books is published before new-bus is started)

One thing that was clear at USENIX in the discussions about new-bus
vs. config.new was that the two parties had many similar goals, but
that there were a few that neither group had considered.  For me,
the implementation of the configuration framework is the easy part.
The hard part is defining all of the scenarios that should be
covered and then looking for an implementation that covers them
all.  What scheme FreeBSD ends up with in the long run is of
no importance to me (I have no vested interest in either approach),
so long as the scenarios are covered.  The way we left this at
USENIX was to move the dialog to the different types of static
and dynamic configuration scenarios we want to support and only
then move on to analysis of the different approaches to deal
with them.  I believe this will be much more productive than
to hash this out as a, 'But your implementation doesn't allow
for this'... 'Of course it does!  Your design lacks this!'...
types of dialogs.

--
Justin