Hi Al, Thanks for the patch. On Thursday 18 August 2011 15:28:29 Al Cooper wrote: > The UVC driver uses usb_alloc_coherent() to allocate DMA data buffers. > On systems without coherent DMA this ends up allocating buffers in > uncached memory. The subsequent memcpy's done to coalesce the DMA > chunks into contiguous buffers then run VERY slowly. On a MIPS test > system the memcpy is about 200 times slower. This issue prevents the > system from keeping up with 720p YUYV data at 10fps. > > The following patch uses kmalloc to alloc the DMA buffers instead of > uab_alloc_coherent on systems without coherent DMA. With this patch > the system was easily able to keep up with 720p at 10fps. > > Signed-off-by: Al Cooper <alcooperx@xxxxxxxxx> Acked-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> I will push it to v3.2. > --- > drivers/media/video/uvc/uvc_video.c | 18 +++++++++++++++++- > 1 files changed, 17 insertions(+), 1 deletions(-) > > diff --git a/drivers/media/video/uvc/uvc_video.c > b/drivers/media/video/uvc/uvc_video.c index 4999479..30c18b4 100644 > --- a/drivers/media/video/uvc/uvc_video.c > +++ b/drivers/media/video/uvc/uvc_video.c > @@ -790,8 +790,12 @@ static void uvc_free_urb_buffers(struct uvc_streaming > *stream) > > for (i = 0; i < UVC_URBS; ++i) { > if (stream->urb_buffer[i]) { > +#ifndef CONFIG_DMA_NONCOHERENT > usb_free_coherent(stream->dev->udev, stream->urb_size, > stream->urb_buffer[i], stream->urb_dma[i]); > +#else > + kfree(stream->urb_buffer[i]); > +#endif > stream->urb_buffer[i] = NULL; > } > } > @@ -831,9 +835,15 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming > *stream, for (; npackets > 1; npackets /= 2) { > for (i = 0; i < UVC_URBS; ++i) { > stream->urb_size = psize * npackets; > +#ifndef CONFIG_DMA_NONCOHERENT > stream->urb_buffer[i] = usb_alloc_coherent( > stream->dev->udev, stream->urb_size, > gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]); > +#else > + stream->urb_buffer[i] = > + kmalloc(stream->urb_size, gfp_flags | __GFP_NOWARN); > +#endif > + > if (!stream->urb_buffer[i]) { > uvc_free_urb_buffers(stream); > break; > @@ -908,10 +918,14 @@ static int uvc_init_video_isoc(struct uvc_streaming > *stream, urb->context = stream; > urb->pipe = usb_rcvisocpipe(stream->dev->udev, > ep->desc.bEndpointAddress); > +#ifndef CONFIG_DMA_NONCOHERENT > urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; > + urb->transfer_dma = stream->urb_dma[i]; > +#else > + urb->transfer_flags = URB_ISO_ASAP; > +#endif > urb->interval = ep->desc.bInterval; > urb->transfer_buffer = stream->urb_buffer[i]; > - urb->transfer_dma = stream->urb_dma[i]; > urb->complete = uvc_video_complete; > urb->number_of_packets = npackets; > urb->transfer_buffer_length = size; > @@ -969,8 +983,10 @@ static int uvc_init_video_bulk(struct uvc_streaming > *stream, usb_fill_bulk_urb(urb, stream->dev->udev, pipe, > stream->urb_buffer[i], size, uvc_video_complete, > stream); > +#ifndef CONFIG_DMA_NONCOHERENT > urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; > urb->transfer_dma = stream->urb_dma[i]; > +#endif > > stream->urb[i] = urb; > } -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html