Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754632AbeALJir (ORCPT + 1 other); Fri, 12 Jan 2018 04:38:47 -0500 Received: from mout.gmx.net ([212.227.15.15]:57177 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754403AbeALJin (ORCPT ); Fri, 12 Jan 2018 04:38:43 -0500 Date: Fri, 12 Jan 2018 10:37:54 +0100 (CET) From: Guennadi Liakhovetski X-X-Sender: lyakh@axis700.grange To: Kieran Bingham cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Laurent Pinchart , Olivier BRAUN , Troy Kisky Subject: Re: [RFT PATCH v3 6/6] uvcvideo: Move decode processing to process context In-Reply-To: Message-ID: References: User-Agent: Alpine 2.20 (DEB 67 2015-01-07) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Provags-ID: V03:K0:YA3Omu2RbcHAjvzw9CZLXptQrkYdiMZoGobffR/vcs3yLDmSFMH UuWfM7fgE6d7opSFv3gP3tTqEijSr7Uz8s/T9kGLloxzQRHxSOic5TohETRCrUGLkrNjPcA 9SzyL/FowuX1fPS/Wa/sI21pXf0/VOZehBMdpuJmQ7vw+nkdg2z9yZDb+gUT5L55axEgVM5 6bRUdvPfz9DdNnemJ96rA== X-UI-Out-Filterresults: notjunk:1;V01:K0:zmriJO9ga58=:8MytP3ZXgOH41/twx3HTNO atbnGbSWCvMzz4yVFcjx2riq6BJ92gLz/26jwWZdeqdLPxDWPWAViyDgnC6nKGFQ/8g2LmJPA jkoRux1FzLkSdRNTydGWsDtJ20NA2P2kYx7SupGFSsQTkFWvmSp4bxKuAsAb/y3UYiUiT9G+b xR/MrDx5RywXH1wohNGlcRNmZZEvZisNT2rBXinCeV4M8Wbd3QksgGr+l8pqPOtF3/br+V4dQ P80rRMEU68+L3D7pgeAlB1U9bkeheFlGLEQ2YKzvTnAq8eqp27CY/QBOK8JvgiopqXhS3Uuis Hg2hkerDmQKsAwTP5nfAyrQZ4xKhfv957cIqy9k1EZw2/7O3Pp5bAP1U8SAjPcWii3XDPJJ1m 9ccf3O/4/zulkpRWTZKBWhjMqWdHJRoA5Iv45a5lVZgOyizXvTd2Ub8LZDt1GQaDS2A0C2pBK Soa+o206+dLCSaMHyXEY5VaJ+YxL34DYZO+dcuNFLj7e7YdO4OmOZzbdCTaUTxYO2m+8FF/d6 A8LztLl4cnym9LyAixRMPSh50yfFX6nLoinLdtRMoIBa8loTn1FPa0OU+HkusvZ/N0hjQFwsx fAMn01MJOUJozGcWXR/lo/RlyJbSpnV4v+3IPf3yAfUO4A4pXgpKivpv2b8VcJEQTBcNC1ZpR 6OD5UyB0ripRxyxkJslFYN7+Cl4YCIomUVmnrFw9Cr2xlxb4fehtK6IeTyjAgqri826kjttrh Tl6hK+c6tyZt5VpusMcfegpLQyfI1oNEGQ4qc2/p9yFsSR8lzu1j35vsI4/wiAEP4wwf5tILn t+0H5yCNCh334T1vQyunstQOjfmjmG858MO1ELef7epGt1eb0o= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: Hi Kieran, On Fri, 12 Jan 2018, Kieran Bingham wrote: > Newer high definition cameras, and cameras with multiple lenses such as > the range of stereo-vision cameras now available have ever increasing > data rates. > > The inclusion of a variable length packet header in URB packets mean > that we must memcpy the frame data out to our destination 'manually'. > This can result in data rates of up to 2 gigabits per second being > processed. > > To improve efficiency, and maximise throughput, handle the URB decode > processing through a work queue to move it from interrupt context, and > allow multiple processors to work on URBs in parallel. > > Signed-off-by: Kieran Bingham > > --- > v2: > - Lock full critical section of usb_submit_urb() > > v3: > - Fix race on submitting uvc_video_decode_data_work() to work queue. > - Rename uvc_decode_op -> uvc_copy_op (Generic to encode/decode) > - Rename decodes -> copy_operations > - Don't queue work if there is no async task > - obtain copy op structure directly in uvc_video_decode_data() > - uvc_video_decode_data_work() -> uvc_video_copy_data_work() > --- > drivers/media/usb/uvc/uvc_queue.c | 12 +++- > drivers/media/usb/uvc/uvc_video.c | 116 +++++++++++++++++++++++++++---- > drivers/media/usb/uvc/uvcvideo.h | 24 ++++++- > 3 files changed, 138 insertions(+), 14 deletions(-) > > diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c > index 5a9987e547d3..598087eeb5c2 100644 > --- a/drivers/media/usb/uvc/uvc_queue.c > +++ b/drivers/media/usb/uvc/uvc_queue.c > @@ -179,10 +179,22 @@ static void uvc_stop_streaming(struct vb2_queue *vq) > struct uvc_video_queue *queue = vb2_get_drv_priv(vq); > struct uvc_streaming *stream = uvc_queue_to_stream(queue); > > + /* Prevent new buffers coming in. */ > + spin_lock_irq(&queue->irqlock); > + queue->flags |= UVC_QUEUE_STOPPING; > + spin_unlock_irq(&queue->irqlock); > + > + /* > + * All pending work should be completed before disabling the stream, as > + * all URBs will be free'd during uvc_video_enable(s, 0). > + */ > + flush_workqueue(stream->async_wq); What if we manage to get one last URB here, then... > + > uvc_video_enable(stream, 0); > > spin_lock_irq(&queue->irqlock); > uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR); > + queue->flags &= ~UVC_QUEUE_STOPPING; > spin_unlock_irq(&queue->irqlock); > } > > diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c > index 3878bec3276e..fb6b5af17380 100644 > --- a/drivers/media/usb/uvc/uvc_video.c > +++ b/drivers/media/usb/uvc/uvc_video.c [snip] > + /* > + * When the stream is stopped, all URBs are freed as part of the call to > + * uvc_stop_streaming() and must not be handled asynchronously. In that > + * event we can safely complete the packet work directly in this > + * context, without resubmitting the URB. > + */ > + spin_lock_irqsave(&queue->irqlock, flags); > + if (!(queue->flags & UVC_QUEUE_STOPPING)) { > + INIT_WORK(&uvc_urb->work, uvc_video_copy_data_work); > + queue_work(stream->async_wq, &uvc_urb->work); > + } else { > + uvc_video_copy_packets(uvc_urb); Can it not happen, that if the stream is currently being stopped, the queue has been flushed, possibly the previous URB or a couple of them don't get decoded, but you do decode this one, creating a corrupted frame? Wouldn't it be better to just drop this URB too? > } > + spin_unlock_irqrestore(&queue->irqlock, flags); > } > > /* Thanks Guennadi