Subject: Re: Device Properties: The Next Generation
To: None <cgd@sibyte.com, eeh@netbsd.org>
From: None <eeh@netbsd.org>
List: tech-kern
Date: 02/21/2001 22:01:39
eeh@netbsd.org writes:
> Here's a question: why support PROP_INHERIT at all?
>
> i.e. why not _always_ inherit from parents?
>
> Most of the time you want to query a particular device's
> properties, usually yourself. Should I use TAG QUEUEs?
> What is MY interrupt number? What is the physical address
> of MY registers? What are the limits of MY DMA addresses?
> You do not want this information from your parent because
> it is likely to be of little use. And, if you don't have
> the property but some ancestor does, and you start to use
> it as your own, this can have disasterous effects.
Right, but, haven't we previously covered this? The protocol between
parent and child says what has to be provided at each level, and what
can be inherited, right?
So, it should always be safe to _try_ inheritance, right? It will
only succeed incorrectly if a parent has _not_ provided something that
it should.
For instance, in the case of tagged queueing:
(1) if there's a local setting, you _do_ want to use it,
(2) but if there's not, you want to fall back on the default
(e.g. to disable it globally),
correct? (the global default might be a tri-state switch, enable,
disable, default, even.)
For most of the things that you describe (interrupt number, physaddr,
DMA addresses), providing those is part of the parent->childe property
passing protocol. The other is inheritable, but also settable by the
parent.
What's a case where you could inherit a property incorrectly, that
_wouldn't_ signal a violation of the property-passing protocol?
O.K. I will give you and explicit example of why you need to
be able to control this sort of searching when you do a query:
A cartain Solaris SCSI controller device driver wanted
to know the chip's clock frequency. There were several
versions of this chip at different clockrates, and the
faster ones were capable of faster transfers. So if
it was running on a fast chip, the driver would enable
the higher speed transfers. To make this determination,
it queried the `frequency' property. However, some
of the older devices did not have a `frequency' property
in the FCode for that node. Since the request had
specified PROP_INHERIT, it would match the `frequency'
for the bus on some machines, which was not the right
value. This caused the driver to use the wrong settings
and caused problems.
The solution was to remove PROP_INHERIT from the
call so it would only search that particular device
node.
> It seems to me what you have right now is:
>
> "0, many"
>
> I.e., you search only your locally attached properties, or you search
> the entire tree up to the root.
>
> It seems to me that that's missing the classic "1" (or a more abstract
> version of that).
>
> The `classic "1"' is a query of your direct parent without PROP_INHERIT.
I disagree with this. A device should _never_ have to look directly
at another device's 'struct device' in order to function properly.
Then why are we passing a `parent' pointer into the driver *match()
and *attach() functions?
> If your claim is, the protocol is defined and can be followed to
> correctly produce a property using inheritance, then you shouldn't
> need to specially turn on inheritance.
>
> If you use inheritance you never know who's property you're getting.
> The parents are not the ones who care who's reading which property.
> It's the children who can't trust the source of the property, whether
> it comes from some parent node or some machine dependent repository.
Again, if this is true, what's a real-life example of a problem that
_isn't_ a 'protocol violation' bug?
See above. This is for much more than just attaching
devices to buses.
> If your claim is that you _should_ need to specially turn on
> inheritance, then you're missing support features that I think are
> important: some way of limiting the inheritance in cases where it's
> "known" (by the protocol) not to be desirable.
>
> You do not `specially turn on inheritance'. You are doing
> queries that either do or do not continue up-tree. This is
> not something that can be limited at the producer side because
> the producer does not usually know the consumer's information
> requirements.
Huh? The procotol between parent and child means that indeed, the
producer can and _does_ know the requirements of the child/consumer!
It may not know them all the way down the chain... but that's the
whole point. It shouldn't be (effectively) passing things all the way
down the chain unless it knows that protocol!
Which was the whole genesis of the notion of limiting how far
properties can be inherited.
No. Properties are for much more than just attaching
child devices. They are for controlling driver behavior.
There will be many properties that will be used by device
drivers that the bus drivers will know nothing about.
Anything that is accessed through dev_mdgetprop() for
example, or properties attached to devices in config
files.
This is not just replacing locators and `aux'. It also
replaces `flags' amongst other things.
> You can't really pick both at the same time...
>
> The only reason to have inheritance is to simplify programming.
The point of my question was the only one of the following can really
be true:
(1) you need some form of limiting inheritance at the source, or
(2) the protocol at each level takes care of the problem.
You have been asserting the latter.
If you assert the latter, it seems reasonable that PROP_INHERIT should
_always be on_, i.e. inheritance should always happen.
If not, then really that's a statement that, for each level, the
inheritance protocol is not as well defined as it should be. And one
of the things that falls out of that is that devices might then
reasonably want to be able to define how far their properties flow.
I.e. I understand why you want PROP_INHERIT. I don't understand why,
assuming the protocol for passing properties is defined as well as it
should be, you'd ever need to _not_ use it.
Properties cannot be taken care of at each level because
there are potentially multiple protocols in operation on
the same nodes at the same time. One protocol would be
the bus driver/child protocol, which is used to pass
attachment information. Another is the protocol to
set bus attributes, like SCSI SYNC and TAG QUEUEs.
Yet another could set speed, parity, and handshaking
on a serial port.
Also, some of the properties involved in a protocol
may be set by the parent driver, but others may be
set by firmware or inside the config file. If we
try to control inheritance when properties are added,
we can only control the inheritance of properties that
were added by drivers at run-time.
Properties added in config files or through some MD
manner, (say through firmware) have no mechanism by which
inheritance can be manipulated. So we need to provide
it to the driver that makes the query, whether we use
some other method to control inheritance or not.
And since we need to provide those, we may as well not
complicate the code with something this complicated
that won't always work.
Now, if you still think that this sort of functionality
is required, I am certainly willing to entertain the
idea. However, I really don't have any good ideas about
how to implement it in a clean, efficient manner.
1) What interface would you use to limit inheritance?
2) How would you implement it so it works in conjunction
with properties generated from a config file or returned
by dev_mdgetprop()?
3) What mechanism would you use to extend the inheritance
of a propert a level further because a bridge node is
attached rather than a device?
Eduardo