From patchwork Wed Oct 16 13:58:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 13838519 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 29BF020E01E for ; Wed, 16 Oct 2024 13:58:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087108; cv=none; b=UmUCucQmiWn6kCxMZq+WwQMzc9dWrZ1STwdfUZhQOqFCU5raO3CXOgvjjXYPj+xXqQ34zysBjt7Kyh5zHcErpzTOwjBDyfY4XyTkOmZxN8L2sb8MhQCOFW/ydVtepIgfzVgCVQ5VGTT5uuGZDE4/K+1YD7vgkcx4NrEmag8Fhj0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087108; c=relaxed/simple; bh=KOYB94vey15IcIEifhD0pxE/3ywuoSg72econbiOevY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rVjMvCY22KACoVUg6lHzd3Lh9tzC3A3TrzOkNlQBRxVBF/eOzwRHIMXZ1jxAfwgRJI8rbn9d/5eUKGd1buVVlaGJYoJOiWbiDJjlPVrQ6aqJ92U2JCu1ytXRCL/SylpCaoF4KgD3Un2R2hBH2kaW/vv3ltUscuB88PAE18k2l74= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t14Xd-0003Gy-L5; Wed, 16 Oct 2024 15:58:21 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t14Xd-002Hj9-14; Wed, 16 Oct 2024 15:58:21 +0200 Received: from localhost ([::1] helo=dude04.red.stw.pengutronix.de) by dude04.red.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1t14Xc-00BU5S-37; Wed, 16 Oct 2024 15:58:20 +0200 From: Michael Grzeschik Date: Wed, 16 Oct 2024 15:58:06 +0200 Subject: [PATCH v7 1/9] usb: gadget: uvc: wake pump everytime we update the free list Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240403-uvc_request_length_by_interval-v7-1-e224bb1035f0@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh , Jayant Chowdhary Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1174; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=KOYB94vey15IcIEifhD0pxE/3ywuoSg72econbiOevY=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBnD8Z5OwzTS3YtusaUNYvdnd8da0k7vpqucVTOV mEniLmQiOeJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZw/GeQAKCRC/aVhE+XH0 q4LYD/9PPaYo5AxM/QjZCKDxQB/DiJSeQ6koO1itB166LtcsAw7ukVLcIfTLoJl8wKRxj8B3Kbe MixNISTNr4aaBooYk/dJHqiP2Pin6Ya9mTNUnydxIQeo9tAuPud687TtM8WbKzYoCRX4gzmeT6K xrx+EeHeuPBTov2n0a6jqatYipsI0BAW6KPm3svMgZsJWE5hAEUMplCyZK5yD3SXyo56rwKYXP+ fhGJnbuv34snmCXS3t27BlKBlThLDMHD4XNDAZS5d6R0/s8p+bZeI3H0oHqf5yzj77Yo1nDDBjT QxiHC04jfc83rPnbX0s3wTC1SGoCiE8syS0wSTd9Mtl7o6wR/aCLfd91Cu3UQIuqUTB3ups3D8C BoTLGK34dksil8vdqrq9S1J+HM0XZzuEexWC/wsDVf1fWSQUyxu7TTTo1hqXj/p/Z99a1ja/3X8 keM7hWqg6BX4+rZAnP6/npgbvEZk5pGnrp622OuFa7St6Vv+u1b04SthK58RKyEUJbXC6Eqx0H6 FxLTEAeBoR7MGQpDwXgcZqFUOT1FK1A7vMvKAj6fEHIAVh3sF0BtNVbWDLDtR3J1jU2ZIeRNtCt LDPc1BK1E/SLc5xf76pN4sTEK5dxpv7nnVUOoA6F8X9L6NPP2lhzOknqRnSww2hh9z1v42qHSTd Or9hYr0xC68I8kg== X-Developer-Key: i=m.grzeschik@pengutronix.de; a=openpgp; fpr=957BC452CE953D7EA60CF4FC0BE9E3157A1E2C64 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: m.grzeschik@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-usb@vger.kernel.org Since the req_free list will updated if enqueuing one request was not possible it will be added back to the free list. With every available free request in the queue it is a valid case for the pump worker to use it and continue the pending bufferdata into requests for the req_ready list. Fixes: 6acba0345b68 ("usb:gadget:uvc Do not use worker thread to pump isoc usb requests") Signed-off-by: Michael Grzeschik --- v5 -> v7: - v1 -> v5: - new patch --- drivers/usb/gadget/function/uvc_video.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 57a851151225d..002bf724d8025 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -480,6 +480,10 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) * up later. */ list_add_tail(&to_queue->list, &video->req_free); + /* + * There is a new free request - wake up the pump. + */ + queue_work(video->async_wq, &video->pump); } spin_unlock_irqrestore(&video->req_lock, flags); From patchwork Wed Oct 16 13:58:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 13838520 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8A5B720E02B for ; Wed, 16 Oct 2024 13:58:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087109; cv=none; b=GyhHvoYjxR8SNNzbdysCAyW5WdBvo7hYfnmzWqqYdeF1V2wSGMUkHOdL4d5xuBm7MbZVWOOQvkHNR0aDpEatlFtjPphJXvx0vCYE2GunNNlWNkY7HvnwtPKVx8G8MM0ksX2e3P1T61nkVa6johP6SDEsUdDdNFVCo6GtUZN1DDs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087109; c=relaxed/simple; bh=ooy60Kjh+R8yyJdOBwPpkv3fFDlPOvGI/ynsYu/cvOY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qBSBFmw+Axd7Vz8pxx/Dlg90aGfPlni6miwcX7HVHgAx7RvWuShZEpWy0xjBJI28hFgaBz7xT8+yTnWfcQMGrBqx/aZkbI32PsDVuu6B8HJqTgOM3j0hX50nPWcF4pOAfr/zRkRzybIN9oJQLGBbfsM1FWMOxPTZSn9hZ8DVOww= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t14Xd-0003Gz-L6; Wed, 16 Oct 2024 15:58:21 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t14Xd-002HjB-1J; Wed, 16 Oct 2024 15:58:21 +0200 Received: from localhost ([::1] helo=dude04.red.stw.pengutronix.de) by dude04.red.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1t14Xc-00BU5S-38; Wed, 16 Oct 2024 15:58:20 +0200 From: Michael Grzeschik Date: Wed, 16 Oct 2024 15:58:07 +0200 Subject: [PATCH v7 2/9] usb: gadget: uvc: only enqueue zero length requests in potential underrun Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240403-uvc_request_length_by_interval-v7-2-e224bb1035f0@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh , Jayant Chowdhary Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4026; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=ooy60Kjh+R8yyJdOBwPpkv3fFDlPOvGI/ynsYu/cvOY=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBnD8Z6XdppAEweFE2Z9KEyu37zvRrf2TQJ3kDqY 9GxAhxbXGKJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZw/GegAKCRC/aVhE+XH0 q+wFD/4jYqa0Hj9wBuLqPvWt+T1d6MzhUFjF4q4cJArzwNObFCBuA5glD8rJ/B/9VoJXSOYGpmp B7wCedYvNn2IHjbN7phgknQ5gkNi1FKF9YBwp241yua4Aq4RR5ltrjc92cpWDIp9SmRRXNj1dwB x+8knZUvmhy8/AH10/mdHZv0wqSsEVDobTtU0oRVUS9b7BUmJ0xagxywJYjHRDQR0dBmtpuTpoR 37oVCegYgf6w7n4+cBBMpYaxLLmvIxXc3JT4GwW9cRK5LJMYIUY2U7ZBWQwuZ+GZsuDwP5o0EER WKsQgwIi88LO0SoTlWIJkk4dyGO1tsd7pf3rVh66vhan+n3VgsOKpZlMOGpiQA5RQMGTqbPWHVu wVrfhpR78XKHQeALmg5rxaYUs3V/dNS5NiZ1+s4KLLUYG+iisicbLSoMnxNwI5rYRGpu8nWg6av MZjEbGrOKy8XztJF+tDTArmLvnBMIok9tJZsB+WF/3m7iX2He+Rmln8gm76qjBWF2BhaBPdPts1 MeHNxAhsKkRqCyYzAtxBr6l3tcE4PC76Ty5nYP29Es6NazVqLjvrrpezt8HIq2ycSLmrgkOeth+ IkomfA3TKYtZuadrzEb90pCbPzfHkQt6MLXESorZDoFPnYZ40y9AKSe9dTLb43cYLiej9qvPCDP NB2s7hN5X1QcCQw== X-Developer-Key: i=m.grzeschik@pengutronix.de; a=openpgp; fpr=957BC452CE953D7EA60CF4FC0BE9E3157A1E2C64 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: m.grzeschik@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-usb@vger.kernel.org The complete handler will at least be called after 16 requests have completed, but will still handle all finisher requests. Since we have to maintain a costant filling in the isoc queue we ensure this by adding zero length requests. By counting the amount enqueued requests we can ensure that the queue is never underrun and only need to get active if the queue is running critical. This patch is setting 32 as the critical level, which is twice the request amount that is needed to create interrupts. To properly solve the amount of zero length requests that needs to be held in the hardware after one interrupt needs to be measured and depends on the runtime of the first enqueue run after the interrupt triggered. For now we just use twice the amount of requests between an interrupt. Signed-off-by: Michael Grzeschik --- v5 -> v7: - v4 -> v5: - using min to limit for UVCG_REQ_MAX_INT_COUNT as the interrupt boundary - using atomic_inc, atomic_dec on one variable to avoid rollover - reordered this patch in the series - added UVCG_REQ_MAX_ZERO_COUNT to set the threshold of zero length requests in the hw - added UVCG_REQ_MAX_INT_COUNT as quantifier for the highest amount of request between an interrupt v1 -> v4: - --- drivers/usb/gadget/function/uvc.h | 5 +++++ drivers/usb/gadget/function/uvc_video.c | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index cb35687b11e7e..55d796f5f5e8d 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -71,6 +71,9 @@ extern unsigned int uvc_gadget_trace_param; #define UVCG_REQUEST_HEADER_LEN 12 +#define UVCG_REQ_MAX_INT_COUNT 16 +#define UVCG_REQ_MAX_ZERO_COUNT (2 * UVCG_REQ_MAX_INT_COUNT) + /* ------------------------------------------------------------------------ * Structures */ @@ -91,6 +94,8 @@ struct uvc_video { struct work_struct pump; struct workqueue_struct *async_wq; + atomic_t queued; + /* Frame parameters */ u8 bpp; u32 fcc; diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 002bf724d8025..c041873cf8560 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -269,6 +269,8 @@ static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req) } } + atomic_inc(&video->queued); + return ret; } @@ -304,7 +306,7 @@ static int uvcg_video_usb_req_queue(struct uvc_video *video, */ if (list_empty(&video->req_free) || ureq->last_buf || !(video->req_int_count % - DIV_ROUND_UP(video->uvc_num_requests, 4))) { + min(DIV_ROUND_UP(video->uvc_num_requests, 4), UVCG_REQ_MAX_INT_COUNT))) { video->req_int_count = 0; req->no_interrupt = 0; } else { @@ -379,6 +381,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) int ret = 0; spin_lock_irqsave(&video->req_lock, flags); + atomic_dec(&video->queued); if (!video->is_enabled) { /* * When is_enabled is false, uvcg_video_disable() ensures @@ -466,6 +469,16 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) * happen. */ queue_work(video->async_wq, &video->pump); + } else if (atomic_read(&video->queued) > UVCG_REQ_MAX_ZERO_COUNT) { + list_add_tail(&to_queue->list, &video->req_free); + /* + * There is a new free request - wake up the pump. + */ + queue_work(video->async_wq, &video->pump); + + spin_unlock_irqrestore(&video->req_lock, flags); + + return; } /* * Queue to the endpoint. The actual queueing to ep will @@ -756,6 +769,8 @@ int uvcg_video_enable(struct uvc_video *video) video->req_int_count = 0; + atomic_set(&video->queued, 0); + uvc_video_ep_queue_initial_requests(video); queue_work(video->async_wq, &video->pump); From patchwork Wed Oct 16 13:58:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 13838526 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7C53120F5B5 for ; Wed, 16 Oct 2024 13:58:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087111; cv=none; b=P5GFfjbhapunT2AJD6sUdM6gDivZWihu8m3szewR6rjdW8T1mAFYyghg8HrPjznPqgvSgqFEWmPh3zaANEQTw1hXrgABuyzmgyusKOg7RfOvX6Bv9s6kfxMdnyI2si9qT5ir0LnzEhb8B9+FHrHvUdaYDDQbEXVt37j0neW7Os8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087111; c=relaxed/simple; bh=zXcv+GZp8owNqCV32UIHQkKuIzK350cvbZnPJj04JBM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BQOxStLdp7dyPqlk2/rvCdfEUS8KMZp0bHv4oKtLLZWPovkt/rVzOewkyaF20+60bFVErGuEAmsQO5hon8N9CakWtznF0ZoO0YXz8jAK5KAVUFsuZxel3kDcjjDCBEMxwKeANRqlMjT7TY+AM0/+T/CwEE/KL0YADI60kZJnaVo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t14Xd-0003H2-Ov; Wed, 16 Oct 2024 15:58:21 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t14Xd-002HjC-31; Wed, 16 Oct 2024 15:58:21 +0200 Received: from localhost ([::1] helo=dude04.red.stw.pengutronix.de) by dude04.red.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1t14Xc-00BU5S-39; Wed, 16 Oct 2024 15:58:20 +0200 From: Michael Grzeschik Date: Wed, 16 Oct 2024 15:58:08 +0200 Subject: [PATCH v7 3/9] usb: gadget: uvc: rework to enqueue in pump worker from encoded queue Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240403-uvc_request_length_by_interval-v7-3-e224bb1035f0@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh , Jayant Chowdhary Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=10792; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=zXcv+GZp8owNqCV32UIHQkKuIzK350cvbZnPJj04JBM=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBnD8Z6/pD6SvMbEaBupeoUQ84CNdPv1HyNNjwta EUpDs7tv0iJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZw/GegAKCRC/aVhE+XH0 q0xZD/9XTDNT8YNXu5UdbZ4eJtq3VCmCn77LZQWMR048JL2HtlyaclRpsZ9AmTYNbwjjNz97hXX y4gw5nXbtAk3aWEnVhruw6UNrd2ySBdEBQ2yDKItlWdpPubV2YcAuKM7wFbwCkjpTc2oviO8c9D h0Ln/lLWrfomXVq4eu3xx7szl/9WIh1MlCLCWqyzJ0KggGMAjLQAizX6Z4LQ1vOUKdk4vFbebD3 HoZCAqbizu7/nh7qSJB3eFHDg25BE57N8d8VYrhuEHMDBU4iuF3rNa93T8z58BZnJZKOgICtzP8 6n67nkwlpjkHbSk4SvoaoMOFQIzBdRL9hSaX/7nYG9iXue116XrGuUxAWdIg+sUD2OVeX6ME1Cx LCM8BhN7W0MMehHyFU8MEK73ZeLr0IWry2cECdcGbWi5x0ynWcfQNumLXb22wgazbp3UoCMHvCl CTL5SPasdvUzOPuisMejJ5rT25xzh9GVH4A9GGCdZKRC0+pONJq72Q84CIcNO3ud/iN+LBK00If G8vFroXmaK7B+v5QT3ww+oP8EsKH/DfNelXh+V3ONYdG65r36QAzsExW/XJ51CHB7Z7jWJDe+xR GaDCWg748D3VeZXZdJgGx4dMPZvpursOnxkFMlHKkPmlog6aj68HzJPzCgMm5WHIWbpB4tOgkO1 HqHhlEvMCOeza8g== X-Developer-Key: i=m.grzeschik@pengutronix.de; a=openpgp; fpr=957BC452CE953D7EA60CF4FC0BE9E3157A1E2C64 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: m.grzeschik@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-usb@vger.kernel.org We install an kthread with pfifo priority that is iterating over all prepared requests and keeps the isoc queue busy. This way it will be scheduled with the same priority as the interrupt handler. As the kthread is triggered with video_enable it will immediately queue some zero length requests into the hw if there is no buffer data available. It also watches the level of needed zero length requests in the hardware not to fall under the UVCG_REQ_MAX_ZERO_COUNT threshold. This way we can drop the function uvc_video_ep_queue_initial_requests entirely. By using the kthread to do the actual request handling the interrupt handler will not be running into the time consuming and eventually locking work of actually enqueueing the requests back into its own pipeline. This work can now even be scheduled on another cpu. Signed-off-by: Michael Grzeschik --- v5 -> v7: - v4 -> v5: - merging patch '(drivers/usb/gadget/function/uvc_queue.h') into this one - added initial kthread_queue_work(video->kworker, &video->hw_submit); to uvcg_video_enable - fixed error message in uvcg_video_init - reordered this patch in the series - renamed the kworker to hw_submit since the pump thread is used again with the work_queue v1 -> v4: - --- drivers/usb/gadget/function/f_uvc.c | 2 + drivers/usb/gadget/function/uvc.h | 3 + drivers/usb/gadget/function/uvc_video.c | 180 +++++++++++++++----------------- 3 files changed, 87 insertions(+), 98 deletions(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 40187b7112e79..f04376768bc10 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -991,6 +991,8 @@ static void uvc_function_unbind(struct usb_configuration *c, uvcg_info(f, "%s()\n", __func__); + kthread_cancel_work_sync(&video->hw_submit); + if (video->async_wq) destroy_workqueue(video->async_wq); diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 55d796f5f5e8d..4f44a607d9f5c 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -94,6 +94,9 @@ struct uvc_video { struct work_struct pump; struct workqueue_struct *async_wq; + struct kthread_worker *kworker; + struct kthread_work hw_submit; + atomic_t queued; /* Frame parameters */ diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index c041873cf8560..06055959f7165 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -324,50 +324,6 @@ static int uvcg_video_usb_req_queue(struct uvc_video *video, return 0; } -/* - * Must only be called from uvcg_video_enable - since after that we only want to - * queue requests to the endpoint from the uvc_video_complete complete handler. - * This function is needed in order to 'kick start' the flow of requests from - * gadget driver to the usb controller. - */ -static void uvc_video_ep_queue_initial_requests(struct uvc_video *video) -{ - struct usb_request *req = NULL; - unsigned long flags = 0; - unsigned int count = 0; - int ret = 0; - - /* - * We only queue half of the free list since we still want to have - * some free usb_requests in the free list for the video_pump async_wq - * thread to encode uvc buffers into. Otherwise we could get into a - * situation where the free list does not have any usb requests to - * encode into - we always end up queueing 0 length requests to the - * end point. - */ - unsigned int half_list_size = video->uvc_num_requests / 2; - - spin_lock_irqsave(&video->req_lock, flags); - /* - * Take these requests off the free list and queue them all to the - * endpoint. Since we queue 0 length requests with the req_lock held, - * there isn't any 'data' race involved here with the complete handler. - */ - while (count < half_list_size) { - req = list_first_entry(&video->req_free, struct usb_request, - list); - list_del(&req->list); - req->length = 0; - ret = uvcg_video_ep_queue(video, req); - if (ret < 0) { - uvcg_queue_cancel(&video->queue, 0); - break; - } - count++; - } - spin_unlock_irqrestore(&video->req_lock, flags); -} - static void uvc_video_complete(struct usb_ep *ep, struct usb_request *req) { @@ -375,10 +331,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) struct uvc_video *video = ureq->video; struct uvc_video_queue *queue = &video->queue; struct uvc_buffer *last_buf; - struct usb_request *to_queue = req; unsigned long flags; - bool is_bulk = video->max_payload_size; - int ret = 0; spin_lock_irqsave(&video->req_lock, flags); atomic_dec(&video->queued); @@ -441,65 +394,85 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) return; } + list_add_tail(&req->list, &video->req_free); /* - * Here we check whether any request is available in the ready - * list. If it is, queue it to the ep and add the current - * usb_request to the req_free list - for video_pump to fill in. - * Otherwise, just use the current usb_request to queue a 0 - * length request to the ep. Since we always add to the req_free - * list if we dequeue from the ready list, there will never - * be a situation where the req_free list is completely out of - * requests and cannot recover. + * Queue work to the wq as well since it is possible that a + * buffer may not have been completely encoded with the set of + * in-flight usb requests for whih the complete callbacks are + * firing. + * In that case, if we do not queue work to the worker thread, + * the buffer will never be marked as complete - and therefore + * not be returned to userpsace. As a result, + * dequeue -> queue -> dequeue flow of uvc buffers will not + * happen. Since there are is a new free request wake up the pump. */ - to_queue->length = 0; - if (!list_empty(&video->req_ready)) { - to_queue = list_first_entry(&video->req_ready, - struct usb_request, list); - list_del(&to_queue->list); - list_add_tail(&req->list, &video->req_free); - /* - * Queue work to the wq as well since it is possible that a - * buffer may not have been completely encoded with the set of - * in-flight usb requests for whih the complete callbacks are - * firing. - * In that case, if we do not queue work to the worker thread, - * the buffer will never be marked as complete - and therefore - * not be returned to userpsace. As a result, - * dequeue -> queue -> dequeue flow of uvc buffers will not - * happen. - */ - queue_work(video->async_wq, &video->pump); - } else if (atomic_read(&video->queued) > UVCG_REQ_MAX_ZERO_COUNT) { - list_add_tail(&to_queue->list, &video->req_free); - /* - * There is a new free request - wake up the pump. - */ - queue_work(video->async_wq, &video->pump); + queue_work(video->async_wq, &video->pump); - spin_unlock_irqrestore(&video->req_lock, flags); + spin_unlock_irqrestore(&video->req_lock, flags); - return; - } - /* - * Queue to the endpoint. The actual queueing to ep will - * only happen on one thread - the async_wq for bulk endpoints - * and this thread for isoc endpoints. - */ - ret = uvcg_video_usb_req_queue(video, to_queue, !is_bulk); - if (ret < 0) { + kthread_queue_work(video->kworker, &video->hw_submit); +} + +static void uvcg_video_hw_submit(struct kthread_work *work) +{ + struct uvc_video *video = container_of(work, struct uvc_video, hw_submit); + bool is_bulk = video->max_payload_size; + unsigned long flags; + struct usb_request *req; + int ret = 0; + + while (true) { + if (!video->ep->enabled) + return; + spin_lock_irqsave(&video->req_lock, flags); /* - * Endpoint error, but the stream is still enabled. - * Put request back in req_free for it to be cleaned - * up later. + * Here we check whether any request is available in the ready + * list. If it is, queue it to the ep and add the current + * usb_request to the req_free list - for video_pump to fill in. + * Otherwise, just use the current usb_request to queue a 0 + * length request to the ep. Since we always add to the req_free + * list if we dequeue from the ready list, there will never + * be a situation where the req_free list is completely out of + * requests and cannot recover. */ - list_add_tail(&to_queue->list, &video->req_free); + if (!list_empty(&video->req_ready)) { + req = list_first_entry(&video->req_ready, + struct usb_request, list); + } else { + if (list_empty(&video->req_free) || + (atomic_read(&video->queued) > UVCG_REQ_MAX_ZERO_COUNT)) { + spin_unlock_irqrestore(&video->req_lock, flags); + + return; + } + req = list_first_entry(&video->req_free, struct usb_request, + list); + req->length = 0; + } + list_del(&req->list); + /* - * There is a new free request - wake up the pump. + * Queue to the endpoint. The actual queueing to ep will + * only happen on one thread - the async_wq for bulk endpoints + * and this thread for isoc endpoints. */ - queue_work(video->async_wq, &video->pump); - } + ret = uvcg_video_usb_req_queue(video, req, !is_bulk); + if (ret < 0) { + /* + * Endpoint error, but the stream is still enabled. + * Put request back in req_free for it to be cleaned + * up later. + */ + list_add_tail(&req->list, &video->req_free); + /* + * There is a new free request - wake up the pump. + */ + queue_work(video->async_wq, &video->pump); - spin_unlock_irqrestore(&video->req_lock, flags); + } + + spin_unlock_irqrestore(&video->req_lock, flags); + } } static int @@ -771,7 +744,7 @@ int uvcg_video_enable(struct uvc_video *video) atomic_set(&video->queued, 0); - uvc_video_ep_queue_initial_requests(video); + kthread_queue_work(video->kworker, &video->hw_submit); queue_work(video->async_wq, &video->pump); return ret; @@ -794,6 +767,17 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc) if (!video->async_wq) return -EINVAL; + /* Allocate a kthread for asynchronous hw submit handler. */ + video->kworker = kthread_create_worker(0, "UVCG"); + if (IS_ERR(video->kworker)) { + uvcg_err(&video->uvc->func, "failed to create UVCG kworker\n"); + return PTR_ERR(video->kworker); + } + + kthread_init_work(&video->hw_submit, uvcg_video_hw_submit); + + sched_set_fifo(video->kworker->task); + video->uvc = uvc; video->fcc = V4L2_PIX_FMT_YUYV; video->bpp = 16; From patchwork Wed Oct 16 13:58:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 13838518 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2A02120E01F for ; Wed, 16 Oct 2024 13:58:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087108; cv=none; b=c7bnWn6FnhwPcw8zhOVLDMyY8sE4IPti7vxm5/0D6dURWUEXSCkiH5b0IVMgCfmXZrKw8379G/tsqzkRCLBZQW28sRtdS8JnmBNvLVr3yuJ1VtQpEjNaMOAFxfPWSJbFWtVJW/4rPlpC65/2pKSjy/xjGdgX8/GkD1vZICAl/KY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087108; c=relaxed/simple; bh=sugFjLlnRL6qi61vWs3XwyGeYuxVHOvvOko5oTWsf7U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gmSo3tbolFoPpaiU0bM6YzdAnFu/aTBmwc5YWBhOVI+XRzVT7alzgj7HXvcGyH8G54BDwzOJiR/qAWoTlwcZTeXZgrD+bVUdJv9rbf6U7y9QR6NCJhLcFTEpPfbn1Ymj4dyGQ+Faid4S+5XuqUcaNotvhxst2ca8chcGkyYVbIQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t14Xd-0003H0-L5; Wed, 16 Oct 2024 15:58:21 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t14Xd-002HjD-2O; Wed, 16 Oct 2024 15:58:21 +0200 Received: from localhost ([::1] helo=dude04.red.stw.pengutronix.de) by dude04.red.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1t14Xc-00BU5S-3A; Wed, 16 Oct 2024 15:58:20 +0200 From: Michael Grzeschik Date: Wed, 16 Oct 2024 15:58:09 +0200 Subject: [PATCH v7 4/9] usb: gadget: uvc: add g_parm and s_parm for frame interval Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240403-uvc_request_length_by_interval-v7-4-e224bb1035f0@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh , Jayant Chowdhary Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4059; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=sugFjLlnRL6qi61vWs3XwyGeYuxVHOvvOko5oTWsf7U=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBnD8Z6M8kB2qi29uojUzyv2o0+HmCnBlKGjLgK1 hc47cGXyf6JAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZw/GegAKCRC/aVhE+XH0 qxhjD/9l8DN/jBe8ZWGXSmg0tH9+GFkpZs470MLiZJ5kUhR/2zlQHewf0iMTiE8z0he16/KwVWC v/tIoIymPVONePPrGAHdKCK/hg10cxeOSjJn/OPkFlHTPn9nz5s59jh87g3jJdRG2MhJoLMqbwJ SqLqdXmeXhJjj+ZVmNSM5I3IubhIZa1IqNqQEQf/m6a9upG4nmgCW2ZANvUKLjmHWRE0KtSZt4A FrYxB8uhr2Yahl2bdPJKHYIf4qP17FlQ1n8SPyu8tqRQieALMcopRkKI5kb8/2qicdSidmw5liB eej67Xuaj6uFUcvuAAxoK9TdVgLNMQa9mF8Z2Fj3AMeTt3H2t5g6HcPDveNok1yzghEYA8wvGhy hlgaQjbCIaWxe0GtH7jvpNog9kFrtvhPFr/O+NNrEdwuuN1lIGCP4kyCx1qeLrBKX3QXFYumxZk pkAV2Xgi22wLi/h+Sn5QxkDLKdVV1J5GH/JiHmI6nRdcUqe8SMHfOpKp9/oFnf6MhdmwZQszWXH RvifyKFIj3rtvfbEjvock7U8l54yXrMsV2R8+XfhqtuQusLHyBOCpF7G2Q/CaCzx75nzU/bwYWr nHgE1eMEoGaYPbyUIiMNhVCsR/No/76zB0wA+CnKts/14u0cpEWFtjpxh87sIHoV1n8yLYLuw7W UFVQvsMxgj7y4Bw== X-Developer-Key: i=m.grzeschik@pengutronix.de; a=openpgp; fpr=957BC452CE953D7EA60CF4FC0BE9E3157A1E2C64 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: m.grzeschik@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-usb@vger.kernel.org The uvc gadget driver is lacking the information which frame interval was set by the host. We add this information by implementing the g_parm and s_parm callbacks. Signed-off-by: Michael Grzeschik --- v5 -> v7: - v4 -> v5: - using !V4L2_TYPE_IS_OUTPUT to check for type - initialzing interval to same default as in configfs - reordered this patch in the series v1 -> v4: - --- drivers/usb/gadget/function/uvc.h | 1 + drivers/usb/gadget/function/uvc_v4l2.c | 52 +++++++++++++++++++++++++++++++++ drivers/usb/gadget/function/uvc_video.c | 1 + 3 files changed, 54 insertions(+) diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 4f44a607d9f5c..099038f1088ef 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -105,6 +105,7 @@ struct uvc_video { unsigned int width; unsigned int height; unsigned int imagesize; + unsigned int interval; struct mutex mutex; /* protects frame parameters */ unsigned int uvc_num_requests; diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index de1736f834e6b..ab89f1630acb0 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -314,6 +314,56 @@ uvc_v4l2_set_format(struct file *file, void *fh, struct v4l2_format *fmt) return ret; } +static int uvc_v4l2_g_parm(struct file *file, void *fh, + struct v4l2_streamparm *parm) +{ + struct video_device *vdev = video_devdata(file); + struct uvc_device *uvc = video_get_drvdata(vdev); + struct uvc_video *video = &uvc->video; + struct v4l2_fract timeperframe; + + if (!V4L2_TYPE_IS_OUTPUT(parm->type)) + return -EINVAL; + + /* Return the actual frame period. */ + timeperframe.numerator = video->interval; + timeperframe.denominator = 10000000; + v4l2_simplify_fraction(&timeperframe.numerator, + &timeperframe.denominator, 8, 333); + + uvcg_dbg(&uvc->func, "Getting frame interval of %u/%u (%u)\n", + timeperframe.numerator, timeperframe.denominator, + video->interval); + + parm->parm.output.timeperframe = timeperframe; + parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; + + return 0; +} + +static int uvc_v4l2_s_parm(struct file *file, void *fh, + struct v4l2_streamparm *parm) +{ + struct video_device *vdev = video_devdata(file); + struct uvc_device *uvc = video_get_drvdata(vdev); + struct uvc_video *video = &uvc->video; + struct v4l2_fract timeperframe; + + if (!V4L2_TYPE_IS_OUTPUT(parm->type)) + return -EINVAL; + + timeperframe = parm->parm.output.timeperframe; + + video->interval = v4l2_fraction_to_interval(timeperframe.numerator, + timeperframe.denominator); + + uvcg_dbg(&uvc->func, "Setting frame interval to %u/%u (%u)\n", + timeperframe.numerator, timeperframe.denominator, + video->interval); + + return 0; +} + static int uvc_v4l2_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival) @@ -587,6 +637,8 @@ const struct v4l2_ioctl_ops uvc_v4l2_ioctl_ops = { .vidioc_dqbuf = uvc_v4l2_dqbuf, .vidioc_streamon = uvc_v4l2_streamon, .vidioc_streamoff = uvc_v4l2_streamoff, + .vidioc_s_parm = uvc_v4l2_s_parm, + .vidioc_g_parm = uvc_v4l2_g_parm, .vidioc_subscribe_event = uvc_v4l2_subscribe_event, .vidioc_unsubscribe_event = uvc_v4l2_unsubscribe_event, .vidioc_default = uvc_v4l2_ioctl_default, diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 06055959f7165..ee7326029d6f9 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -784,6 +784,7 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc) video->width = 320; video->height = 240; video->imagesize = 320 * 240 * 2; + video->interval = 666666; /* Initialize the video buffers queue. */ uvcg_queue_init(&video->queue, uvc->v4l2_dev.dev->parent, From patchwork Wed Oct 16 13:58:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 13838525 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 79F6920F5B4 for ; Wed, 16 Oct 2024 13:58:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087110; cv=none; b=dqpPKB+rIAkhNruP/kKrEGVGbsuYYWc6tH5rP5n6TvEz7GBWEfels2Eb7GWnt1SEhJ6BVLow1cFUpNwsOBw6iVRk8SQad/sy6gTsGzzf54fYV0rtN11lAwgRe8EXihmEC8sDCHMEGIdqbtGwxMjMjLFqaMb2RzKzZDLiDm/o2cM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087110; c=relaxed/simple; bh=VkGHojJXVjUPcrVlp6aBloMUADGg7oqEWQq8vZNf8Xc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KqLCwz4LMpUT1SBf7Zv3eh2VgM7ESyPFqZmd9tCVK/eDhXtstEHBSOSPA5YaxyWLHuDsmLhEqKwlgVbXGTzABWDnhxuGQbP6eG/DHWcCTk8WisIDNnPa3D+9KikXALfYTO/JXCIX3QUjt3iBIvDvDTMFYRn5UNRpxOswIkSjZio= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t14Xd-0003H6-Ou; Wed, 16 Oct 2024 15:58:21 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t14Xd-002HjE-3d; Wed, 16 Oct 2024 15:58:21 +0200 Received: from localhost ([::1] helo=dude04.red.stw.pengutronix.de) by dude04.red.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1t14Xc-00BU5S-3B; Wed, 16 Oct 2024 15:58:20 +0200 From: Michael Grzeschik Date: Wed, 16 Oct 2024 15:58:10 +0200 Subject: [PATCH v7 5/9] usb: gadget: uvc: set req_size and n_requests based on the frame interval Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240403-uvc_request_length_by_interval-v7-5-e224bb1035f0@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh , Jayant Chowdhary Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6421; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=VkGHojJXVjUPcrVlp6aBloMUADGg7oqEWQq8vZNf8Xc=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBnD8Z7GotufjzwiWaTcI/C4V/f/yyUJUWsBSz7E KH25JBWafGJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZw/GewAKCRC/aVhE+XH0 q+wHD/9T0aqYXZV02cKRIc7vOc4kUc68pVgefAM8XLzb+MaZPdbVGuO8YOQLSSRliKU39TMNsDG hmsV60TQ6T/K5K/hGc1R9SP+w4TfBHQuEpL57dSElXEkRabcP+HYFUyO/f0VJt/dcTl3k74X6P7 W785tAA07+t/QJGILuN21FeYs1CzzdwcgXvaEL0yIBhyQOq8ElEiEwW7Ap6cfl76IQFxNJsG/A1 tlbZ6O8kRl3oYPPdLrcgIA2Jqc+PY0Wid01+D7PKFmXcfsPYAYi1cJmKrw/d1dUAOYbRKHOOKYk aUT6dhBtrpz4Cn6NkQjB1MTeSJWg9BXcJymepIqCqoS2kg0pfc6u8RAUAxvKwmRRmChe/08IBnJ 4/haYRaDpsQS5J+JPaR9W4TRgW+hQDSCvsQjj1Apc2apZyeQAJ0pku9pCQJtLV04Zkns4D15cjN IhL6cuxp2Q3X72QWTk8S81XYr5ldl5jH+NR8Pc67HN8hufaV1Zj+xF0IffSp/zYk0j7k7w8EVH6 eXNVb9T2LlfEWqrpgmF8FR6/+eWWPzBkiAFsKHNFTrLfkt5C/MKy4QyuzPcq46FmxbdFtmdklOi u4BuGz8qjcUqRRlF0170394+mY0n9ibjpJdIYSt6KLGR/H0+TQvy0nb8EQRnfvonYR+gbR3szrL eVnlJ2/pz/ivvHw== X-Developer-Key: i=m.grzeschik@pengutronix.de; a=openpgp; fpr=957BC452CE953D7EA60CF4FC0BE9E3157A1E2C64 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: m.grzeschik@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-usb@vger.kernel.org This patch is removing the initial imprecise and limited calculation of requests needed to be used from the queue_setup callback. It instead introduces the uvc_video_prep_requests function which is called immediately before the request allocation. With the information of the usb frame interval length it is possible to calculate the number of requests needed during one frame duration. Based on the calculated number of requests and the imagesize we calculate the actual size per request. This calculation has the benefit that the frame data is equally distributed over all allocated requests. When the req_size is not in the range for the actually configured max_req_size configured for the overall bandwidth we fallback to use the max_req_size instead. Since this calculations are only important for isoc transfers we just use max_request_size for bulk and skip it. As video->req_size will be recalculated on every video_enable resetting it to 0 is not necessary anymore. Signed-off-by: Michael Grzeschik --- v5 -> v7: - v4 -> v5: - reordered this patch in the series - merging previous extra patch: ('usb: gadget: uvc: set req_size once when the vb2 queue is calculated') - moved the overall request size calculation to one seperate function - only calculating once before enabling the video ep v3 -> v4: - v2 -> v3: - added the frame duration for full-speed devices into calculation v1 -> v2: - add headersize per request into calculation --- drivers/usb/gadget/function/uvc_queue.c | 13 ------- drivers/usb/gadget/function/uvc_video.c | 68 +++++++++++++++++++++++++++------ 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index 0aa3d7e1f3cc3..731e3b9d21acc 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -44,8 +44,6 @@ static int uvc_queue_setup(struct vb2_queue *vq, { struct uvc_video_queue *queue = vb2_get_drv_priv(vq); struct uvc_video *video = container_of(queue, struct uvc_video, queue); - unsigned int req_size; - unsigned int nreq; if (*nbuffers > UVC_MAX_VIDEO_BUFFERS) *nbuffers = UVC_MAX_VIDEO_BUFFERS; @@ -54,17 +52,6 @@ static int uvc_queue_setup(struct vb2_queue *vq, sizes[0] = video->imagesize; - req_size = video->ep->maxpacket - * max_t(unsigned int, video->ep->maxburst, 1) - * (video->ep->mult); - - /* We divide by two, to increase the chance to run - * into fewer requests for smaller framesizes. - */ - nreq = DIV_ROUND_UP(DIV_ROUND_UP(sizes[0], 2), req_size); - nreq = clamp(nreq, 4U, 64U); - video->uvc_num_requests = nreq; - return 0; } diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index ee7326029d6f9..ecb32a3e03760 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -486,23 +486,70 @@ uvc_video_free_requests(struct uvc_video *video) INIT_LIST_HEAD(&video->ureqs); INIT_LIST_HEAD(&video->req_free); INIT_LIST_HEAD(&video->req_ready); - video->req_size = 0; return 0; } +static void +uvc_video_prep_requests(struct uvc_video *video) +{ + struct uvc_device *uvc = container_of(video, struct uvc_device, video); + struct usb_composite_dev *cdev = uvc->func.config->cdev; + unsigned int interval_duration = video->ep->desc->bInterval * 1250; + unsigned int max_req_size, req_size, header_size; + unsigned int nreq; + + max_req_size = video->ep->maxpacket + * max_t(unsigned int, video->ep->maxburst, 1) + * (video->ep->mult); + + if (!usb_endpoint_xfer_isoc(video->ep->desc)) { + video->req_size = max_req_size; + video->uvc_num_requests = + DIV_ROUND_UP(video->imagesize, max_req_size); + + return; + } + + if (cdev->gadget->speed < USB_SPEED_HIGH) + interval_duration = video->ep->desc->bInterval * 10000; + + nreq = DIV_ROUND_UP(video->interval, interval_duration); + + header_size = nreq * UVCG_REQUEST_HEADER_LEN; + + req_size = DIV_ROUND_UP(video->imagesize + header_size, nreq); + + if (req_size > max_req_size) { + /* The prepared interval length and expected buffer size + * is not possible to stream with the currently configured + * isoc bandwidth. Fallback to the maximum. + */ + req_size = max_req_size; + } + video->req_size = req_size; + + /* We need to compensate the amount of requests to be + * allocated with the maximum amount of zero length requests. + * Since it is possible that hw_submit will initially + * enqueue some zero length requests and we then will not be + * able to fully encode one frame. + */ + video->uvc_num_requests = nreq + UVCG_REQ_MAX_ZERO_COUNT; +} + static int uvc_video_alloc_requests(struct uvc_video *video) { struct uvc_request *ureq; - unsigned int req_size; unsigned int i; int ret = -ENOMEM; - BUG_ON(video->req_size); - - req_size = video->ep->maxpacket - * max_t(unsigned int, video->ep->maxburst, 1) - * (video->ep->mult); + /* + * calculate in uvc_video_prep_requests + * - video->uvc_num_requests + * - video->req_size + */ + uvc_video_prep_requests(video); for (i = 0; i < video->uvc_num_requests; i++) { ureq = kzalloc(sizeof(struct uvc_request), GFP_KERNEL); @@ -513,7 +560,7 @@ uvc_video_alloc_requests(struct uvc_video *video) list_add_tail(&ureq->list, &video->ureqs); - ureq->req_buffer = kmalloc(req_size, GFP_KERNEL); + ureq->req_buffer = kmalloc(video->req_size, GFP_KERNEL); if (ureq->req_buffer == NULL) goto error; @@ -531,12 +578,10 @@ uvc_video_alloc_requests(struct uvc_video *video) list_add_tail(&ureq->req->list, &video->req_free); /* req_size/PAGE_SIZE + 1 for overruns and + 1 for header */ sg_alloc_table(&ureq->sgt, - DIV_ROUND_UP(req_size - UVCG_REQUEST_HEADER_LEN, + DIV_ROUND_UP(video->req_size - UVCG_REQUEST_HEADER_LEN, PAGE_SIZE) + 2, GFP_KERNEL); } - video->req_size = req_size; - return 0; error: @@ -689,7 +734,6 @@ uvcg_video_disable(struct uvc_video *video) INIT_LIST_HEAD(&video->ureqs); INIT_LIST_HEAD(&video->req_free); INIT_LIST_HEAD(&video->req_ready); - video->req_size = 0; spin_unlock_irqrestore(&video->req_lock, flags); /* From patchwork Wed Oct 16 13:58:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 13838522 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2283E20F5A4 for ; Wed, 16 Oct 2024 13:58:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087110; cv=none; b=szKDvI56Dzc1aMFgIIwx73YavnRQbCxnWVp/qL0cnJmWWAO/R8bUsgx9iuFZ6c381eEVWYxDPLNaSUN7+NE4yRI0DCFjVNZmCcCKdT2I4rVb3iS7ZHst/Ni4pgJVN5mjpUGXNTZAMqa0Y7mEGPhk57M76vUTx+NQ3r0qtoJESAk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087110; c=relaxed/simple; bh=SCnB0IVoVu6QPaJhJtJ6/MNhWTj2P5Lgsxjj60AYCOE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=n0fb/0XKuCWu0I8iZDsFjLUV9N0MoDZwi4OZ6TnU8rNn9Gz4GNw0SxEzhuSicCH80coQ5+uKzvteMJgi2EwJLakJxbPkAZ81k7pBlN94LeUJxshPvlQCI05gu2Tt3rerGfvRaQBXioCZIIUoa8hTc2zbuRNBMQd+U9wCRzW31B0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t14Xd-0003H7-O8; Wed, 16 Oct 2024 15:58:21 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t14Xd-002HjF-3Q; Wed, 16 Oct 2024 15:58:21 +0200 Received: from localhost ([::1] helo=dude04.red.stw.pengutronix.de) by dude04.red.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1t14Xc-00BU5S-3C; Wed, 16 Oct 2024 15:58:20 +0200 From: Michael Grzeschik Date: Wed, 16 Oct 2024 15:58:11 +0200 Subject: [PATCH v7 6/9] usb: gadget: uvc: set req_length based on payload by nreqs instead of req_size Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240403-uvc_request_length_by_interval-v7-6-e224bb1035f0@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh , Jayant Chowdhary Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5699; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=SCnB0IVoVu6QPaJhJtJ6/MNhWTj2P5Lgsxjj60AYCOE=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBnD8Z7MDvY04M2QbiBFOOaXdzGsMMTnhd8RJmsh qenuA+BN2eJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZw/GewAKCRC/aVhE+XH0 q6t6EACKyNRQC6z87LfLnC259TWATLnFXQErAbbTEuexdWnS4BIjk6gHq0rweeXu6G6NHKJr/DW KJEgKCHGuOZnoMq12skmYYJ97Wut5OFn+sw2yCm+w3WtU6UVy+Wdw5n9RFi0Vkum786lZirVehS xpiT31mmjoEdX521TSVhQSO9koofBoKm37fAkfVH1aWRjlHdMJ1kLaVt4CsO8Vj4DopdkbBis66 Vg0AL47O+5dQc4a5FAeV7h2ia5yoJNEmQO29a2dhVp6+dtCL/wL0EIy9RcvjoqLpKAHKHsBsP26 ZghFoWwZ5vaO5OBMaE6t+eFijnULzCYXjUNrfsn0okFrY69aQ0NSlIowEbLq13Nr+ckjISOQnfl PVNOg4igB0CFEcKWlXyIWrHAmZsAy9njMmgkqgUoIAZyVBOOrZ0aNGo/REUk8DvI128nO0iCI4R faBa40YVp8ycWWRTkyMgOLn353tx1srrSiVMaveBi2/vN0nZmkOqHyyUN0UziSXMHtJDymhmdIQ aUNRFhF9otcxa9WKGPe8kkeany0JVOKOZdD3dpDHlqkAIYhwfVEI4bK2/JOJtr+nhE3sfrYFtbK emCM9OLESvxYpRBjel1zO5Cc01DOfwtpXXQ/aR8dj+yKAU/PEmbsn8ZRoOMMTBiQ0Icp1zd+N4T xTmOKOzz+0vV+IA== X-Developer-Key: i=m.grzeschik@pengutronix.de; a=openpgp; fpr=957BC452CE953D7EA60CF4FC0BE9E3157A1E2C64 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: m.grzeschik@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-usb@vger.kernel.org Compressed formats generate content depending amount of data that is set in the vb2 buffer by the payload_size. When streaming those formats it is better to scatter that smaller data over all requests. This patch is doing that by introducing the calculated req_payload_size which is updated by each frame. It the uses this amount of data to fill the isoc requests instead of the video->req_size. For uncompressed formats it will not make a difference since the payload size will be equal to the imagesize. Therefore the code will have no effecta as req_payload_size will be equal to req_size. Signed-off-by: Michael Grzeschik --- v5 -> v7: - v4 -> v5: - keep using req_size instead of len in encode_isoc_sg to be more explicit - using new initialized variable reqs_per_frame instead of two calculations - reordered this patch in the series v1 -> v4: - --- drivers/usb/gadget/function/uvc.h | 2 ++ drivers/usb/gadget/function/uvc_queue.c | 10 ++++++++-- drivers/usb/gadget/function/uvc_queue.h | 2 ++ drivers/usb/gadget/function/uvc_video.c | 15 ++++++++------- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 099038f1088ef..bedb4ef42864f 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -110,6 +110,8 @@ struct uvc_video { unsigned int uvc_num_requests; + unsigned int reqs_per_frame; + /* Requests */ bool is_enabled; /* tracks whether video stream is enabled */ unsigned int req_size; diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index 731e3b9d21acc..6757a4e25a743 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -58,6 +58,7 @@ static int uvc_queue_setup(struct vb2_queue *vq, static int uvc_buffer_prepare(struct vb2_buffer *vb) { struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); + struct uvc_video *video = container_of(queue, struct uvc_video, queue); struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf); @@ -78,10 +79,15 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb) buf->mem = vb2_plane_vaddr(vb, 0); } buf->length = vb2_plane_size(vb, 0); - if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { buf->bytesused = 0; - else + } else { buf->bytesused = vb2_get_plane_payload(vb, 0); + buf->req_payload_size = + DIV_ROUND_UP(buf->bytesused + + (video->reqs_per_frame * UVCG_REQUEST_HEADER_LEN), + video->reqs_per_frame); + } return 0; } diff --git a/drivers/usb/gadget/function/uvc_queue.h b/drivers/usb/gadget/function/uvc_queue.h index 41f87b917f6bc..b54becc570a38 100644 --- a/drivers/usb/gadget/function/uvc_queue.h +++ b/drivers/usb/gadget/function/uvc_queue.h @@ -39,6 +39,8 @@ struct uvc_buffer { unsigned int offset; unsigned int length; unsigned int bytesused; + /* req_payload_size: only used with isoc */ + unsigned int req_payload_size; }; #define UVC_QUEUE_DISCONNECTED (1 << 0) diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index ecb32a3e03760..677eaf5b7e4d0 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -136,7 +136,7 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video, unsigned int pending = buf->bytesused - video->queue.buf_used; struct uvc_request *ureq = req->context; struct scatterlist *sg, *iter; - unsigned int len = video->req_size; + unsigned int len = buf->req_payload_size; unsigned int sg_left, part = 0; unsigned int i; int header_len; @@ -146,15 +146,15 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video, /* Init the header. */ header_len = uvc_video_encode_header(video, buf, ureq->header, - video->req_size); + buf->req_payload_size); sg_set_buf(sg, ureq->header, header_len); len -= header_len; if (pending <= len) len = pending; - req->length = (len == pending) ? - len + header_len : video->req_size; + req->length = (len == pending) ? len + header_len : + buf->req_payload_size; /* Init the pending sgs with payload */ sg = sg_next(sg); @@ -202,7 +202,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, { void *mem = req->buf; struct uvc_request *ureq = req->context; - int len = video->req_size; + int len = buf->req_payload_size; int ret; /* Add the header. */ @@ -214,7 +214,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, ret = uvc_video_encode_data(video, buf, mem, len); len -= ret; - req->length = video->req_size - len; + req->length = buf->req_payload_size - len; if (buf->bytesused == video->queue.buf_used || video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) { @@ -504,7 +504,7 @@ uvc_video_prep_requests(struct uvc_video *video) if (!usb_endpoint_xfer_isoc(video->ep->desc)) { video->req_size = max_req_size; - video->uvc_num_requests = + video->reqs_per_frame = video->uvc_num_requests = DIV_ROUND_UP(video->imagesize, max_req_size); return; @@ -535,6 +535,7 @@ uvc_video_prep_requests(struct uvc_video *video) * able to fully encode one frame. */ video->uvc_num_requests = nreq + UVCG_REQ_MAX_ZERO_COUNT; + video->reqs_per_frame = nreq; } static int From patchwork Wed Oct 16 13:58:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 13838524 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 67A9220E019 for ; Wed, 16 Oct 2024 13:58:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087110; cv=none; b=QLETxXa7wFInTLuqrMK9NkvUWDca9uDloAbD+mEBV644xCzjvN7qHxtFy3kSSohlMygwQh2z+cbF/S8cKVq5Rc12nmrt3l3Cu8LTRIew3kO8tEq2xyoqYO61jA5/Zk61ZLyWFKiTemoSsnkTme0t/WxTrA4RPQMWB6YGOR6ypis= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087110; c=relaxed/simple; bh=p1xoTdRWHxbpJYFPocjjD/k91A3hz/ET82iys+wS7Os=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZmZYad95bKuJCGuSz8pbzBY1nANBOO1dbIRr8tcxHl7AxgP2CQcqKmxAE85YdViAxNZKbsx21orTRsFiN83J69ag8osWG3mm60xcMx9bYkgzcWUBChB7lzeDcBwGDxMIPxil8RD0+2LgC5ygT8R30/SldugC6iqGMNOUQb9nQMY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t14Xd-0003H5-PT; Wed, 16 Oct 2024 15:58:21 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t14Xd-002HjG-3B; Wed, 16 Oct 2024 15:58:21 +0200 Received: from localhost ([::1] helo=dude04.red.stw.pengutronix.de) by dude04.red.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1t14Xc-00BU5S-3D; Wed, 16 Oct 2024 15:58:20 +0200 From: Michael Grzeschik Date: Wed, 16 Oct 2024 15:58:12 +0200 Subject: [PATCH v7 7/9] usb: gadget: uvc: set nbuffers to minimum STREAMING_MIN_BUFFERS in uvc_queue_setup Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240403-uvc_request_length_by_interval-v7-7-e224bb1035f0@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh , Jayant Chowdhary Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1928; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=p1xoTdRWHxbpJYFPocjjD/k91A3hz/ET82iys+wS7Os=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBnD8Z7Om6EfinVW5Cow+C1IkkkMK4IdC0diReNx dzxIDjTu0CJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZw/GewAKCRC/aVhE+XH0 q6uwD/0aizggiuVqSZMlzlvvriGjXgtsSLE3YyciXl3VVz5Hs1+fMvak+5wYsSXZ0IXcC4M+bWd XEhD6DsTGUlO0bXXnazYZ/JgPf+BUlegErqjYXAv9rDwVjprPQ1zaAEhAmCjX+0zJeI8y5azG0I aJcIb7qpsDGzL3406CvEAVj1bPq6e5bce7Uk2mmTnkAUiyVEIGoVheN9h2/blQ9F6gJyBfL1ziy mojFkGODORs5Zj0kXMu1YGY7128C1/8PyplPQw2uJwaXqsaCNCnDhL6jnMgHXhjNZOaHAepluEL KEglKE4ndvQlnRsBTmvtENL3SM0EQ0XklyDQt3UWvwNE1QHJHXsAAV9xARR/YNu73uEnFCYvjTu imiR5FostREvwqVmUB7cUMIqHTBDrjrKusRbnCmgBoKf00pFKEM13QnDN3xkTDr2+YL036VH9xj hrrIDElEZ2bxzVbDc8kKyR9yo6/TWJl2MNea6S7EHElESFo00khtO/13a9gaP7q81yCXD+FmeqU WLBAb1/YJ7R70lRW2MZv0TEIB4I9sxUt2QWkAL0BzCYZpH2G5NLGWYGHdtjDAP8YawUNCfXPbVP w5llwQ4oLrpYZ7I9+iWXh3YL5R1cLO7i39aE+qa17nKvpMS1ZRXYnf8+YyZdgrKqGcNOVIoaTtF UEHR2p13Grmj7MQ== X-Developer-Key: i=m.grzeschik@pengutronix.de; a=openpgp; fpr=957BC452CE953D7EA60CF4FC0BE9E3157A1E2C64 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: m.grzeschik@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-usb@vger.kernel.org We set the minimum amount of v4l2 buffers that is possibly be pending to UVCG_STREAMING_MIN_BUFFERS which is two. This way the driver will always have at least one frame pending to be encoded while the other is being enqueued in the hardware. Signed-off-by: Michael Grzeschik --- v5 -> v7: - v4 -> v5: - using STREAMING_MIN_BUFFERS set the min nbuffers - renamed the patch since the function changed - removed the g_ctrl function - reordered this patch in the series v1 -> v4: - --- drivers/usb/gadget/function/uvc.h | 2 ++ drivers/usb/gadget/function/uvc_queue.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index bedb4ef42864f..6f44dd7323150 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -74,6 +74,8 @@ extern unsigned int uvc_gadget_trace_param; #define UVCG_REQ_MAX_INT_COUNT 16 #define UVCG_REQ_MAX_ZERO_COUNT (2 * UVCG_REQ_MAX_INT_COUNT) +#define UVCG_STREAMING_MIN_BUFFERS 2 + /* ------------------------------------------------------------------------ * Structures */ diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index 6757a4e25a743..5eaeae3e2441c 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -21,6 +21,7 @@ #include #include "uvc.h" +#include "uvc_video.h" /* ------------------------------------------------------------------------ * Video buffers queue management. @@ -47,6 +48,8 @@ static int uvc_queue_setup(struct vb2_queue *vq, if (*nbuffers > UVC_MAX_VIDEO_BUFFERS) *nbuffers = UVC_MAX_VIDEO_BUFFERS; + if (*nbuffers < UVCG_STREAMING_MIN_BUFFERS) + *nbuffers = UVCG_STREAMING_MIN_BUFFERS; *nplanes = 1; From patchwork Wed Oct 16 13:58:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 13838527 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7DE9820F5B6 for ; Wed, 16 Oct 2024 13:58:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087111; cv=none; b=gh3BzCWZpRYznZneBgZhvRU3ostc01xQwkvBOSZA2m70oNMn0RomWPOsV3h9fGxirmFnygeqvcRrAytUgGCCylqhJB1qh2k/kgEFn4q8+YfrpNYfKmb+prku7ymvBYLP0QUIn25Xv+0qKpX5IGlTr9OqcK6NU4oJKJsW10CgRZI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087111; c=relaxed/simple; bh=0mH4CO2b/d19TFj3TcXj0yg1eJ2aecYH2/1yxCflbn8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WUUw1oYVOnhyXJcNhX+l7fJM1epMXqMDrZEl6B+d4YDq/mq4cljG6emjZQHB0lc+ccICVScNKVan20a8A4faDOsjAIMWEmGmHu5Hhq7WWsJlLw27AS6EU9tJSPUI6fag414Laavyng8ghpqSKIPicfTrpBG+zjmjFv/rgk7MGnE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t14Xd-0003H3-PX; Wed, 16 Oct 2024 15:58:21 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t14Xd-002HjH-3I; Wed, 16 Oct 2024 15:58:21 +0200 Received: from localhost ([::1] helo=dude04.red.stw.pengutronix.de) by dude04.red.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1t14Xd-00BU5S-00; Wed, 16 Oct 2024 15:58:21 +0200 From: Michael Grzeschik Date: Wed, 16 Oct 2024 15:58:13 +0200 Subject: [PATCH v7 8/9] usb: gadget: uvc: add trace of enqueued and completed requests Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240403-uvc_request_length_by_interval-v7-8-e224bb1035f0@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh , Jayant Chowdhary Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4563; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=0mH4CO2b/d19TFj3TcXj0yg1eJ2aecYH2/1yxCflbn8=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBnD8Z8mDtmNcR5F4/cpzQ/l8FFDJ3HRyuqKlOOy 0Owx3cZMC+JAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZw/GfAAKCRC/aVhE+XH0 q25UEAC3HbWR+gG5dFir37oWCwKAXD0ElHI4qvtwL4qgnpVn7ofoNjxYzI/zm8FAZGv/qYlafTf D5XPpsmkiAk29/kym8rBpDMBZVaZS7mm5VVlch/4vMqH+ji6/Mm5sp3kg6cR3tNvTRCs0NpBllD K4ynZf/1UdFCAjyHNW8RthOU61Y0W15IehYhTC+sJWyZXV/LD6doewa+c+vyWyd9lX+cpuWhn06 RyZuVJZLgozEKNgy3yb9t8GMdX1VTH8YxqgYDakE2F5d8PQRlr+Nr9OvS9Wxr2NCyLv5UC49yf4 E9xhZAylLfpsvY3+E0hVi7JVn4CxM/EU754IyuvZ5692xF+uzdyjLvhxXmbkFK9d6dxnzvrPA7f ybspTsJeBEUq5Dy+69EUPtFgVADFdSSMeI9K4by2FJbUBiyrtL0caf6u1UhobEVsbmCa1Q4KyGl rPM8nTizmO1xzrL56Wl/e69Rv+jujXfVhQBjwjtg3P/aJUW+F/I98LWQKSYnVC/8xntlFPGC2PP RWDXABoqVbY13Nd6b/rY9tU3vKQNTXMvjYmMRomOwIkbhi6KuUKx8qEqoLw3E3Ebk9Gf36KWJVP 8ymlo+t+0n6rzYvCWDdMiUyIBg9LHO3PoZVISu90oTA1b0ceANpSrIAJP8M0EMGZAXSu83p0hPZ 1DEKm8zFQL3ifTg== X-Developer-Key: i=m.grzeschik@pengutronix.de; a=openpgp; fpr=957BC452CE953D7EA60CF4FC0BE9E3157A1E2C64 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: m.grzeschik@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-usb@vger.kernel.org This patch is adding trace events for each request that is being enqueued into the hw and will be completed. This way it is possible to track the fill status of the gadget hardware and find potential issues. Signed-off-by: Michael Grzeschik --- v6 -> v7: - add missing CFLAGS for uvc_trace.o in Makefile v5 -> v6: - fixed compile rule as module - reordered header files v1 -> v5: - new patch --- drivers/usb/gadget/function/Makefile | 4 +++ drivers/usb/gadget/function/uvc_trace.c | 11 ++++++ drivers/usb/gadget/function/uvc_trace.h | 60 +++++++++++++++++++++++++++++++++ drivers/usb/gadget/function/uvc_video.c | 5 +++ 4 files changed, 80 insertions(+) diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index 87917a7d4a9be..7ce1637276f09 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -41,6 +41,10 @@ obj-$(CONFIG_USB_F_UAC1_LEGACY) += usb_f_uac1_legacy.o usb_f_uac2-y := f_uac2.o obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_configfs.o +ifneq ($(CONFIG_TRACING),) + CFLAGS_uvc_trace.o := -I$(src) + usb_f_uvc-y += uvc_trace.o +endif obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o usb_f_midi-y := f_midi.o obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o diff --git a/drivers/usb/gadget/function/uvc_trace.c b/drivers/usb/gadget/function/uvc_trace.c new file mode 100644 index 0000000000000..d384f6d8221a5 --- /dev/null +++ b/drivers/usb/gadget/function/uvc_trace.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * trace.c - USB UVC Gadget Trace Support + * + * Copyright (C) 2024 Pengutronix e.K. + * + * Author: Michael Grzeschik + */ + +#define CREATE_TRACE_POINTS +#include "uvc_trace.h" diff --git a/drivers/usb/gadget/function/uvc_trace.h b/drivers/usb/gadget/function/uvc_trace.h new file mode 100644 index 0000000000000..04c33cf43cc2d --- /dev/null +++ b/drivers/usb/gadget/function/uvc_trace.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * trace.h - USB UVC Gadget Trace Support + * + * Copyright (C) 2024 Pengutronix e.K. + * + * Author: Michael Grzeschik + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM uvcg + +#if !defined(__UVCG_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define __UVCG_TRACE_H + +#include +#include +#include +#include + +DECLARE_EVENT_CLASS(uvcg_video_req, + TP_PROTO(struct usb_request *req, u32 queued), + TP_ARGS(req, queued), + TP_STRUCT__entry( + __field(struct usb_request *, req) + __field(u32, length) + __field(u32, queued) + ), + TP_fast_assign( + __entry->req = req; + __entry->length = req->length; + __entry->queued = queued; + ), + TP_printk("req %p length %u queued %u", + __entry->req, + __entry->length, + __entry->queued) +); + +DEFINE_EVENT(uvcg_video_req, uvcg_video_complete, + TP_PROTO(struct usb_request *req, u32 queued), + TP_ARGS(req, queued) +); + +DEFINE_EVENT(uvcg_video_req, uvcg_video_queue, + TP_PROTO(struct usb_request *req, u32 queued), + TP_ARGS(req, queued) +); + +#endif /* __UVCG_TRACE_H */ + +/* this part has to be here */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . + +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE uvc_trace + +#include diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 677eaf5b7e4d0..23fad3bc72c03 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -19,6 +19,7 @@ #include "uvc.h" #include "uvc_queue.h" #include "uvc_video.h" +#include "uvc_trace.h" /* -------------------------------------------------------------------------- * Video codecs @@ -271,6 +272,8 @@ static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req) atomic_inc(&video->queued); + trace_uvcg_video_queue(req, atomic_read(&video->queued)); + return ret; } @@ -408,6 +411,8 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) */ queue_work(video->async_wq, &video->pump); + trace_uvcg_video_complete(req, atomic_read(&video->queued)); + spin_unlock_irqrestore(&video->req_lock, flags); kthread_queue_work(video->kworker, &video->hw_submit); From patchwork Wed Oct 16 13:58:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 13838521 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 67BBD20E022 for ; Wed, 16 Oct 2024 13:58:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087110; cv=none; b=SJHaOPSJ3d8XmLVJ11Mz0PWCneJShgQZf7EisfHasv07m/pJG6vDJJIYe0FOujWp/Ot9iHClJOlVJDoKXgCI349HYQpz9+VhtZkUuMd/zclC1+23cJ+R+jW/bxi/DTvA/BgL6TzE2E73EZ1KCZZ2WxIRIXXf3vFC1TAldVILjyk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729087110; c=relaxed/simple; bh=lxMrwpZ77rgZrCcv4E5I3U8EaQhP4MIcvyniUzUZWhA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RH//vlSWStabpQGjx1i51FVXyi6OK863UKp9rteIl5VoZowBr2Li+JgEWvdrevq4zI9GUl1vqPv56uFilNE6sVWqZrMENAe8UyKYrU81Y5sP6APCyqBHCEuGpUGAKJWJi77do8TlSf4HqebWygdanjQ0UQKxpv4MQz1LliYI2p8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t14Xd-0003H4-O8; Wed, 16 Oct 2024 15:58:21 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t14Xd-002HjI-3L; Wed, 16 Oct 2024 15:58:21 +0200 Received: from localhost ([::1] helo=dude04.red.stw.pengutronix.de) by dude04.red.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1t14Xd-00BU5S-01; Wed, 16 Oct 2024 15:58:21 +0200 From: Michael Grzeschik Date: Wed, 16 Oct 2024 15:58:14 +0200 Subject: [PATCH v7 9/9] usb: gadget: uvc: dont call usb_composite_setup_continue when not streaming Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240403-uvc_request_length_by_interval-v7-9-e224bb1035f0@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v7-0-e224bb1035f0@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh , Jayant Chowdhary Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1116; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=lxMrwpZ77rgZrCcv4E5I3U8EaQhP4MIcvyniUzUZWhA=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBnD8Z88gJtVaxHj75VmfrPgW5ryXP6R57oHQ4T8 QMXUsyvSD2JAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZw/GfAAKCRC/aVhE+XH0 qzZeD/9LNNHzSWIZRPjbyAcnY5lTswVMrMdcGtoylDHPnrj1xoxad4+5W9s9ZA1tUHIm4txVDdF Fen1nYlDehldlyn68Ca2h8oVcr5ZQdQhnwGteFYw9/LwXIqOpO8pRSBy5Sq0YPo5pJcB7HDvoJA CFJ7uIV8gmu5PQAy619EgSnbRWMm0k/qzrAkcUUioed24lWB/8AoA5nCNX0RtfVpA1CGnGwBDen Q7dETeO7OxWiXZfx7PLaC4/KHGD2C6qvLrKnCd4ua1/bcAC3icYsqlzhnlSslmgo27IhPcIAFSd pyWGd1qFRp2X5s9BbpaTy8bQ8KkwHWMGXZiE12uxUGYAKkZ8Xd/+MdvItMMT7SNeu69d00tISWP q/4X9Fhi6x1vAuOMPxelGUGgUS0iPVP6HuGDgaFS6+jMD2v9a8Ak6pta5f/NaVNKKr72lFQuSlA GlvZdTujNFvORsVb9zMiAXqiY9IeZjCYuBTybWtjv71Ww2ajIQdxU3C1G+OYEML8j6yPwJFlWv2 nYsLnxpec9vEuEejNfG5aH7nyg3MEoRcp727ge4CUdz18jiRGtArhS8An+q3LhgxC0huG4I36Ej Kaj0bDsWQOU2ekmUxJLn+IFcl958dEbUYFJ9Gp2ipKO3N6TQbb0Px/Y4PAju7LAtgY70KmgMKPN OO+6VMxkQQVT2oQ== X-Developer-Key: i=m.grzeschik@pengutronix.de; a=openpgp; fpr=957BC452CE953D7EA60CF4FC0BE9E3157A1E2C64 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: m.grzeschik@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-usb@vger.kernel.org If the streamoff call was triggered by some previous disconnect or userspace application shutdown the uvc_function_setup_continue should not be called and the state should not be overwritten. For this situation the set_alt(0) was never called and the streaming ep has no USB_GADGET_DELAYED_STATUS pending. Since the state then was already updated before we also omit the state update. Signed-off-by: Michael Grzeschik --- v5 -> v7: - v1 -> v5: - new patch --- drivers/usb/gadget/function/uvc_v4l2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index ab89f1630acb0..3492855f0fb29 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -546,6 +546,9 @@ uvc_v4l2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) if (ret < 0) return ret; + if (uvc->state != UVC_STATE_STREAMING) + return 0; + uvc->state = UVC_STATE_CONNECTED; uvc_function_setup_continue(uvc, 1); return 0;