Subject: Re: Device Properties: The Next Generation
To: None <eeh@netbsd.org>
From: Chris G. Demetriou <cgd@sibyte.com>
List: tech-kern
Date: 02/22/2001 12:42:57
eeh@netbsd.org writes:
> I really don't want to get involved in this issue.
> If you think that we should get rid of the parent 
> pointer passed in to the *match() and *attach()
> routines, please put together a separate proposal.
> It really is orthogonal to device properties.

Sure.  However, note two things:

(1) if you do the macros for conversion as I suggested, it's trivial
to do at the same time.  Such a proposal is simply a matter of lumping
in with yours "in addition to the other modifications to the
match/attach calling conventions, don't pass in the parent device.
All in favor say Aye."  8-)

(2) If it is done, it should be done at the same time, so you don't
redefine the definition of what goes into match/attach twice.  It
shouldn't hurt to do so, in fact, but it's best to do it just once.



> A device can attach to multiple different buses.
> Each bus may require different properties to attach
> children.  They may conflict.  

A device that attaches to multiple different busses uses different
attachments for those where using a single attachment would conflict.

That's entirely what got us to doing attachments, in fact.


> 	> 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.  
> 
> 	Sure.  And those have to be defined by a system-wide protocol, rather
> 	than a simple parent-child protocol.
> 
> Are you saying that we need to define a global 
> protocol for all possible buses, even ones that
> have not been designed yet, initially, so that
> no properties can conflict between them? 

No.  We have to define a global protocol for all cases that _may
overlap_.

As long as you permit inheritance/searching-of-parents, you need to do
this.

The only way to avoid it completely is to compartmentalize at each
level.

I suggested that previously, it doesn't seem like a great idea though.


> 	Right.  That seems fairly straightforward.
> 
> 	For flags, you need to enumerate up front (e.g. in the config file)
> 	what the possible flag-replacement options are.  If an option is not
> 	specified, the default value should be provided.
> 
> So every time that a driver wants to add a new
> property to, say, turn on debugging, you need
> to edit `files' files to add in a default?  I
> suppose it could be done, but it seems a bit
> restrictive to me.

Depends on how you define things.

Were I defining debugging, I might define two things:

(1) global default property name to be inherited, a string that
specifies what debugging to enable.

(2) local name (probably reused by lots of devices that accept
debugging information) that again specifies what debugging to enable.


If you want to replace each individual flag bit with its own property
name, e.g. debug_foo, debug_bar, debug_baz, well then, yes, you've got
a fair bit of typing to do.  But I think that that would be a bad use
of the interface.



> 	(2) you need some way to limit the scope of use of protocols.  And,
> 	I'll again assert that, if you're going to do that, "0 and many"
> 	aren't sufficient.  e.g. limiting scope to grandchildren is quite a
> 	reasonable thing to want to do.  (scsi ctlr, scsi bus, scsi device...
> 	or, if somebody ever fixes the SCSI code to attach targets rather than
> 	target,luns, you'd need great-grandchild...)
> 
> I'm still interested to know how you would implement
> a protocol that is more complicated than "0 and many".

I've mentioned a couple of ways, I think.

One would be to attach values at data creation time, that say how far
you can inherit values.  (That doesn't cover the problem of how far to
allow MD-fetched property values to propagate.  One reasonable answer
to that is, any given property name/value will be accompanied by some
sort of context, which means that the MD code can limit its use as
appropriate for that context.  I.e., This is a SCSI bus, let some
use-luns flow down 2 levels if it's fetched via an MD property.
Another mechnaism would be, e.g. scsi bus does a getprop on use-luns
to see if it should.  it then setprops use-luns on itself specifying
the appropriate level.  That takes complication out of the MD code.)

Another would be to specify at lookup time just how far to search.

To be honest, though, I think since the usefulness of the data is
defined where it's created, something that associates a 'downstream
lifetime' with the data is the right thing to do.

Anyway, as i've said, I don't think this is the right approach.


> 	It's worth re-emphasizing that your proposal specifies the mechanism
> 	for looking up properties, but doesn't actually say what properties
> 	should be looked up, should be passed down from parents, should be
> 	globally defined, etc.  Those things really should be subject to
> 	another discussion entirely, but really come after the definition of
> 	the interface, to my mind.
> 
> Now you have completely lost me.

Hmm.  Well, mrg seems to mostly share your world-view, but seemed to
understand what I was saying here.  Perhaps he can explain it to you
better than i can.  8-)


> You are saying that we should always do a full depth search
> for properties and not allow a single query to determine if
> a property is associated with a specific device node?  

Sure.  The logic behind it goes something like this:

(1) For properties that you expect to be directly attached to you, you
know that they're directly attached (if the value is no, the property
no is attached, i.e., you don't assume no-property means value == no).
The sets of properties you expect are defined by your parent-node
protocol, or node-only protocol.

(2) For properties that you expect to be had by searching, you must
know before hand that in fact they exist and pretty much where.  The
sets of properties you can search this way are defined by the
grandparent-node, greatgrandparent-node, etc., protocols or the global
protocol.  If you do not know that and where the properties will be,
your search results can't have useful meaning (because you don't know
that the value you get applies to you).

(3) Therefore, following from (1) and (2), for all properties that you
may access, you know where they're coming from, and that they exist,
and that they are attached in the right places.

(4) Therefore, following from (3), you never need to specify "search"
-- you know everything's there in the right places, so you can
_always_ search and expect the right result.


> Hm.  O.K.  We could do that....  So if you need a property
> attached to a particular node you could search that node, 
> and it's parent, and if it's on that node but not its parent
> then it's on that node.  You also need to compare values to
> make sure they are the same.  It will be less efficient, and
> if the node you want *and* some ancestor have identical values
> then you will think that the property is not attached to the
> node you want....

But the point is, you shouldn't need to do that.

If you want to know about a property, you're guaranteed that you will
have information about the property you want, and that it will apply
to you.


> Although, getting rid of the depth search feature would be
> more flexible in the long run.  It's much easier to implement
> the depth search with a single node search than to implement
> a single node search with a depth search.

That's the other side of the coin.

If you're going to do this, i assume that the only people who will
explicitly make the parent->child jump are those that have in-depth
knowledge of what their parent is.  If you do other than that, well,
then you start needing to worry about the whole 'defined protocol'
issue.

It has some distinct advantages and disadvantages:

Advantage:

(1) you don't have to spend much time worrying about what you're going
to pass down, since the scope of that passing is very limited.

Disadvantages:

(1) it wastes a lot of space on duplication of properties, that could
otherwise be inherited.

(2) it means that if you want to set defaults at any level of the
hierarchy, they have to be passed down to children.  That means you
know what all possible settable defaults are, and are sure to pass
them down.

(3) it means that if you want to _change_ a default that's already
been passed to children, you have to do a lot of work; you can't just
update the default, you have to update the copies too.



cgd