(Not exactly off-topic:  I presume you noticed that Greg sent
a 2.5.25 patch to Linus making "usb-uhci" the only UHCI driver
in the 2.5 build?  Congrats -- fine choice!)


Johannes Erdfelt wrote:
> Before I reply, let me clarify something. We're talking about 2,
> completely seperate concepts in this email which I know has been causing
> some confusion:
> 
> 1) Management and processing of outstanding URB's
> 2) Management of completions

Actually I've been talking about one (simplifying the UHCI code)
with multiple aspects.  My original post mentioned fewer locks
(it _can_ be done with just one) and simpler queuing, as general
areas where it seemed there was excess code and complexity.

I  wasn't really talking about those particular details, although
they might fit in the "simpler queuing" category. I'd rather just
see the UHCI code get to the point where I can look at it without
feeling it's way more complex than the problem really requires.

(It's 50% bigger than the OHCI driver, measured by object code
size, and also is bigger than the EHCI driver.  The hardware isn't
anywhere near different enough to require that much extra code.)


>>>>Or maintain a "shadow schedule" ...
>>>
>>>I saw that in the EHCI code. Can you elaborate on what it does?
>>
>>...
>>
>>And it holds _all_ the TDs that have been issued ... the HC removes
>>some TDs as it processes them, the HCD has to walk behind (shadow)
>>the HC and handle those (collect status, free memory, sometimes
>>unmapping buffers or reporting URB completions).
> 
> So you add all TD's to the schedule, not the QH's?

Erm, since TDs ("qTDs") don't exist except in conjunction with
a QH, both are in the schedule.  Only ISO TDs (either type) can
into an EHCI schedule without a QH.


> Or do you modify the piece of data that is in the "shadow schedule"
> based on what work has been completed by the HC?

The HC modifies schedule data directly, and the "shadowing" involves
seeing those modifications ASAP.  In most cases, when the HC finishes,
the qTD/iTD/sITD is then taken out of the schedule ... in the case of
a qTd, the HC does that.


>>>Since we need to check each URB to see if it's done, I don't see how
>>>using a "shadown schedule" is any better. The current list is the most
>>>efficient way of doing that.
>>
>>How so?  Given "U" urbs and "N" endpoints, we know at least
>>that N <= U.  How is it that checking U times would usually
>>be more efficient, especially given cases when not all N would
>>need to be checked?
> 
> 
> Not all endpoints will have an URB queued. But I suspect you meant N as
> in "endpoints with an outstanding URB".
> 
> Yes, again, more efficient.

Good, so we _are_ communicating!  :)  Yes, endpoints don't hang out
in the schedule for very long unless they're active.  That cuts down
on PCI access, and helps keep throughput up (both USB and system).


>>>The only possible optimization I can see would be to not check some
>>>periodic URB's, but we can't do that because we don't know definitively
>>>or not if the HC has processed the TD's since the last interrupt.
>>
>>We know equally well with both models:  if the TD is now marked as
>>done (by the HC), then it was processed.
> 
> You have me lost here. I'm not quite sure what your comment is
> addressing?

Responding to your "we don't know definitively" point.  We do know
well enough ... one time we'll see a TD marked active, next time it's
marked as done.  The primary reason to interrupt is in fact that TDs
have been processed.

(FWIW I don't see those as "optimizations" but just as desirable
fallout of an uncluttered design.)


> Umm. You said it yourself later in your reply, the HC doesn't know, nor
> care, about URB's.

I was talking about the schedule, and how it's processed; with
no mention of URBs, actually ...:)


> You said there was a corollary between removing URB's from a list as it
> was for removing QH's from the HC's schedule. While they both remove
> something from a linked list, the way the removal is achieved is
> different.

I was actually not talking about the model with an URB list at that
point, I was still (consistently) talking about the "no urb_list"
model.  You're reading more into it than I meant:  of course there
are differences to be expected, that's why I said "corollary" and
later "isomorphic", instead of "identical".


>>>A - B - C - D - E
>>>
>>>and we're processing URB B and C gets removed while we're traversing the
>>>list, thanks can break. That's what we need to protect against.
>>
>>I'm not quite clear what scenario you're talking about.  If they're
>>not queued to the same endpoint, there's no issue, except for HCDs
>>using that "list of all active URBs" model.  (Another area where
>>avoiding that model gives simplification ... :)
>>
>>If they're queued to the same endpoint, ...
> 
> You're confusing things. I'm not talking about the schedule here. I was
> talking about the management of outstanding URB's. Like uhci-hcd does
> with urb_list.

