On Sunday 01 May 2005 2:04 pm, Oliver Neukum wrote:
> Am Sonntag, 1. Mai 2005 21:29 schrieb Harald Welte:
> > A quick browse through the EHCI specification and the ehci linux hcd
> > driver 

This should be true of any HCD that supports DMA, FWIW.

EHCI is probably most interesting because it's the only
HCD that already achieves dozens of MByte/sec througput,
hence the only one where a few more might be achievable!
And where the cpu overheads of lots of userspace copies
can start to be objectionable, too.


> > revealed that it should be technically possible to: 
> > 
> > 0) open an usbdevfs file like usual
> > 1) set up a mmap()ed buffer between kernel and userspace
> > 2) create one (or multiple consecutive) urb that points into the
> >    mmap()ed buffer
> > 3) submit that urb to ehci-hcd, which would in turn set up qtd's
> >    pointing directly into that buffer
> > 
> > The result should be a truly zerocopy dma-to-userspace architecture.

I've thought about that on occasion.  On some processors you'd
need to flush the userspace caches first, but on typical PC-ish
stuff the main concern would be making sure that the buffers are
aligned nicely ... i.e. only start a 512 byte packet on a 512 byte
boundary, since if it crosses pages then most systems aren't going
to be able to turn it into DMA-contiguous address space.  (Even
with an IOMMU, it's not guaranteed ...)  In terms of USB protocol,
one 512 packet != two packets of 500 + 12.


It might well be simpler to just pin whatever (aligned) buffers
have been passed, ensure they're properly flushed, and then just
DMA to/from those pages without requiring special DMA mappings
to be set up first, and without needing special new usbfs calls.

I was looking at that sort of stuff a while back, in conjunction
with seeing how the AIO stuff might replace the rather funky
USB-specific AIO-ish stuff in usbfs.  A lot of the relevant
infrastructure is already in place.

As an example, we now have AIO support in "gadgetfs", which I've
suggested should be the basic model to follow when rewriting
"usbfs".  With a one-to-one mapping between URBs (or usb_requests)
and kiocbs, an incremental development step might be as simple as
just adding an ioctl to usbfs to return a new AIO-capable file
handle for a given endpoint, then using normal AIO calls on that
to reuse some of the existing zerocopy work ...


> > Do you think a system described above is actually feasible?  If yes,
> > what kind of implementation suggestions do you have?  
> 
> In static int hcd_submit_urb (struct urb *urb, int mem_flags) you can
> see that usbcore really doesn't care what buffer you feed it if you've
> called dma_map_single() on it. You will need to make sure that buffers
> don't overlap and make sure there's some limit to the ram a task can pin
> thus.

The key point to draw from that is that all this zerocopy stuff
can (and should!!) be done at layers above usbcore.  If the
layer above -- "usbfs", "usbfs2", or even "usbfs 1.5" -- passes
URBs with DMA mappings already established, all the nasty/fragile
usbcore stuff can be left alone.  And even "usbfs" could mostly
be left alone.

Eventually I'd not be surprised to find that an AIO layer on top
of usbcore would highlight some places where the USB I/O path
could usefully be tuned.  Right now the fastest path there is
probably the usb_sg_*() stuff, but there's nothing letting those
techniques (IRQ reduction, transfer queueing, IOMMU coalescing)
be accessed from userspace.

- Dave


-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.
Get your fingers limbered up and give it your best shot. 4 great events, 4
opportunities to win big! Highest score wins.NEC IT Guy Games. Play to
win an NEC 61 plasma display. Visit http://www.necitguy.com/?r 
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to