Matt, what's wrong with this analysis (if anything)?

Looking first at the typical case (no short-read error,
device returns all the data that's expected), and in
all cases ignoring the actual API used to get to this
"best of all possible I/O patterns":

- For Bulk-Only, the I/O pattern is always going to
  be WRITE (command, maybe data), IRQ (for
  completion of 1 or N+1 urbs), READ (maybe
  data, certainly status), IRQ.  Since the data
  is transferred on the same endpoint used for
  either command or status transfer, one or the
  other can always be queued.

- For Control/Bulk, the I/O pattern is always going
  to be CTRL-WRITE, IRQ, WRITE or READ
  (for data), IRQ ... hmm, same performance model.
  Maybe that's why there's no status phase for CB? :)

- Control/Bulk/Interrupt is just like Control/Bulk
  except that there's an additional INTR-READ, IRQ
  pair at the end.  A smidgeon slower; there's also a
  polling delay for that INTR-READ (goes into the
  next frame or microframe).

And for those error paths, with short reads, where
I'd contend slower behavior is reasonable/expected:

- For bulk only, the short read case will involve
  an extra READ+IRQ at the end, since the
  error will have dequeued the status read.

- For control/bulk, same as the non-error case.
  (I can imagine other errors, like overruns, would
  cause more trouble, given "no status phase".)

- For control/bulk/interrupt, also just like non-error.

Now, as for the "semantic difference" and how to
factor the API ... call me a purist, but I don't see
any benefit to adding intelligence to usbcore so that
it can have logic like this, which can just as easily
live in the device driver's completion handlers:

    // in scatter/gather completion
    if (that was a bulk-only short read)
        set flag to remember this;

    // in status read completion, bulk-only case:
    if (we were canceled, and that flag's set)
        reissue myself

Seems straightforward to me.  Reworking the
drivers/usb/storage/transport.c won't be notably
easier by avoiding that, since the big issue is that
it's structured to demand rescheduling the request
thread between each transfer phase (and right now,
even between each bulk-queuable s/g segment).

Of course, just making the data phase use bulk
queuing would be the single biggest performance
win (save ten interrupts and thread reschedules,
in your example :) and that doesn't require that
larger restructuring.  I'd be more tempted if I
weren't already tied up with other things.

- Dave


----- Original Message ----- 
From: "Matthew Dharm" <[EMAIL PROTECTED]>
To: "Johannes Erdfelt" <[EMAIL PROTECTED]>
Cc: "USB Developers" <[EMAIL PROTECTED]>
Sent: Sunday, November 25, 2001 3:04 PM
Subject: Re: [linux-usb-devel] URB with scatter-gather?

Nono.. we're confused here.

What I'm describing here is a three-stage transaction, with the middle
stage being a scatter-gather stage -- that is, the "data" phase involves
trying to get data in/out of multiple non-contiguous buffers.

So, I'm not talking about 3 URBs... I'm talking about 12.  One command, 10
data, and 1 status.

The problem here is that there is a semantic difference between the way
command/data/status are queued together and the way the data segments are
queued together, and we need a way to represent both.

Command/data/status should be queued together so that a short packet does
_not_ stop the next transaction.

Data blocks need to be queued together so that a short packet _does_ stop a
transaction.

The problem is, for maximum effeciency, I want to be able to use _both_
types of queueing.  I want scatter-gather as well as "unrelated URB"
(for lack of a better term) queuing.

Matt Dharm




_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to