I see what happened -- I forgot you were talking _only_ from the
perspective of having an "urb_list of all active urbs".  So you
can ignore that second paragraph ... but not the sentence about
avoiding that model leading to simplifications!  :)


> You're right the HC doesn't care about URB's. I really meant it in the
> logical sense of a "transfer". In uhci-hcd's case, that would be a QH
> (for control, bulk), a single TD (for interrupt) or a group of TD's (for
> isochronous).

The HC doesn't care much about that either!  All it sees is schedule
entries ... basically TDs, with QHs to structure them.  (And, except
for UHCI, QHs hold endpoint data like device address, IN vs OUT, max
packet size, and endpoint number.)


> You need to protect against multiple CPU's inserting into the schedule
> at the same time. In the case of OHCI, the HC arbitrates this. In the
> case of UHCI, the HCD needs to arbitrate it. But you know all of this
> already I think.

The HC _never_ arbitrates that stuff; that's why a schedule lock is
needed.  The HCD needs to grab a lock for SMP synchronization before
it adds to (or starts a removal from) the schedule.


> Do you mean that the code to handle completion notifications in uhci-hcd
> is too complex?

I'd have to study it to see if that _particular_ chunk of code is
too complex.  I mean that the whole thing is too complex; that surely
translates to a lot of individual chunks being too complex!  Maybe
including that one.  Otherwise the object code wouldn't be so much
larger than either EHCI or OHCI.


>>>Thankfully, you've explained that you meant a "shadow schedule" which is
>>>different and thusly isn't as bad as I was led to believe.
>>
>>Right.  In a sense, every HCD except OHCI keeps a "shadow schedule",
>>but (at this point) only EHCI organizes it like the hardware does.
>
> I think you're using the term "shadow schedule" loosely here.

Right there I was.  Elsewhere I used it consistently to talk about
such a schedule organized exactly like the hardware schedule (and
sharing the same memory for almost all of the data structure).


>>I was talking about advantages of that organization, like being able
>>to do less work when scanning ... but mostly not having code to keep
>>a second not-quite-parallel data structure in sync with the hardware.
>>That's a "simpler is better/faster" tradeoff.
>
> Which "not-quite parallel data structure" are you talking about?

Well, start with all of that urb_list stuff ... :)


>>What I'd call "jumping through hoops" is anything that spreads knowledge
>>of such rare cases throughout the whole driver ... which is exactly what
>>that UHCI "complete_list" does, making two passes become typical.  :)
> 
> 
> You're being misleading. uhci-hcd doesn't make 2 passes at urb_list. It
> makes one pass on urb_list, and then one pass on complete_list.

That's two passes, which could be done in one.  What's misleading?


> Don't underestimate how important simple code is over more complicated
> code for a small optimization.
> 
> The goal here isn't the be most efficient possible. It's about having
> efficient code, that is maintainable. And that means simple.

It's not simple now though; certainly not "as simple as possible".
I believe that eliminating one page  (4KB) of object code (and
corresponding source) is achievable (making uhci-hcd be about as
big as ehci-hcd).  Quite likely even more.


> Remember what Linus has said "Make it as simple as possible, and no
> simpler".
That's Linus quoting Einstein, BTW...


> That all being said, uhci-hcd isn't perfect, yet :)

I won't quote Einstein, but rather Antoine de Sainte-Exupery:

     Perfection is attained not when there's nothing left to add,
     but when there's nothing left to take away. (*)

None of the HCDs are perfect; and "perfect" is more of a direction
than a place, I suspect!  The code in all their innards is also
a bit fragile ... it's a good thing we have a development kernel
cycle for now, it's expected that there can be nontrivial changes
and some things will break (for a while).

- Dave

(*) Or in the original, where I think he was talking about airplane
     design:

       La perfection est atteinte non quand il ne reste rien � ajouter,
       mais quand il ne reste rien � enlever.

     Can anyone tell me where this quote actually comes from?
     I'd have thought "Wind, Sand, and Stars", but of course didn't
     see it there last time I read that.  Was it even in a book?




-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Bringing you mounds of caffeinated joy.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to