Subject: Re: [RFC] Interface to hardware-assisted data movers
To: None <cgd@broadcom.com>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: tech-kern
Date: 07/18/2002 15:22:29
On Tue, Jul 16, 2002 at 07:22:53PM -0700, cgd@broadcom.com wrote:

 > So... I think that might be a mistake.  Specifically, now there's no
 > way to have a single 'copy' operation gather disjoint chunks into a
 > contiguous destination buffer, as one might want for, say, coalescing
 > packets for a network interface w/ "less-than-desirable" alignment
 > constraints.

Ok, I added it back.  (I also discovered I needed it for doing
userland access in a sane fashion, though not for the reasons you
might think.)

 > Comments on the new document:
 > 
 > * intro: you might want to enunciate the notion of 'zero or more input
 >   regions', 'one output region', and 'same lengths for each.' here.

Ok, added text there.

 > * DMOVER_REQ_WAIT: You probably want an additional flag which forces
 >   the processing code to spin, rather than sleeping.  Horrible, yes,
 >   but desirable if you're using it in a place where you can't sleep
 >   but do know that the data mover will be substantially faster or
 >   provide other benefits as compared to a CPU-based copy.  (an example
 >   of this might be a pmap zero page routine.)

The restriction, of course, is that that can never be called from an
interrupt handler.  Any thoughts on a name?  Where should the spinwait
be done?  In the back-end or the midlayer?

 > * so, all these immediate value things...  should probably be a union,
 >   or even just a single 64-bit type w/ e.g. fill8 specified to use
 >   only the low byte value.  maybe if you want to do something even
 >   better (i heard you talking about byte order problems), maybe an
 >   array of bytes, and specify how they're copied (and that fill8 uses
 >   the first one, fill16 uses the first 2, etc.)

In the code, they are all union'd together.  I've been considering making
it:

	uint8_t dreq_imm[8];

to eliminate any confusion about byte ordering.  Thoughts?

 > * There's still some things missing in session method specification
 >   interface, from where I sit.  e.g., you might want to specify the
 >   expected likelyhood of (lack of) reuse of the data, either via
 >   specifying a vague "locality" value (say, 0-3), or by providing
 >   explicit flags like, "try to avoid putting this data into l1 cache,
 >   l2 cache, etc."  The latter type of thing may be translated into,
 >   say, flags on HW requests by a hardware back-end, or specific
 >   prefetch ops or a specific pattern of accesses by a SW back-end.
 > 
 >   Maybe you could say "copy-<something>", but after you have a flag or
 >   two that really does get tedious.

Yah, this would be nice.  I'll see what I can come up with.

 > * copy should be defined to not operate on overlapping regions.  more
 >   generally, methods should be "restartable" in case of HW removal and
 >   the need to re-assign the request to a different back-end.

Yah, I've added a bunch of verbosity about this.

 > * can dmover_request_alloc fail?

Hm, yes.  Guess I should mention that in the manpage :-)

 > * Is it the only interface by which one can get request structures, or
 >   may they be allocated by other means?  if the latter is OK, specify
 >   that they must be zeroed so that we can add things in the future w/o
 >   too much pain.  (e.g., priority, but i don't know if that should go
 >   on session or request.)

Well, nothing frees the request structures implicitly, so certainly clients
could provide their own.  However, I'm trying to keep ABI considerations
in mind.  I suppose I could note the ABI consideration in the document, and
explicitly allow callers to provide their own request structures if they
want to do so.

 > * assymetry between dmover_request_alloc's allocation of input buffers
 >   and dmover_request_free's freeing of them is ... dangerous.  (i.e.,
 >   to get it to alloc you pass NULL, to get it to free you have to pass
 >   the allocated ptr!)  Perhaps: pass inbuf to dmover_request_alloc to
 >   use pre-existing buffer, else it will allocate.  if you provide
 >   buffer, you must dispose of it yourself.  if it allocates, it sets
 >   flag in request and deallocates on free.  don't take buffer ptr in
 >   free.  if free free's something passed in arbitrarily, you'll lose
 >   due to malloc types, too.

Yah, I'll clean this up.

 > * what happens if you destroy a session while requests are active?
 >   What happes if you free a request while it is active?

Right now, it panics.  I haven't addressed that yet.

 > * puzzled by description of use from interrupt context...  you can use
 >   it, at, say, IPL_BIO and IPL_SOFTNET, but not IPL_NET (between the
 >   two)?  does this mean from interrupt context caused by interrupts of
 >   those types, or called under splFOO()?  (IPL == priority level, not
 >   "context," but you knew that.  8-)

Ah, I need to document that interrupt handlers for hardware back-ends
should be registered at IPL_BIO.  The intent is to allow various routines
to be called from handlers at IPL_BIO, IPL_SOFTNET, or IPL_SOFTCLOCK.  I've
changed the wording here.

 > * should probably say that dmover_algdesc, dmover_backend should have
 >   all unspecified fields zero-initted (initted in data section, or
 >   bzero'd before filling in the known ones) so that things can be
 >   added later safely.

Okay.

 > * if you do that, not sure what point there is to have the dmb_speed
 >   there now, since it's not used for much...

Well, right now, it's used to cause my test system to prefer the
hardware mover over the software one.

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>