From patchwork Thu Sep 26 23:37:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 831156 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 C9ECB1B07BC for ; Thu, 26 Sep 2024 23:37:50 +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=1727393875; cv=none; b=cr+rbUlZ9cYwg4boUJQpoZVCGF7cVZ6PCzCvtVzRWNkUJDU9B+yutiit8M+/bzTsSwv2i3PVQMVmlaNBl3DyfSoq6boauDnuiJLVds5vq/oz9sE+e2t/vJAYPWbojH9VEpnE9uMWQNW/unCJE++RF6JqyDwHiSjaTbSnvbrCWlA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727393875; c=relaxed/simple; bh=WxO9FtiUOTZsczgqkrChh1s/riJQM+B/cX5Zyz/pI8Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=R/Mdka18cCl4UsRs4Fp7PIhgmpSzr/gQ1FQy7uZW1nwnauKjOE9w08EfKnVhF64RVzj7UqW0PSQyo5mxI0dERPMpP9d6tsY9jQEiH1WiIiH32S9xfUKfKaPEuSaQRPtgKm5peVjgaOsXIMJaDFb7Hqk7hJgJqi7/SoavWWYHqDI= 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 1sty3M-0007WH-W9; Fri, 27 Sep 2024 01:37:45 +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 1sty3M-001nOS-C7; Fri, 27 Sep 2024 01:37:44 +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 1sty3L-005IAz-2s; Fri, 27 Sep 2024 01:37:44 +0200 From: Michael Grzeschik Date: Fri, 27 Sep 2024 01:37:40 +0200 Subject: [PATCH v5 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-v5-1-2de78794365c@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@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, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1131; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=WxO9FtiUOTZsczgqkrChh1s/riJQM+B/cX5Zyz/pI8Y=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBm9fBE87K/lCGYSq61GH93p/Kp43Ax28QA1oXFb /hEf3UlBSqJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZvXwRAAKCRC/aVhE+XH0 qwEpD/9vV+ue53srQIH2xrzTw2RGRx0vuHfO1CfTnVsH7x7czHwmnHrrt/Icq4sYYcpE4KIbjIm PGKMxiqVKDNhaaSanozcoJdQsEJC/fVdkCzP+6+aE8fsieUDRXBll7khL9nMko8Xo+DZWeY7Flm dZLGV/k4bCUl2Yx2xQ/DFcT2YkgbDHJUW5EFqgIA9z9ZkhRNqj3/NmdPFYA6FWa7wZHcsGNsjt9 NvZupWjgzPypE4Tsdfa41i2+682u7TnLNhsIEWEHmxsoelB9nwgo0f4MfY+WnOXU3aB2yL9rrhc uEs7OzXPcme9U+NdAdTwl+bXrwRypGXdJJKYAIZhI9QCOW/GOdJHZGcFM/lLJnH4OZyLY1d7wnz /q3puwCFk4MWtibfltmPMPu9pio/gcz8bLpcKip5iu3AaYl2rJ65IkBpL4cd1XQZsRfYGpm1tVd P3FkzRJdjh8lxa+wuVPLq/+B/lLTMXNfvlSgdpgevMJiruarks9wdCXAOfN+LMZgnvc3hd42TUS HIBHr2YRr4Aw6EyAwcFoy29NDR5ZCGI7tEgoXPfWnDe11cqDe/l0XPIX9zPQI4DOnM7z7zidl3v KRfzfSAV8UKupO6ZFd+67cTvoc2heiuTHOfea/JNHgoqS+LYQr3MQAH8GcZ87thVQPdaljXNX28 FELoAJOfwdNFkKA== 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 --- 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 a9edd60fbbf77..48fd8d3c50b0c 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 Thu Sep 26 23:37:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 831006 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 C3A461B07B2 for ; Thu, 26 Sep 2024 23:37:50 +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=1727393875; cv=none; b=LP0tvp2l8bjIopz8rBNtsk6ZI9SLkP9iYboQrwFl0oItx5FkmlkzxdNEOWs3ADb87En8J8IE4/s7+te/COhkelyYfui3bXITReUTqh8TkT1Yo6//FrLvdZR1QuXsmfscejc6YCCFUAlsAukREKZfcpeoTxnuquOhPd6Ia9IT1AM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727393875; c=relaxed/simple; bh=TQh5etl5nIijawyn7zhFuQ1u9gYq3NJFYxbxyXSOgDQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KU9HHjQo+VgOyygk8SSC7tDYSpbvBHFTy8k4v/ZBpJakLK/KxTpfTr/ZeIxTOZgqRudQAatS9CL2A+52dmaS/Tq8KaBQv26zeszEdVuWJi04GBO9oSzk+Nnw70fEthcGCvEdZ6hqXs4ousCkg1qVBpuE1V3WYI1MPWxIr4jFmtQ= 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 1sty3N-0007WK-0F; Fri, 27 Sep 2024 01:37:45 +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 1sty3M-001nOT-Dx; Fri, 27 Sep 2024 01:37:44 +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 1sty3L-005IAz-2t; Fri, 27 Sep 2024 01:37:44 +0200 From: Michael Grzeschik Date: Fri, 27 Sep 2024 01:37:41 +0200 Subject: [PATCH v5 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-v5-2-2de78794365c@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@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, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4015; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=TQh5etl5nIijawyn7zhFuQ1u9gYq3NJFYxbxyXSOgDQ=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBm9fBF//QA6EV7T8iUSotsdn91e8fIxWUibO7lj 1soIvjgwDKJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZvXwRQAKCRC/aVhE+XH0 qxkZD/wLxyxVSrFO3Wslyn000Cra4ZoFDxksNZVrd3l0Tr72bg4FWjk49o9vhnADGcJZs1nqv5Y L8iZi6dXHh2c7u2FPvRmYgpNAHGePxwYGYueIBgDHgGHxz0kdTHAdCmGfTVm+eKzfLLsaZfvwrE OieSB4lFNFjTWTE8YZDn+VviS7w6M20tEpSbmKfS47WkHB5+QUJPu5K7Py7YNiP23SiOVbUTqwL 1QXBKAoCohv0PDAk3TMafiN3Avz+4Vh87Y5vcgNxQjTLRh7fFPNOLyj5apkf4bcMXBUR6yHkjIO RqQMCv7eCQZ6//65GtMwAYCJp160vp0wR1DAuGVpmIJBhPeQ4hktEKOVWmgbsVgA68ZXWoHy+7l YS0MmZ+6W/Y48OlAROWgKCYItVWzLH5hsyOJCF+fgBnrfRol4h46L7DINSttN0Olito6jCiYcEm FuIWwyHg6fm1W+qqn2lUgoNoH32RfBnMNYGkRDSCjurCQdgvUUf6EERfBi7mvbFDWB/NqYMvq7U /Ns3oDSlHxUITddAVWIUqwMVjOlL07fuUIbNEhwRV5f1MUM69QBHBBzLPZrp4/sX3V4jjQDTPVk vH8X2Mu2H46hT+3r8PJVPHEUS6N4YurbUWvTATpFsYrnk/j2a95SNQzAF9a0WFjhPqMXESYUd5B vbG1f94I2o+Ka2w== 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 --- 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 48fd8d3c50b0c..eb82aaed6ba13 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 Thu Sep 26 23:37:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 831007 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 C5C401B07B4 for ; Thu, 26 Sep 2024 23:37:50 +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=1727393874; cv=none; b=HB9mZdMGcnU1zwtliOrO7uRBR2Ox9CegahEiT1RWIdBBwGDCWLknAqRuzSAl5MVuGMkTpj4+iVzUnsueV/JMt/j4XhNUwJbID0vJfUzTMFLmVU1kR7LQL7FVmVyFxy5UdiYGJAxckCbyieUdET9Kf4OaVHu1pxe3HYqOvgLX5LE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727393874; c=relaxed/simple; bh=ZTQKP2sfNERxtywaJwln4crmv8LFrsjEw5HBFI0JHIo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Idv84c8oyoDG2O4mxRIh0zvtDkf/NAineZ8LvWy2c6Gkd4dn0JOtpDxGSeKSUD+Bikv67rj1dL7gjx71sxnZ/GL4KhKI++fkeXuRFzNAyz13ydMzS4XRDWZEn+s2F2V0rcWSGYIWKROznEhTVWaWjpmu3VXl4+4XgaFDnRD/BQY= 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 1sty3M-0007WI-WA; Fri, 27 Sep 2024 01:37:45 +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 1sty3M-001nOU-DG; Fri, 27 Sep 2024 01:37:44 +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 1sty3L-005IAz-2u; Fri, 27 Sep 2024 01:37:44 +0200 From: Michael Grzeschik Date: Fri, 27 Sep 2024 01:37:42 +0200 Subject: [PATCH v5 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-v5-3-2de78794365c@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@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, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=10779; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=ZTQKP2sfNERxtywaJwln4crmv8LFrsjEw5HBFI0JHIo=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBm9fBF9IhRjLIY7xx4jkk1FoAJDzcGWB2l/tX0T 6oXtl8SKl+JAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZvXwRQAKCRC/aVhE+XH0 qypLD/9bxIHxCfFccJ1FdGhecmmGATd3I59P2MhWA/HieP7qFbEz0fr7nQMq3/L9u94YUhwltX7 8cPG2vlGfHADpnksyl4h0WQ8+/YJ3UxNu4iJnuj/S9HGTNbQNO9AzFSr6KoYnywXKFuGTwKW/5r f650RBfvRXxbvHwltC7ZNuH78jO6+qK4Lu+qnXxotNDHTw/qVSRS84MLSb9bFgjy+9SQPd/iJIz ipTflvCT/byDCJ+N0+1/oX9oZ7fIh/OQrMSuSV3YOudKTDz2FO8ymi49P5mC4uVARzGjm6j+9ue rJzWt7bMTf8+t5D3rpx3E/6i+6JFq/aDtOyojlR+HmqB+u8pwLRzbwGpyydms08u3F/rwjPyFmL MZvqaG2gPjw729mkZEnKbaLrQeY5jio+DTFrNQzpnWLGOfUBImYTcGO+UWvoCW65FP2J/is7OV+ FOWdawNIlR/oEwpf11babrxBIHpJXjY3ZW/jDKfcmSjbi4C/eK5u6XjiteVTHiFPr1CHrc9YcS8 UPnRjyt6Dfd9/FNOHJyL1Pp9FY+NBALVyvgrRS4DbVsxZSKmChlTarDWQVdK7rmtxe5YTKziumj 9OxtkSI8ESBnlTRJpl7AQhENLE3lkOalcRU8SlnC+cj4V6Cdwa51nkPvgRH4S/LwFl1A7hbbtUb jEkHuZn3d7F0KYw== 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 --- 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 eb82aaed6ba13..f43bf19218963 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 Thu Sep 26 23:37:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 831158 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 C6C0A1B07B7 for ; Thu, 26 Sep 2024 23:37:50 +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=1727393873; cv=none; b=lvIhOWNWDf0CxIY45xDtjLo1+/O/cqTGzHPnHbSBx3pfYEG86kmdeoCem2wfREhO68J0ud7X3XzAqqVE9E/SKIBZzgKXdWqrFOmCSb18fQ+f5zcQhgnYwlwTy4pZiqlAeIMsJz11Ah8pWkUvfGjPBZDAy0OX2dp4pBKGuQYwxAk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727393873; c=relaxed/simple; bh=OotUQNt61dUhnjWyZkFcz575ktiMrhwQHmq4WSJYwik=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=k5Zd00/LcAt6vvjGeASift0wvJNHmj9sSLYRQbmYtybWwLG6JK4wQO9jgmaGFW9FLp1Bm70VRE7k/M3Dhf5oOT+LTzSE2FhXazI8k1vt+kKPO4//mbNEZSv+mX1uO0UbGhvuVQJ8dGL137HbmPOZmiv4m6b14dxITLCKWSda6LQ= 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 1sty3M-0007WL-WB; Fri, 27 Sep 2024 01:37:45 +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 1sty3M-001nOV-EF; Fri, 27 Sep 2024 01:37:44 +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 1sty3L-005IAz-2v; Fri, 27 Sep 2024 01:37:44 +0200 From: Michael Grzeschik Date: Fri, 27 Sep 2024 01:37:43 +0200 Subject: [PATCH v5 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-v5-4-2de78794365c@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@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, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4046; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=OotUQNt61dUhnjWyZkFcz575ktiMrhwQHmq4WSJYwik=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBm9fBF5sLFiUig04zxmxDqsZpgmFxx3UaagU91L cMka02T8i6JAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZvXwRQAKCRC/aVhE+XH0 qxpgEACFupnEpDtrjVG+Ks0+5kJPrTbpf68trEWWVS3PVmxQJ23fHUgUHq9mdnbXNqlI6IxRd48 +J4p3Coh5Sv1cZazyw52RV+aeEHOu2PjR2OCWpdH0BJZwBvM8RhB2a3Ysubzquo+CJR8enQ5yt/ LIZO3BlKJpvJ5yXUkQ7m2ORVQTCExHheTFbJ5J7/fsxo01RqkH9APrTlR18m4M/9fTGKo6ek7G+ QLxXucSBD0k83dvedu94akU9FOcmCT2p4DjVTl5yRuDI77i2RhPueTfDcl1k0nsSOiOKqvu+cgJ SbKGIoqo7ePQDBMt7nMP5E0j1MvskZXbD/GjhsnfjL891QQmLvs+cr2lOIAYa14YSEffni5WChB dOP1kjaSxoFU1ENlnGUcXEOK+l1bHSWk8oa3EwrrK6m0qXjukhcurM/06RzaXM8/B/XHU/XHols Zp40BDGozg/mNriCDuHUhaywNPaoCrN2Zyw26spoa8yrtj2HjH0v6tVP1f0+HYTKPRDyYUgP+st iKCla3wtlZJbokfMx9ZwEvGatRcBLIbL5Jn5KMKqV/96WCP8dM5T0Uje+ixaHw3BayVBxLu8Oym 24tK+TZf63VxpqksuzhztytIPCePqXYczBjmPimC2NC9/H4PunK+VU6+HBmYPsWDgLkcaepeOD4 ayDQ9pa331yEmxw== 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 --- 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 f43bf19218963..19ba18d5a42fb 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 Thu Sep 26 23:37:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 831159 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 47D311AFB28 for ; Thu, 26 Sep 2024 23:37:49 +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=1727393873; cv=none; b=DPc9+5MveEIniqjeDKhuXjFEt2GHqAMCz4TYbKfzqXxvV2khXQ9tRf9p392pOtuzN57bYmyQVu2IMs0O0EP45msS6qnMVtUnazvTAS9X8WI9PJOQHD2rgL9NjMi5M7uGbyfsRjJTp4wU9ct8AS9vNfsHeXPfyXrgv3z7WKCD69Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727393873; c=relaxed/simple; bh=KCJzkVrbX4p9KesPyrZo5pncQyB+kG1CpQ7sBxu5iMs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eZGG++aGbEwz8P8upnpLM8aBz8FdUgReOkt/jeMVkePKZpqJKMfUZgOKSHg5Mj3ez2J/G335Fzb2TClV1S0t6otc0zAdxohwP7xGI6MnTrIKGKIEJh3fwPJbD/IaE8onj/p4ZTg73UOEYqWvx4VitvZu2Hsla2kzQYJLzP3tlnw= 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 1sty3N-0007WO-4J; Fri, 27 Sep 2024 01:37:45 +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 1sty3M-001nOW-EF; Fri, 27 Sep 2024 01:37:44 +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 1sty3L-005IAz-2w; Fri, 27 Sep 2024 01:37:44 +0200 From: Michael Grzeschik Date: Fri, 27 Sep 2024 01:37:44 +0200 Subject: [PATCH v5 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-v5-5-2de78794365c@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@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, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6408; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=KCJzkVrbX4p9KesPyrZo5pncQyB+kG1CpQ7sBxu5iMs=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBm9fBGFy4t+EJHFvImBrY+QlhgY+LhIhazRHzIz Npc8Dk9vVCJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZvXwRgAKCRC/aVhE+XH0 q7dOD/9yOmHDiZh+OFpzfvBlSwcjTvaeisRmpyMbTIkFJ9SYLzs7FRXNpO4g5ipcXxQKTtpZuui AeaUVptm8ckzAu11iZabQ8eTS0i6mpaX5yF38rmqoTJFpKtK8D03I/p0AYBs2cmyrUuZbGIORy3 lic4g4PWT0Q/xuvvd4URIcQ62tA95oQui7PLgN5M8q76oqC022z2JgMUaHtZLiFHqsVMZNSrg6o Jzprc5uVAf00FGCg1X5jplTqyrlUSDK4AOVDh3DUU5YERjoqPT3NECp66sncgC98SdoR1qbUAaT 6LHsJDahxRrEXUIE+gRtsBs3Kuihh8LwHnNd2QRAVCvdBBTOvWd4rE5UvTfoSzWINT45Tb5R58V E1RbNgQxqDvRcMqnCs6suz5FySjcbiRQj8B2XCdekHiKH8/OquY48EKn/4pTBfPMX5hceZBalsz 2UMwgudML9Q+SSxSzhu6VvHEgxjZoX0XWijF40pFdr4daRtmUHnC7zAE6v5DOs4znbA068UmkFV wjTuP+sE2eJ8OrbaB4ShzGXhFz8ui8KMloVSGQiBtemzSJaT/Jnf7oUT0CLZJa1ntRi5PRiKOME znNUmi4OkJv8PLiYsBmCCcAen+uAOl1b1Jp6XCw6D7xMSh8NvtB/N+AS06F9a9lo1aRxiC2WYQG U/Zm6uV/VTfD09Q== 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 --- 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 19ba18d5a42fb..4efd7585d7541 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 Thu Sep 26 23:37:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 831008 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 47DD21B011E for ; Thu, 26 Sep 2024 23:37:49 +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=1727393873; cv=none; b=nW6MWfXRjI7RrzTai1YEyRtO/mTqbT0lLVLPPWrMXUX1ossNcBzelZSgPpHk7X5LdVgMSYowKkVPKz2/4QrTEUeyrX7rmjlAMKHevlGo67V/j7CfOajHht92DYnfGiCIcF2NhAOArxlYSaIT55wU8Tz68r3XbFAGSOp6wJvLRMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727393873; c=relaxed/simple; bh=vHXFLUU+y+3pf2Umb7EfHapkoh6hw41as8tjpDPtTzo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N/854xt3nyNShmClmhRHdDGa8AWN+lSwg9QluqvTXFuYNDZ0pWI9NmmdQyhcpUcCF9oil/zVZJ4Ed3CeCimak8yogcfzArJJ6/HaGr7CYUNXOiqXILjsn9yfZ4lqIHbxV45YSeymmmAR4nxd21lNGRFKoJ2ngTlTFn28M0nbXmw= 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 1sty3N-0007WM-22; Fri, 27 Sep 2024 01:37:45 +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 1sty3M-001nOX-EO; Fri, 27 Sep 2024 01:37:44 +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 1sty3L-005IAz-2x; Fri, 27 Sep 2024 01:37:44 +0200 From: Michael Grzeschik Date: Fri, 27 Sep 2024 01:37:45 +0200 Subject: [PATCH v5 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-v5-6-2de78794365c@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@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, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5686; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=vHXFLUU+y+3pf2Umb7EfHapkoh6hw41as8tjpDPtTzo=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBm9fBGQBBFyvRTvKNrvCOoDUXWMvep5pk+Z4w+8 ME81qpJCfCJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZvXwRgAKCRC/aVhE+XH0 q/VhD/4tL8V5YkIrBDhVu2qE6dSzbTlzEPno9s0XHc0kchi04Fbhcf7P4Q2m1YYhTlTXAJkH21W Mqq7F0rGF4YbBZr1nPx1/T0PapJN40KJzpe8naQm2XqovpFr3Tm8+R/gVNi4fccCzw8Pv7dTqs0 CWXQ+K/bMO8h24qEFzzYDCmvEIl2nz6fy2bZyL2rx4AJ10x+QL87dtoDpxEI3sb4p+qfj5YOUT+ OUuSU7lhGMc7LGykCQbxDpMMJseNdl7QHCQe/n28Lr1J+TIbAe1b8ogRR4v9BFby/cWwMLml4OF DA5kfMU4nGJslZcmkYUvAzG8jjCqkM5Zsi/oNPMjCyqUK6qmMDqXONfrTpmhzrU/9x5Lg7jNoJj Pf/LFs2WkiitDrNK2eVA5Suz1weby7V57z6y68jwot3zlF4gx56mJlL1YqLbUoOB+osCd/LATHG xrPhURsAl0kp/vOGSHdpMeO496/4riB8nV3Fb1TpCVj9xvNPiTfhWCBEO78UWfNMzu8SDTwt80G +JunkmqYQW0vHDdT2R9ZCQaBwTUZmJTr1FFPbXfynYdlcyIxzKE1oG30pQ9JgrN9d26+5dpqJ0N 9p1RoIuA+bW7Vf4IW8SCoL91EYr0QSQeqD+k14kK49xDJU9pEs0WCrRXaFz5ZDrqObaEXT0idER wpNPi87FmXUXmDA== 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 --- 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 4efd7585d7541..0287a56fa50ad 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 Thu Sep 26 23:37:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 831005 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 E04161B1422 for ; Thu, 26 Sep 2024 23:37:53 +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=1727393875; cv=none; b=uGLqGJpHg9+K4c3+e73sKP3KHSEF7CF7Gzbk3AuiALotmfarxleKYNaPhYRYdXHhjlhds1Ne71HtC86zJUGKMmO4kIxYmJBDPXjBU7ER7pVORW0N3JqEWpmgIgEU5uqFMXAalxSO5lDViHeYLY6Y2gizFlcT8G4YOhkvVXGEsOU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727393875; c=relaxed/simple; bh=2E2DSWp9jRss1gsarQGHeBIDtJR9gvC7i2e631GtL6Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Q6w9iMEaLt12ytYx7NiaWSo2Vdxq5UGwZrHJpxgYlzggpE3vOdLsIKwZ5Uznu5DbZPvVP8x9aJDwRwfOOFKD5hK7KxTZJJKvYXdQjtvnnybFqRtaZ/zNBBMWeiIdU0ilreor5Y5PeaJr/7VFr/8tWd4A0cZDwoJC3gv93dpWLwo= 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 1sty3N-0007WP-11; Fri, 27 Sep 2024 01:37:45 +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 1sty3M-001nOY-F4; Fri, 27 Sep 2024 01:37:44 +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 1sty3L-005IAz-2y; Fri, 27 Sep 2024 01:37:44 +0200 From: Michael Grzeschik Date: Fri, 27 Sep 2024 01:37:46 +0200 Subject: [PATCH v5 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-v5-7-2de78794365c@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@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, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1915; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=2E2DSWp9jRss1gsarQGHeBIDtJR9gvC7i2e631GtL6Q=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBm9fBHF8gn+ePJeCHwBKrCx9BRxUYzpsPLP+3Qq MsNPy87EPiJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZvXwRwAKCRC/aVhE+XH0 q4F3EACTWbE6uCHYvTtugu0tSUHlHc70kSp7Ksb2maUjGsAQ+qTiZlRAw6Gqu0lRgTWXkhQmAp4 enPlpb37TsOhi1be2mDfHUw6nodNxw4s086d/+BcKh0iwSVO2S+0MDFGCfDTvBvVQfm0V5eyUjx hBXUdERvFptQKo3Q1psCuQ6EIWa4KwW/BKkv6HxSJdI5h2BTA+gXpC8atvzug8L85yw6lesE8kz n7cqQAq07Xay74Wuaixj+BJ9wWWqtNvIwx7o4al6NeM3WLWBJ06FdDW7VKcfdwYzkgOx/DIxbhV 8SRYJNaFH/fQE5aBEUH4LvrSBj09kN+t38zu4sWKc9ktlD6kyswsTfopYU83BXvuPKcAewAUSHJ xNbQCeIsvoBhPO1G3tRkQ6WJgiIif8l1E+Xvh9ixF4OWSr9T+aCEDUzMkFBPvecswXwX0Rp4sLZ TdpfEpT2ymYe3U1MEt+fFCnxVGiytM/LRYrkLfD80LZEdZJT1LiBqjpI+SXt1W+H+bIpYRyEkmJ IiZ72RNFwszmDcakZq/MBNo2UBqORK4DT7kPdJtr2PXR717jpdtgQfY0T9tFFspDc78g8XQdGN/ CRR5EAZdwxRKg14MuTP6Mhk4hIx979sBef0rqb1lD3QuQO0RLvrrWarVc9wmgDOZ5/VLA+qxs04 E4SD6zC7sKxXL7A== 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 --- 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 Thu Sep 26 23:37:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 831157 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 C860D1B07B9 for ; Thu, 26 Sep 2024 23:37:50 +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=1727393874; cv=none; b=Fz61ryfJumx2heD9Yzep4kGuQMrIMT1alX1gqtvsylhaOlGW2qQIHRCXJHOQCLm6iN4mf92fKyn26Np7K1sThsKMWpJcRJEOu9Q1FpN5EJo1LW3UwBRQLm8XPpqdxYWKR1uRCvMRD4ZrBy3dINhCfIEL6Y+Xk3x7nQD5+1ZVh20= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727393874; c=relaxed/simple; bh=VlRem29ucC+ZWWE+AHehS7FAtKKyvZ57k+KTI5b6wDg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nz2hqB1gHc7j9JkB0+mrq/DJ6xUgQt43T57Zq/rS4EhJpxNXe7ISBso2AEnXfrqGiUv+bgsencnOUPYzxwtG3keHF7d86ujc5xgm1wEhbfch2TQseJ7JhkQfXzgv1judcjp0yhLnfM4zBw+9m6l+WVRxiUSm/ak7QsL3ubTNJ40= 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 1sty3N-0007WQ-5C; Fri, 27 Sep 2024 01:37:45 +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 1sty3M-001nOZ-F4; Fri, 27 Sep 2024 01:37:44 +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 1sty3L-005IAz-2z; Fri, 27 Sep 2024 01:37:44 +0200 From: Michael Grzeschik Date: Fri, 27 Sep 2024 01:37:47 +0200 Subject: [PATCH v5 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-v5-8-2de78794365c@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@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, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4417; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=VlRem29ucC+ZWWE+AHehS7FAtKKyvZ57k+KTI5b6wDg=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBm9fBHDQXHElrvv/5Z4Ckfoxzv2S0Lc53+rO3on m9GF92+S6uJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZvXwRwAKCRC/aVhE+XH0 q8MUD/0aO99vLHJlXPsRlCXFwFFg9kge+w17rxzW8sCT8p61UaQTccYRVEA3MGJjEA33ywaFXiQ zT2t0DstAVsCeEoxXRmzolHOXjaPdU8UbvqGT50RxwPo5Ymuskj3tyFo5THB6CLZD6oE7K7AG1a 4+jbQOuhXXjWUdOFm4CCZy4eb0Pxw6onDFwI/25V2RAaE5Wf2bQ15kKysyLIcgRQB3bIs9sxy2Q oFi3YVqmoSFqJLxxUmiOMecw6CF6bC6DoyYE8av4UUfHP6PuWc5wQfCUc9eu+2PbWyVocS+qQyz Vo10W1JD8zxRjxosRTGVvv0FbkQaALqr1wBHuIaBZkB36iF/fIwObYGLFnj8HkirVxXMCXKeByV 7fMioJGaSuYCtzdcWAEbspkxGWjH5SSQB52Hdu1LIqp6VbXbOmAnLtsxmjmCUCfJ3ucEbYwpaBB hwPVKbVKKlgbzCAdApygS+QMWal0HpeKX7To4B0weL6EmqU7+ZsdJFVYLpiGwCE371epTn9OiU8 GVQ7TB/L135nVzunOHZvbeXrCscUZEeZyteMWOBZIIthDNBKKE6CjTQGpYYfM6QXwIrA5neer/C RkX3N68LRsaUfM2VXVoDdoGxgGUvnyMyIRepBilFxSobTJYo33jessTbnhIdRIMX0SSNv4DbTNS 47r2PFsBHfHApJQ== 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 --- v1 -> v5: - new patch --- drivers/usb/gadget/function/Makefile | 5 +++ 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, 81 insertions(+) diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index 87917a7d4a9be..99b2bab4cc32f 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -42,6 +42,11 @@ 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 obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o +ifeq ($(CONFIG_USB_F_UVC),y) + ifneq ($(CONFIG_TRACING),) + obj-$(CONFIG_USB_F_UVC) += uvc_trace.o + endif +endif usb_f_midi-y := f_midi.o obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o usb_f_midi2-y := f_midi2.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..43b9544d56550 --- /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 0287a56fa50ad..115524b79ebd7 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 Thu Sep 26 23:37:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 831160 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 B88991B07A6 for ; Thu, 26 Sep 2024 23:37:49 +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=1727393872; cv=none; b=WfMwDxbUoIECtDbv3YsuKUivebedCTmvTomjFZ8qaHysF0Hf1NGDNAE8x/Aq0/K4oBcJ8AFxrzQPsaYpoLI3Y4vSZW0LUtprQ/okt5f7PEhvUTIwnlppeKYKL++T/D395GNYKgg0uEQqp2mEThoPhCJ/BOmMqYkeWmH6gbGf6u8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727393872; c=relaxed/simple; bh=ZC7vhKknmIv2ZJpX7IaaS5kqxmYqf1oRBfTMnf5v6m0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=j1ubHUju2q4KWMLFFEMxURonLtMESaVAqMXKAiX6sZHLXvYhPRR4VF53MwkCLBMpjSkH6ifwyIwOygc45XwxmkN3zGZ1WYu3qedAm+YgWfTo1wzuDv9Ew6iLLRsiUMKJ4Ax4aIWZ/G2PV9bykCqU5HYIF7eZ463ZqP9e0xQpCSo= 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 1sty3N-0007WN-5q; Fri, 27 Sep 2024 01:37:45 +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 1sty3M-001nOa-Ec; Fri, 27 Sep 2024 01:37:44 +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 1sty3L-005IAz-30; Fri, 27 Sep 2024 01:37:44 +0200 From: Michael Grzeschik Date: Fri, 27 Sep 2024 01:37:48 +0200 Subject: [PATCH v5 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-v5-9-2de78794365c@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v5-0-2de78794365c@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, Michael Grzeschik X-Mailer: b4 0.12.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1103; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=ZC7vhKknmIv2ZJpX7IaaS5kqxmYqf1oRBfTMnf5v6m0=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBm9fBHaxZ6s0DMLzvJkk19xjWII0MPbZ0SlIxKq vNDrRVcwLuJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZvXwRwAKCRC/aVhE+XH0 q5FaD/9ghIhrqeWPp637SzW/2Q4M+yfgvTtyuejRgbG4WJBtRw8e+KtBTtUu4v7ZI0oRuNIYsLE OoxjXeAwfRaEkhhMAkU3rS+dRb1NunFeekzU69ghb32iRdpvrEOiu8TrIeDROoEVf7cK7jCMVHE wUamCzEc7syyz/rutIrnANuAhNdYX7a2AZ+yVW9e57Yor4voD4W+YNrEYLMYkwcgRsH6alcJPLo TO2L7tJySox+UcIhyDwHSEnBq+SPvjX22xUalUFBD7ZRCB1QGbh9y9Dbd26tVMzfKbzG6drvHHQ +vPLyAbV2uhi9c2dnjHRClXj6rs+/BgWu1x/EsZ6RhHp4bsZq836nHUuklDJQnHxyMdDXeJDjgv VZyL04aL6a00j4F7BmpywSNG/t1fcfSWCYSoqaqsyr/ojGwi89SEyiirr3eiODd8bljH1m54E2l piKbHAs+iisJXFKHkBEOGZltxT0TeJfYCdlnwrMRPz2xj2Dju3Yh6y4yIXzZ85aqfFzjFXg5LLH Px4t1aNTm/sV7qZ0450wqJpx82xJxG67V5qy3VyGGupjpXQVlYZY1x089TajMfRVNuqY0LPUqu0 OUUoMZbYpaf+oP51VKR91D+cSekDUJLxBrzEVIhU30vrX4VPYr04D2irsjW9ePLs9aZwRDCmqne BYk2kCQItpTG6BQ== 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 --- 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;