From patchwork Fri Jan 12 09:19:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 10160131 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0B15F602B3 for ; Fri, 12 Jan 2018 09:22:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E0773288A3 for ; Fri, 12 Jan 2018 09:22:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D486728942; Fri, 12 Jan 2018 09:22:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, RCVD_IN_DNSWL_HI, URIBL_GREY autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 61F92288A3 for ; Fri, 12 Jan 2018 09:22:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754632AbeALJTc (ORCPT ); Fri, 12 Jan 2018 04:19:32 -0500 Received: from o1682455182.outbound-mail.sendgrid.net ([168.245.5.182]:14578 "EHLO o1682455182.outbound-mail.sendgrid.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754569AbeALJT1 (ORCPT ); Fri, 12 Jan 2018 04:19:27 -0500 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=sendgrid.me; h=from:to:cc:subject:in-reply-to:references:in-reply-to:references; s=smtpapi; bh=xpBXOyfgryIzphfkV6twVnmLFzo=; b=fZQ7uMNHpDWDvfp+/C vY4RN6V94/JGF81IqdevYLfCKEEL/vdFP+FX9UdlQwj2ma9O2AZEG1Gkbw6/DBss Xn5SxNmn4E7cH7jjjrFYZLB16+dbI/BdN78FukHF/UodMuJK9z5U2EogjWjlEEjg 2yL6TKeBIaSvUThRjqgdZs6I4= Received: by filter0023p3las1.sendgrid.net with SMTP id filter0023p3las1-7419-5A587D9D-3A 2018-01-12 09:19:25.982941397 +0000 UTC Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by ismtpd0005p1lon1.sendgrid.net (SG) with ESMTP id noyBj-G3TEC72at1Kxxfqw Fri, 12 Jan 2018 09:19:25.655 +0000 (UTC) From: Kieran Bingham To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Guennadi Liakhovetski , Laurent Pinchart , Olivier BRAUN , Troy Kisky , Kieran Bingham Subject: [RFT PATCH v3 3/6] uvcvideo: Protect queue internals with helper Date: Fri, 12 Jan 2018 09:19:26 +0000 (UTC) Message-Id: <0f14323f98ca64dd828514577167dc232a33a8ad.1515748369.git-series.kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: X-SG-EID: Tfq0zQjjJFmIKL8hyrOr6KT7wyjsEm7XZZskPfLyBPLtLdt1ZgmmyFo2Di2IByCDde+f3MoW5jPm6x LpYDv1NunKJhhdjrSKLqz4kjirt7BhIw6d3ewkTUtMIRTOAEae4zy4ZoKbmUYFbgxsZKbS5CzGAITf G/XNYkW5+wky/xAh/wKSgXYlC+KwZAfPXKgFiPDsySUu3enqotbEARkReUpSgtpv79o5i8O1Envzn/ VjGAJ4gKjdlBrj0ERh973P Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The URB completion operation obtains the current buffer by reading directly into the queue internal interface. Protect this queue abstraction by providing a helper uvc_queue_get_current_buffer() which can be used by both the decode task, and the uvc_queue_next_buffer() functions. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- v2: - Fix coding style of conditional statements --- drivers/media/usb/uvc/uvc_queue.c | 33 +++++++++++++++++++++++++++----- drivers/media/usb/uvc/uvc_video.c | 7 +------ drivers/media/usb/uvc/uvcvideo.h | 2 ++- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index c8d78b2f3de4..4a581d631525 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -399,6 +399,33 @@ void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect) spin_unlock_irqrestore(&queue->irqlock, flags); } +/* + * uvc_queue_get_current_buffer: Obtain the current working output buffer + * + * Buffers may span multiple packets, and even URBs, therefore the active buffer + * remains on the queue until the EOF marker. + */ +static struct uvc_buffer * +__uvc_queue_get_current_buffer(struct uvc_video_queue *queue) +{ + if (list_empty(&queue->irqqueue)) + return NULL; + + return list_first_entry(&queue->irqqueue, struct uvc_buffer, queue); +} + +struct uvc_buffer *uvc_queue_get_current_buffer(struct uvc_video_queue *queue) +{ + struct uvc_buffer *nextbuf; + unsigned long flags; + + spin_lock_irqsave(&queue->irqlock, flags); + nextbuf = __uvc_queue_get_current_buffer(queue); + spin_unlock_irqrestore(&queue->irqlock, flags); + + return nextbuf; +} + struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) { @@ -415,11 +442,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, spin_lock_irqsave(&queue->irqlock, flags); list_del(&buf->queue); - if (!list_empty(&queue->irqqueue)) - nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, - queue); - else - nextbuf = NULL; + nextbuf = __uvc_queue_get_current_buffer(queue); spin_unlock_irqrestore(&queue->irqlock, flags); buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE; diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index 92bd0952a66e..3878bec3276e 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -1322,7 +1322,6 @@ static void uvc_video_complete(struct urb *urb) struct uvc_streaming *stream = uvc_urb->stream; struct uvc_video_queue *queue = &stream->queue; struct uvc_buffer *buf = NULL; - unsigned long flags; int ret; switch (urb->status) { @@ -1343,11 +1342,7 @@ static void uvc_video_complete(struct urb *urb) return; } - spin_lock_irqsave(&queue->irqlock, flags); - if (!list_empty(&queue->irqqueue)) - buf = list_first_entry(&queue->irqqueue, struct uvc_buffer, - queue); - spin_unlock_irqrestore(&queue->irqlock, flags); + buf = uvc_queue_get_current_buffer(queue); stream->decode(uvc_urb, buf); diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 81a9a419a423..5caa1f4de3cb 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -692,6 +692,8 @@ extern int uvc_queue_streamon(struct uvc_video_queue *queue, extern int uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type); extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); +extern struct uvc_buffer * + uvc_queue_get_current_buffer(struct uvc_video_queue *queue); extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf); extern int uvc_queue_mmap(struct uvc_video_queue *queue,