From patchwork Fri Jul 26 22:02:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 814869 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 7B766149E16 for ; Fri, 26 Jul 2024 22:02:54 +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=1722031378; cv=none; b=SCWCP5A4We77G5jxf070ed45OEyrwfNZZA+VsIpwqe7Qi8xN8fYylSKi3TGeEdVhZ3kKhoFJrc84/I7+u36itso9rUW1R9Alea1dPSacdR9KKypnVkAbtDJkCcIUCDi2ot+znrRNT/c5rX8AVlh6QsZQcgrDwyVhkdQ78RenBBc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722031378; c=relaxed/simple; bh=YF8dKVRyhizjPiHy0ih4AgDTr68Pw1ZAnLHDUu9ERrE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lUWucCLPwRJ14Oadmh6jQYGyrqHJ7m8IzKDeIXeU1VYmEllRxESmiMHiky0v3WtzBYQm18eZpXDncuKf5Fo2GdRJALKkfEeGlvtdMm/5sf0GxgFMiIk5gO4C03m+Dwh5+oW33837LIaQCwk5V3eg1WKQ0oQRQJZ+OCwQjtNuigY= 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 1sXT1Q-0005Ml-RH; Sat, 27 Jul 2024 00:02:44 +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 1sXT1P-002Qhs-T6; Sat, 27 Jul 2024 00:02:43 +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 1sXT1P-00FdLn-2a; Sat, 27 Jul 2024 00:02:43 +0200 From: Michael Grzeschik Date: Sat, 27 Jul 2024 00:02:36 +0200 Subject: [PATCH v3 01/10] usb: gadget: uvc: always set interrupt on zero length 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-v3-1-4da7033dd488@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh 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=979; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=YF8dKVRyhizjPiHy0ih4AgDTr68Pw1ZAnLHDUu9ERrE=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmpB0AGohv1n2w/AeHnH8jua9EG3TO0dshNYRLO enKfG3xjAaJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZqQdAAAKCRC/aVhE+XH0 q4RwEACeBnI5CnaavaX5aA7CBBlvvu/QMaK4B7JctaSfSr7Y0qT7z4CZ4PlxpnxjIENeVfIeeKo pKHl7TtkNzHwBWDtqWvWhv41L/nGI9dkIx+juIV3ej45jZ1Gt0aol7+nUfV0hRxyXVNRXad25mO hQqXmcKMNyp7000cQQRIjI/QHDAITkApWjQTY53R5YIx/5RIyI49w09kQmfWNPLbDbvzNMULUJA 7AbiKK8eYgloFJkPGdZPGR6FpdI7z/j4RwIgUOqFQvB13Le0V2VEVwN8PCohMxhUazh7qiI3eZe 1Q0YgGui5J2KDGO3DefBzVai400vVi8Ha1qWEt4AT3u15HDxQAKa08MhxetC94OnOZ6zTHwVWDF JZWtShfeROQ9OH/jrxSF6TibvSTRpijVYbJmX02pl4D55yU1MrNlafkgl1PR2u+9H9ocXsDsicU W7kz3YC+hzUaObV+AjHvrdY1zATS2O7/010kPsB47cThVnZdKfwSdkQ7u4fsnlRpDf6ngcjKzpE zb+hwK0rMJvEGhieK8lrjckxJ0HlX7PXMGobPmflDSW2w42Czvkd4gmXZOc+OM9oMKTGr/AsF8e LjMyjglbCWSnFPzD9oiyK47XSF4ABc5eT/sU1T2JseLHIcj5EUzFkUDaWRfasEbQQ7s1gbYYDj4 GCSrCNWXZz62bfQ== 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 uvc gadget is depending on the completion handler to properly enqueue new data, we have to ensure that the requeue mechanism is always working. To be safe we always create an interrupt on zero length requests. Signed-off-by: Michael Grzeschik --- v1 -> v3: new patch --- drivers/usb/gadget/function/uvc_video.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index d41f5f31dadd5..03bff39cd4902 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -303,6 +303,7 @@ static int uvcg_video_usb_req_queue(struct uvc_video *video, * between latency and interrupt load. */ if (list_empty(&video->req_free) || ureq->last_buf || + !req->length || !(video->req_int_count % DIV_ROUND_UP(video->uvc_num_requests, 4))) { video->req_int_count = 0; From patchwork Fri Jul 26 22:02:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 814754 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 7B67D2E651 for ; Fri, 26 Jul 2024 22:02:54 +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=1722031380; cv=none; b=pfTqys9UTaaPAlRNi8rIW04JmMYE3WhNVF+qsnrYvgjjG8ZKaU+g2fZj8vdZwQrJ5AySGqNzR7MRyaNwlCSw4ud4qTVpO8C8uh7mNbBpijugSYKaB6bUeanVkyyY7GhnXiGPQxDACi/3rvwYu5/Qz1IlXgtTK4lR2xoqBRMB1Gk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722031380; c=relaxed/simple; bh=d4N276jXUhvGBMnQmpZPQHqjqQDtlScV/gbDx0G4ZNQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GN9fQflQx9Z4U1KnihjViH/gUALRG/F0REeSWwerzkJHIqmziH6ORxjtHfJBxNE2RQv5vEeACDa/jSBl0ia+h3qp26LD/fNHqd6sZ2MePNj00cS+TP6ScobOFSuJK5iPx6EYk8IAlGefkp8lhYJiKFKrXbJkwLiUm85Vr/XqgqY= 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 1sXT1Q-0005Mr-RF; Sat, 27 Jul 2024 00:02:44 +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 1sXT1P-002Qhu-VC; Sat, 27 Jul 2024 00:02: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 1sXT1P-00FdLn-2b; Sat, 27 Jul 2024 00:02:43 +0200 From: Michael Grzeschik Date: Sat, 27 Jul 2024 00:02:37 +0200 Subject: [PATCH v3 02/10] 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-v3-2-4da7033dd488@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh 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=2515; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=d4N276jXUhvGBMnQmpZPQHqjqQDtlScV/gbDx0G4ZNQ=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmpB0AED6RR3mV9lMOYlW6C4+MWnuKt9uIgaT+i 5J8wuJ+baGJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZqQdAAAKCRC/aVhE+XH0 q2hsEAC5HHNw5d1IVUmCvkr40fyMJrnXSiEj+u9YwfbargZr+qXTJ2GqNU0WvXTeNS7ALV39sk2 oNw+aszjsEjO4RwOGvPWWRURFuckOGXHXsjptN3kVTS+Zx1SSsMAhLjZHAzPSInG7/PzOpJQ2iz 1/TdJUGUJASohlkpCeO44z3H2mx8owAFmXgDaWlOcg04vQAy/rKiG5ZHoQgkzjnL7/cVbIk9huZ Ue0L4O1/UCADhXnyMlpgeZryRmNhu49o6HslC0semBWiMCIMpVMW2rwCUkEJ7Nff+xH3PT6QZdC 37QA4lN7qVT0o7m6lfIpnQQQg+DfF/XtFFF5uuPiTJI/fvbF119D0cztc162zbzTtCsXrJ57OZE rhnBLKLyeF4C8RXEq4YFAEwAz4000TWhMxK0Tdab6UkhZpMk/IzmNppo1z4jiZmtdHGIzN/zWEl 7op3mm9tjdeEAqXmU59KyEPDzPSEqaadgJTXQWam33KEQCa1oq4M/CiWnbGqp7MGm1mE1HkaLL0 Yu37iXQ9G+l7Pg4SBSck0VJIeHlQMjQv7wodAH+qY8Nk6JoqqluusXld1BZ/4CqLaWxSrDtCe04 Cm77ZrR6uw4If4mQ49eAjA1qBu5W2NR+PZJ+Wpt9q1POR8OxOAMx0g7sCC7s9nbwrbQ2W1BVMzL NCO8au3gOjjgd3g== 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. Signed-off-by: Michael Grzeschik --- v1 -> v3: new patch --- drivers/usb/gadget/function/uvc.h | 5 ++++- drivers/usb/gadget/function/uvc_video.c | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index cb35687b11e7e..646f1c01c5101 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -91,6 +91,9 @@ struct uvc_video { struct work_struct pump; struct workqueue_struct *async_wq; + int enqueued; + int dequeued; + /* Frame parameters */ u8 bpp; u32 fcc; @@ -106,7 +109,7 @@ struct uvc_video { unsigned int req_size; struct list_head ureqs; /* all uvc_requests allocated by uvc_video */ - /* USB requests that the video pump thread can encode into */ + /* USB requests that the video qbuf thread can encode into */ struct list_head req_free; /* diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 03bff39cd4902..d47ddd674f457 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) } } + video->enqueued++; + return ret; } @@ -380,6 +382,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) int ret = 0; spin_lock_irqsave(&video->req_lock, flags); + video->dequeued++; if (!video->is_enabled) { /* * When is_enabled is false, uvcg_video_disable() ensures @@ -467,6 +470,10 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) * happen. */ queue_work(video->async_wq, &video->pump); + } else if ((video->enqueued - video->dequeued) > 32) { + spin_unlock_irqrestore(&video->req_lock, flags); + + return; } /* * Queue to the endpoint. The actual queueing to ep will From patchwork Fri Jul 26 22:02:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 814870 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 7B61D11C83 for ; Fri, 26 Jul 2024 22:02:54 +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=1722031378; cv=none; b=F4ZS+SF3MUvSfAxczbz+wYncg5ZLWtMAzTOefWbttMEfpiCqQIItSvJV4uwqW3dFT2mDfTzxKeFh/0cj5LLWdnOEcpC+FXJ1Cp5TYhRPf5csNGROJRr6pAdrMGFmG8MFP1/L6Y8MxsaGst8I5Isf3GkIQW2c/fv2DnIzApxDqt8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722031378; c=relaxed/simple; bh=dmQtnKe9M2OyHgVT0re5e/U932TrRaxPMLI2yUcJMlo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NJW/BpbNYUgBoAI5+6lHrOkzw2tpurYaOTq43l06XqZ1u+2ha8ShGat4rMCiwDrO+NxFqV51W8zAur30hO1NpYBJG9myb3rqri3kQobxuMe7ao9X6WHMy7O4BGqIXaI+ubdiiKG8PPt7Tw0YpT0mH6gxxhepzX/K+P0XZFy1rU8= 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 1sXT1Q-0005Mp-RG; Sat, 27 Jul 2024 00:02:44 +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 1sXT1P-002Qhv-Uw; Sat, 27 Jul 2024 00:02:43 +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 1sXT1P-00FdLn-2c; Sat, 27 Jul 2024 00:02:43 +0200 From: Michael Grzeschik Date: Sat, 27 Jul 2024 00:02:38 +0200 Subject: [PATCH v3 03/10] usb: gadget: uvc: remove pump worker and enqueue all buffers per frame in qbuf 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-v3-3-4da7033dd488@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh 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=8313; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=dmQtnKe9M2OyHgVT0re5e/U932TrRaxPMLI2yUcJMlo=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmpB0AsN7E/PUPh/qdKSfeQ11vIpC1uvl4jok/E tIDMzFPiwCJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZqQdAAAKCRC/aVhE+XH0 qyioD/9V2Jc2nIy3T0Jsk4pwuje5egVTo945U7NZa/o66LaGzk2FYzDYwhCYiu8G8Wc/Tzc4xki /WwwOnrZD2nNI3yrw+9l0++wO9sWy3T1wD0hBGXzVMGqJhec7UvmygxtDQvwv0WHBgDql1eMnLT fiAzaFUr59mMmt7eqKgMhNKDle6zidVinIu3Ndq93hUPBuIKBuVMKKDR0+Ut4u9O4/reEarlENN L31tPfe4hwDZHgQQkE5K419NH6ybp6D/CpX0lGj4Z3Aw3c4Rjk1C7uBlSCzXXRlZedYjJ8h0ZyE GatLe8GuBdb97oNM7a8fhhVA7MTaf9MMkwCetpWEZoN+G2MzXh6Q31y3rSEhzD11bxBsdNt9+eB RmUYJ7GIbJozPxLMBMCBfzbwlb+VgAukKDbYD57pM3m1xSd5Zto+nDFnA8YEU7uQR14sNq5XHYg EsERxJJF4bZB92u7OGMmCAeG2ebjPhP7LcLpzhnxSHLo6htva60udVlyZLHTj/Z16Lbm1G+fPvl iwLVB6X32jaC5G+QmYMS98Tcn5t4jrCC+t0bA++3d7am9zsjarZK0aSAbX5wSutuXA0bchnA75X f4BVOu9qPjKQsyIM5LwwDkxqCoy+c9fsPqTUSPBFvR3U0X0OK491bjLw+C+Xv7RvWzi6tBguTXH ULPI4HbolLP765A== 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 we now have at least the amount of requests to fill every frame into the isoc queue that is requested with the REQBUFS ioctl, we can directly encode all incoming frames into the available requests. Signed-off-by: Michael Grzeschik --- v1 -> v3: new patch --- drivers/usb/gadget/function/f_uvc.c | 4 --- drivers/usb/gadget/function/uvc.h | 5 +--- drivers/usb/gadget/function/uvc_queue.c | 3 +++ drivers/usb/gadget/function/uvc_v4l2.c | 3 --- drivers/usb/gadget/function/uvc_video.c | 46 +++++---------------------------- drivers/usb/gadget/function/uvc_video.h | 1 + 6 files changed, 12 insertions(+), 50 deletions(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 40187b7112e79..aeaf355a86eb3 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -986,14 +986,10 @@ static void uvc_function_unbind(struct usb_configuration *c, { struct usb_composite_dev *cdev = c->cdev; struct uvc_device *uvc = to_uvc(f); - struct uvc_video *video = &uvc->video; long wait_ret = 1; uvcg_info(f, "%s()\n", __func__); - if (video->async_wq) - destroy_workqueue(video->async_wq); - /* * If we know we're connected via v4l2, then there should be a cleanup * of the device from userspace either via UVC_EVENT_DISCONNECT or diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 646f1c01c5101..e252c3db73072 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -88,9 +88,6 @@ struct uvc_video { struct uvc_device *uvc; struct usb_ep *ep; - struct work_struct pump; - struct workqueue_struct *async_wq; - int enqueued; int dequeued; @@ -113,7 +110,7 @@ struct uvc_video { struct list_head req_free; /* - * USB requests video pump thread has already encoded into. These are + * USB requests video qbuf thread has already encoded into. These are * ready to be queued to the endpoint. */ struct list_head req_ready; diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index 0aa3d7e1f3cc3..7995dd3fef184 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -102,6 +102,7 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb) static void uvc_buffer_queue(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); unsigned long flags; @@ -120,6 +121,8 @@ static void uvc_buffer_queue(struct vb2_buffer *vb) } spin_unlock_irqrestore(&queue->irqlock, flags); + + uvc_enqueue_buffer(video, buf); } static const struct vb2_ops uvc_queue_qops = { diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index a024aecb76dc3..4085f459c3c70 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -429,9 +429,6 @@ uvc_v4l2_qbuf(struct file *file, void *fh, struct v4l2_buffer *b) if (ret < 0) return ret; - if (uvc->state == UVC_STATE_STREAMING) - queue_work(video->async_wq, &video->pump); - return ret; } diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index d47ddd674f457..0bd49d4e106b1 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -445,7 +445,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) /* * 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. + * usb_request to the req_free list - for qbuf 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 @@ -469,7 +469,6 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) * dequeue -> queue -> dequeue flow of uvc buffers will not * happen. */ - queue_work(video->async_wq, &video->pump); } else if ((video->enqueued - video->dequeued) > 32) { spin_unlock_irqrestore(&video->req_lock, flags); @@ -566,27 +565,15 @@ uvc_video_alloc_requests(struct uvc_video *video) * Video streaming */ -/* - * uvcg_video_pump - Pump video data into the USB requests - * - * This function fills the available USB requests (listed in req_free) with - * video data from the queued buffers. - */ -static void uvcg_video_pump(struct work_struct *work) +int uvc_enqueue_buffer(struct uvc_video *video, struct uvc_buffer *buf) { - struct uvc_video *video = container_of(work, struct uvc_video, pump); struct uvc_video_queue *queue = &video->queue; - /* video->max_payload_size is only set when using bulk transfer */ - bool is_bulk = video->max_payload_size; struct usb_request *req = NULL; - struct uvc_buffer *buf; + bool is_bulk = video->max_payload_size; unsigned long flags; int ret = 0; - while (true) { - if (!video->ep->enabled) - return; - + while (buf->state != UVC_BUF_STATE_DONE) { /* * Check is_enabled and retrieve the first available USB * request, protected by the request lock. @@ -594,7 +581,7 @@ static void uvcg_video_pump(struct work_struct *work) spin_lock_irqsave(&video->req_lock, flags); if (!video->is_enabled || list_empty(&video->req_free)) { spin_unlock_irqrestore(&video->req_lock, flags); - return; + return -ENOENT; } req = list_first_entry(&video->req_free, struct usb_request, list); @@ -605,22 +592,8 @@ static void uvcg_video_pump(struct work_struct *work) * Retrieve the first available video buffer and fill the * request, protected by the video queue irqlock. */ - spin_lock_irqsave(&queue->irqlock, flags); - buf = uvcg_queue_head(queue); - if (!buf) { - /* - * Either the queue has been disconnected or no video buffer - * available for bulk transfer. Either way, stop processing - * further. - */ - spin_unlock_irqrestore(&queue->irqlock, flags); - break; - } - video->encode(req, video, buf); - spin_unlock_irqrestore(&queue->irqlock, flags); - spin_lock_irqsave(&video->req_lock, flags); /* For bulk end points we queue from the worker thread * since we would preferably not want to wait on requests @@ -642,6 +615,8 @@ static void uvcg_video_pump(struct work_struct *work) else uvc_video_free_request(req->context, video->ep); spin_unlock_irqrestore(&video->req_lock, flags); + + return 0; } /* @@ -681,7 +656,6 @@ uvcg_video_disable(struct uvc_video *video) } spin_unlock_irqrestore(&video->req_lock, flags); - cancel_work_sync(&video->pump); uvcg_queue_cancel(&video->queue, 0); spin_lock_irqsave(&video->req_lock, flags); @@ -775,12 +749,6 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc) INIT_LIST_HEAD(&video->req_free); INIT_LIST_HEAD(&video->req_ready); spin_lock_init(&video->req_lock); - INIT_WORK(&video->pump, uvcg_video_pump); - - /* Allocate a work queue for asynchronous video pump handler. */ - video->async_wq = alloc_workqueue("uvcgadget", WQ_UNBOUND | WQ_HIGHPRI, 0); - if (!video->async_wq) - return -EINVAL; video->uvc = uvc; video->fcc = V4L2_PIX_FMT_YUYV; diff --git a/drivers/usb/gadget/function/uvc_video.h b/drivers/usb/gadget/function/uvc_video.h index 8ef6259741f13..2f30ebd05fefb 100644 --- a/drivers/usb/gadget/function/uvc_video.h +++ b/drivers/usb/gadget/function/uvc_video.h @@ -17,6 +17,7 @@ struct uvc_video; int uvcg_video_enable(struct uvc_video *video); int uvcg_video_disable(struct uvc_video *video); +int uvc_enqueue_buffer(struct uvc_video *video, struct uvc_buffer *buf); int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc); #endif /* __UVC_VIDEO_H__ */ From patchwork Fri Jul 26 22:02:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 814868 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 7B6EF55894 for ; Fri, 26 Jul 2024 22:02:54 +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=1722031379; cv=none; b=BAoVXWsZSLAKarZf1PUZAboLBTqRVFMacaW+jVX3qd48GMzwChkjD0gip2xjG76bJLtupLv3cyhIsboWqD/1yG2lctY70/Y6Y6hBY9F49+Ve7ZPkAjueaQYnberHeNUkmOK7fFq9ndKuFIS43XrqPrq2Q5Pe+4PMYFEJPUHf37k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722031379; c=relaxed/simple; bh=2fxp7bk7psYrG+xy6iN7lgDuKvbQ1PVeve7j4h04aZI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=V4pt+YBvcO0XMy/4pn0y+xEHN44NgpIeozFi6HaLfCcGm9wwY7KtpY4qZ+uJCLBd+JPdBBdLQBaiehatTxRn5IIAXlrg49IrAi2nD0XN0CpjCJToBTmi+OQaEwSqqmpU4hRWKkrdxNl53Gd7AkfKQimEy8iM/+OhaEWc4pYA7Ro= 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 1sXT1Q-0005Mq-SG; Sat, 27 Jul 2024 00:02:44 +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 1sXT1P-002Qhw-V0; Sat, 27 Jul 2024 00:02:43 +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 1sXT1P-00FdLn-2d; Sat, 27 Jul 2024 00:02:43 +0200 From: Michael Grzeschik Date: Sat, 27 Jul 2024 00:02:39 +0200 Subject: [PATCH v3 04/10] 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-v3-4-4da7033dd488@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh 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=8159; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=2fxp7bk7psYrG+xy6iN7lgDuKvbQ1PVeve7j4h04aZI=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmpB0BJ9vebVmp8oyuYGxvY1Ooiwz9lOFLUZ1JA TG22cv4/p+JAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZqQdAQAKCRC/aVhE+XH0 q+tjD/9dAnLVcFtQzicDRlU5+JmN+MuRUpQ7ZIfHD7H3bikn+D+MI7vp3cVfL6ATjwzn6tb4R27 6qWqv+ASIYxD4DOpBz5hBn7hTFGAszNpEtz7fWrcMtWKGq43X3a8BP08GAIZB4G0vXlxWxbIMrn WN+FGmKx9w21/P4tWt+XLTWtHG0Wsoydsr2VJBYhEX32PHekKo3SaFSv0//vq6o32ROst0nSKCn B34/ZDKGwhdBP0Nvc+xZdroIriNMs9vegKQKQRTOITqzNWQFUlWoi+z0jcQB9w5gZT7BepdcbNd vV71rd+u+YcTl8+xNgwf6vbHcGF9hHMkG0h4Gml70rMi4R8PEf2c9sAdhoeGvm5jaJo3hKryswc 7hXmMb4ID3JizGJ41TOrRqpWWPlnN2Cl11dKameXl8sZ1JxAz8v5ZxpClomfV2YqJlelCQveu41 bNbAikofS9n7eJ/J22+Tlk5a/jaU+iSD4pyqqhUhDHTgBJSnwjTeSn0n/4GFm7QNLGBTxSBkQ+Y LkJQKSUjO8Lzo3xvep6+5hIaUAPst0aOLjBbm81JUmNZORHjUUNtctl97rbNImfecN8B+iyHbeZ sOc4pyNCtN7bhmi84zMsa9cBFQvSwg6Nx/jaztOl+JfBzBy078Y4PzH8fIzYjvqdM2LKebEOzJk M57/piWhxYejDAA== 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 prioroity that is iterating over all prepared requests and keeps the isoc queue busy. It also watches the theshold to enqueue zero length requests if needed. This way it will be scheduled with the same priority as the interrupt handler. But 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 can be scheduled on another cpu. Signed-off-by: Michael Grzeschik --- v1 -> v3: new patch --- drivers/usb/gadget/function/f_uvc.c | 3 + drivers/usb/gadget/function/uvc.h | 3 + drivers/usb/gadget/function/uvc_v4l2.c | 3 + drivers/usb/gadget/function/uvc_video.c | 118 ++++++++++++++++++++------------ 4 files changed, 84 insertions(+), 43 deletions(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index aeaf355a86eb3..1609daf85a258 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -986,10 +986,13 @@ static void uvc_function_unbind(struct usb_configuration *c, { struct usb_composite_dev *cdev = c->cdev; struct uvc_device *uvc = to_uvc(f); + struct uvc_video *video = &uvc->video; long wait_ret = 1; uvcg_info(f, "%s()\n", __func__); + kthread_cancel_work_sync(&video->pump); + /* * If we know we're connected via v4l2, then there should be a cleanup * of the device from userspace either via UVC_EVENT_DISCONNECT or diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index e252c3db73072..b3a5165ac70ec 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -88,6 +88,9 @@ struct uvc_video { struct uvc_device *uvc; struct usb_ep *ep; + struct kthread_worker *kworker; + struct kthread_work pump; + int enqueued; int dequeued; diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 4085f459c3c70..de41519ce9aa0 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -429,6 +429,9 @@ uvc_v4l2_qbuf(struct file *file, void *fh, struct v4l2_buffer *b) if (ret < 0) return ret; + if (uvc->state == UVC_STATE_STREAMING) + kthread_queue_work(video->kworker, &video->pump); + return ret; } diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 0bd49d4e106b1..a0448f8e8f334 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -376,10 +376,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); video->dequeued++; @@ -442,54 +439,78 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) return; } + list_add_tail(&req->list, &video->req_free); + + spin_unlock_irqrestore(&video->req_lock, flags); + /* - * 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 qbuf 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. */ - 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); + kthread_queue_work(video->kworker, &video->pump); +} + +static void uvcg_video_pump(struct kthread_work *work) +{ + struct uvc_video *video = container_of(work, struct uvc_video, pump); + 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); /* - * 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. + * 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. */ - } else if ((video->enqueued - video->dequeued) > 32) { - spin_unlock_irqrestore(&video->req_lock, flags); + if (!list_empty(&video->req_ready)) { + req = list_first_entry(&video->req_ready, + struct usb_request, list); + } else { + if (list_empty(&video->req_free) || (video->enqueued - video->dequeued) > 32) { + 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); - 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) { /* - * Endpoint error, but the stream is still enabled. - * Put request back in req_free for it to be cleaned - * up later. + * 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. */ - list_add_tail(&to_queue->list, &video->req_free); - } + 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); + } - spin_unlock_irqrestore(&video->req_lock, flags); + spin_unlock_irqrestore(&video->req_lock, flags); + } } static int @@ -750,6 +771,17 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc) INIT_LIST_HEAD(&video->req_ready); spin_lock_init(&video->req_lock); + /* Allocate a work queue for asynchronous video pump handler. */ + video->kworker = kthread_create_worker(0, "UVCG"); + if (IS_ERR(video->kworker)) { + uvcg_err(&video->uvc->func, "failed to create message pump kworker\n"); + return PTR_ERR(video->kworker); + } + + kthread_init_work(&video->pump, uvcg_video_pump); + + sched_set_fifo(video->kworker->task); + video->uvc = uvc; video->fcc = V4L2_PIX_FMT_YUYV; video->bpp = 16; From patchwork Fri Jul 26 22:02: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: 814755 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 7B6B042AAA for ; Fri, 26 Jul 2024 22:02:54 +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=1722031379; cv=none; b=PCBQraeXZyV4xOhVWgllUsHM+vIZ58s7C5vd/whFG+89ow8GvIpmFneTHLqTSxzRtVE2qQUtiBpaDZKaF1Ck2HK7MHLMId7qdLuCylitTzdcdzUH8XkHNxb1d8KwvaPXj2l0XXt2C1Hj2A6BFvL4R2I/ZH2TehOMKdVCibkS6Hc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722031379; c=relaxed/simple; bh=toGTO7Y0GTVk2fkauRz++GP/r0GYyNqYRHF8xHVsB1w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hM3iGI+lpuvP8Dz5dtDAgM1X0wmnp5Gegvh74W/XVn7XFfEzUr8BXzc8gkw66rO+nWlFYGSK4KPSqhy9TsB9V+aFEkluJEVH002NqrhUCinfGLe3rbTA8Bx2T08s25OqzxzTgFyd7Njs9FyI58DMdCYrLCdT9WOhmvqJBPYsyp4= 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 1sXT1Q-0005Mm-RE; Sat, 27 Jul 2024 00:02:44 +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 1sXT1P-002Qhx-UX; Sat, 27 Jul 2024 00:02:43 +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 1sXT1P-00FdLn-2e; Sat, 27 Jul 2024 00:02:43 +0200 From: Michael Grzeschik Date: Sat, 27 Jul 2024 00:02:40 +0200 Subject: [PATCH v3 05/10] usb: gadget: uvc: remove uvc_video_ep_queue_initial_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-v3-5-4da7033dd488@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh 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=2676; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=toGTO7Y0GTVk2fkauRz++GP/r0GYyNqYRHF8xHVsB1w=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmpB0BGyY/DsH7t65QxxYphVc5f6oKZh6k2fft9 EDfB52lj0qJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZqQdAQAKCRC/aVhE+XH0 q+JJEACsTAyocFRKtYeFZuT2bmOzFbKFgChfP/9HI/JoYwxz20Mx2wzkYal1LE3BqIZzS0WJPRc 0MnSLyfpzkbwczgc1rLSa0whr1W3VrjipQc0tbghnTlJrLeqkljxWMo3x1TytywzJNCdHVHHYBz ZtabZcpZ9/yn0unqbs/7QPsOfOuQEi+I/fG9QSFRrS8gg+/mPUrZRCrDAuZJw5rJYfDDCcu9dLd 5cgrSNzinvol+2FNaPi+cHD/fxk0d2nUvZPBPPa4y+HG5YxGyiDgW41Xak1FJLbXsNqBWPl2bDt v3U6V5tOvPEvblMD7EmhhibIFYYnKXAygJ3RacKT3SygGewWmFiHJysG4z2JWBAfDWUuRT9vepi oAqbopdyy4bQSH8fzfL1wCZ6Y3lApS2FjCHDFiXUQYgcE+zpWrPmSO0Vc+yMXeQSas11X1E8gqI MAIgT6GRIi6q7EtXtE0Sivq9Pi39Yi5ixCm5oEesgezSO+ePqew6MqpKFkM8Ddi2KUYHTN4QDXq w/glWl7Gdnd1lU+hG9fgD+rbKWuixt6qidSIb0zX2LuynrlemZ/m/4o6T00MIiJV3/6zBojZ1Vg cPJk2oCl95LJuiZsVnOwnmELJzlwBBHskP5Z5fdoWZGmvYHw+UoozHxUkIeIlUQyJqLQtf5VlE8 lCxCX8RzP5wsIAA== 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 By moving the buffer enqueing to an extra worker and not enqueueing the each request by its corresponding complete interrupt, we can remove the initial amount of zero length requests. As soon as real data is available the isoc queue will be filled as much as possible. Signed-off-by: Michael Grzeschik --- v1 -> v3: new patch --- drivers/usb/gadget/function/uvc_video.c | 46 --------------------------------- 1 file changed, 46 deletions(-) diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index a0448f8e8f334..463777b5db6ff 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -325,50 +325,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) { @@ -755,8 +711,6 @@ int uvcg_video_enable(struct uvc_video *video) video->req_int_count = 0; - uvc_video_ep_queue_initial_requests(video); - return ret; } From patchwork Fri Jul 26 22:02: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: 814867 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 7B72455897 for ; Fri, 26 Jul 2024 22:02:54 +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=1722031379; cv=none; b=QKePmq/nN7M74Of69jow8Baa44ZG0eqQle9/ZtidkGB7RQUKYNpDU+GjeC7bDDd76i1KIN/ZMu69F/cSDDzW3ichmvo262PWRMWfUMLHAiB3P9AyTaAVhbcAS3Y1OPPoir2jzbYuuaisNK4xzyD6HHUrceRL50pXDUK3fXY+kTw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722031379; c=relaxed/simple; bh=2cdHVqHAzmPhViiTiJfqBs6awqwnWOp3F22KKYxab9c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=khagnyu/8Uvzw7dwYeRXmfvDyjxvJIK4kRxDb36SBKOnUZb+tEv+1imAAUv27FukFX8a7+xZWDq6HXSODENyuMAyxYVAnoy0EjFtW4l6HY7adY3oghO6c01OQO2kJmNz4FcotnOOD5T5jeSH/ZorL0O63ZioBNgxfsaPUd1rsRQ= 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 1sXT1Q-0005Mu-RD; Sat, 27 Jul 2024 00:02:44 +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 1sXT1P-002Qhy-W7; Sat, 27 Jul 2024 00:02: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 1sXT1P-00FdLn-2f; Sat, 27 Jul 2024 00:02:43 +0200 From: Michael Grzeschik Date: Sat, 27 Jul 2024 00:02:41 +0200 Subject: [PATCH v3 06/10] usb: gadget: uvc: set req_size once when the vb2 queue is calculated 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-v3-6-4da7033dd488@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh 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=3140; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=2cdHVqHAzmPhViiTiJfqBs6awqwnWOp3F22KKYxab9c=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmpB0CigTP7a6ATBe0DOlEpSLqxJ9bWgeYmgTKv EJmPpi3+7uJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZqQdAgAKCRC/aVhE+XH0 q7QHD/4tayZzs7J42eKo0bexh43q6jOSkDfIuS6Oj7Bu3jg2J6CcpnjRFPIiDYQw9taEX/gqTMs nR+8ECMQpYrqH58IcZdXMwzlDvvhP/jVe97rCEoXJAqg7F51JjTkZUzHLIKRkkSyBVasr/fUnMX x48VdGSHOelz7bka12DbpnRG9/ACF7LKQHD3o32CS0XvFy3grRjsYUyjpwHL9mFRCRTdomYaw+J 9gz1kW0nerQFBL8uLjx3OiFWonlUbas2lZ6bAbqUHXvq5aHKFujYmkSidccLIaLR2TErXd9v722 JrFIbN7paHpcoKr6XEL2gJRfP0maqKoofAR96SiIEk1qaM6+s4k/v0cbiTxUXF3fSdvDyOtyuGJ OdxxD67Ixb+iSdXfuroA973oNwUHQ7t7sC2dRsXYqpaRE9spv28vrONipUv4D3gFD9+HFbchgu4 2unklUU3psEIE/O4bqT1NqbzACHFwauXSqWsM+ACe/DBXj0PSQC3VTIistIRKjFeCCtIBXPmMGY 6L9wCLcjYTtR9WOPk/PxEPax3tD261rVBVRxopGGk9fJ/Trl+lx9Yte9HygEVVG7mlT7fjG2An3 To5sXo9vyCozZVGB4mLtBqPcC6PNp76f0dsXq2PYLUxCKuqoAqKd1UVoLIBHTCHQv8ytSvLYdB3 dDLXJ+6Fg2Oj4zA== 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 calculating the req_size on every video_enable/alloc_request and is based on the fixed configfs parameters maxpacket, maxburst and mult. As those parameters can not be changed once the gadget is started and the same calculation is done already early on the vb2_streamon/queue_setup path its save to remove one extra calculation and reuse the calculation from uvc_queue_setup for the allocation step. Signed-off-by: Michael Grzeschik --- v2 -> v3: - v1 -> v2: - --- drivers/usb/gadget/function/uvc_queue.c | 2 ++ drivers/usb/gadget/function/uvc_video.c | 15 ++------------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index 7995dd3fef184..2414d78b031f4 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -63,6 +63,8 @@ static int uvc_queue_setup(struct vb2_queue *vq, */ nreq = DIV_ROUND_UP(DIV_ROUND_UP(sizes[0], 2), req_size); nreq = clamp(nreq, 4U, 64U); + + video->req_size = req_size; 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 463777b5db6ff..9d3cfa96b1350 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -480,7 +480,6 @@ 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; } @@ -488,16 +487,9 @@ 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); - for (i = 0; i < video->uvc_num_requests; i++) { ureq = kzalloc(sizeof(struct uvc_request), GFP_KERNEL); if (ureq == NULL) @@ -507,7 +499,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; @@ -525,12 +517,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: @@ -658,7 +648,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 Fri Jul 26 22:02: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: 814758 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 7B5E4168C7 for ; Fri, 26 Jul 2024 22:02:54 +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=1722031378; cv=none; b=S2TzmdntFuRNgaZ5TZaY2OvTpV97ChRmtj1AeBnbWOGbGCqqS0EcWHjEFd2Cho4xNT3AyUrriiYoagyOoVI7QtcNXoiFssFuicyTqdnNk4xoITavku5cmjOa5D2aP1bUZE3h/pZDqveOQ7cv0U6yvq4xSQ4+8yaq/fUSmCJ/woo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722031378; c=relaxed/simple; bh=YRBDpEfjHAjrzZK3/i0F/BaCWbQtvXY6jTLtlI3OQ3s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MzC6gBnJEpr0Qs4Ln3AHTtA8WCY6mx/wtnz9TVKr1p+9UaBfqw6x581PhhJ0hDjhAFraYhsJm8vpiCJ3HHpJFMmS+k8kc7vWBf2UkI6RkgYlWt1Et8J6KKeMMfC7geJoqmWGzvrEqBt1DkbsJQIkl5Jp8yZjD2SjNPyZrsHAtMI= 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 1sXT1Q-0005Mt-RR; Sat, 27 Jul 2024 00:02:44 +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 1sXT1P-002Qhz-Vl; Sat, 27 Jul 2024 00:02: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 1sXT1P-00FdLn-2g; Sat, 27 Jul 2024 00:02:43 +0200 From: Michael Grzeschik Date: Sat, 27 Jul 2024 00:02:42 +0200 Subject: [PATCH v3 07/10] 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-v3-7-4da7033dd488@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh 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=3309; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=YRBDpEfjHAjrzZK3/i0F/BaCWbQtvXY6jTLtlI3OQ3s=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmpB0Cxv5ljIXB2iYi0xExpUg+xJoNwpnxLuSwY 2q1cww3DgiJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZqQdAgAKCRC/aVhE+XH0 q3avD/9pwh6zTPF3zkMWim9opCdTN/Tg0gAfeqnRFJ6kZQumSsZri0lifkR4G7fuEbWx2FfYN13 Ute37jBOBP1SZYg1jsJtIEkoI/K9NJjG59LySSoadvDZb9Ub1YzqoFPe7jOSs4z13S0ZHbUGyxp Tvu8Rqwi2iqVExUsp3ehUdNeQ0XwBxtM0Urzjaanw5YiYkwVBsXShNCPflH5niMfgQ3M5crjbAc KwSuT33lb4s0lOFLIU0CgYzHYd8l5q/kWghoAKthYte09G91ASeyAWMzL5AMAP+0C0n237kKBWd kRpbarFbVxw1YySgkMypcr+FhVieIViHDl2uBjgonN0YzSGQw+BEzIdDmR81VkZuuHdVRmu9wIA GIGVfZD+iFZTnL3R8rz3gVChH687B4youy1pq9R1OCvMn6W3JXNgZSTbbxtQzamSgkcLIUhZ3xX Ntw1O32b/u+4/QWCg8pfbCKn/EhPfXqETXUbQ0AyyWNhUgfa0Be+EaOiKBy6Ouq+kYEe/wf39WX tQEnKd+NNvIEJ+keYhOd7de94kylUJsNBVLwEA9Ymqc7SQ6kZfXLxR+CnWWzEMunJmFflnO8zGi sDHhNup93CIBgKfUpSZaDthaWqi1o9h1C/cRakONqZBFqwlz+jLsKUrUiqDV7VP2Dh7T25/bZzo Rel+0Byu7FrLTPQ== 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 --- v2 -> v3: - v1 -> v2: - --- drivers/usb/gadget/function/uvc.h | 1 + drivers/usb/gadget/function/uvc_v4l2.c | 52 ++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index b3a5165ac70ec..f6bc58fb02b84 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -100,6 +100,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 de41519ce9aa0..392fb400aad14 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -307,6 +307,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 (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + 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 (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + 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) @@ -577,6 +627,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, From patchwork Fri Jul 26 22:02: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: 814756 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 7B64D2C684 for ; Fri, 26 Jul 2024 22:02:54 +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=1722031378; cv=none; b=fw7aSBrV6dlzy+/4qBOBoCIvrjYKCSE+wk45/fb07Tf93cMQRune3hqhg2EF9g637wz7CUBJyBY/SRCqw1Kw/4n61SZwf/HWUFKrPDaQWiPwW3F5VPExD7VtaDzq6NXsVb8fXlgEaD8ITnuWL4T9YJW7u5vtt3JZprdmGyb7SdM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722031378; c=relaxed/simple; bh=f4ZiiU8LD4siPkXxdwBYmCvsM069yp/y9JCG/a+mOK0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TjaUievEu/rNeShaCo4Rfu2nO9boiPtLX1T1ykJzgos9zedFOv7wlxI/Fr/viS9RzyG5a0Ou0Rpd3OWTq17k2OZiBne1b6fW55sfm7bT1ReXzlhJNUKr06HykfvH6IcLbVD2DFVChTp1JRhuDAXK7MuzpyKYsVIeUGj8RhCWZW4= 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 1sXT1Q-0005Mv-RG; Sat, 27 Jul 2024 00:02:44 +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 1sXT1P-002Qi0-WF; Sat, 27 Jul 2024 00:02: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 1sXT1P-00FdLn-2h; Sat, 27 Jul 2024 00:02:43 +0200 From: Michael Grzeschik Date: Sat, 27 Jul 2024 00:02:43 +0200 Subject: [PATCH v3 08/10] 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-v3-8-4da7033dd488@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh 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=3507; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=f4ZiiU8LD4siPkXxdwBYmCvsM069yp/y9JCG/a+mOK0=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmpB0CTURNsHotBImTaWZbqX3vROnpkkN5brw9G aE9l0bSkSyJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZqQdAgAKCRC/aVhE+XH0 q7v1D/9DA7cD6PPpq9MzFhR5WXx6PdEWMiUA87TqOQ8ySUn7q5PCEAwzq4X+t2V/sj9I8GpfhIJ EVnvNDMiY5Ilfqec+LSZB77sxLQzV6cq9bDhrfpg3hVWILh1VqzzjIl0bCoyFWNxWjiXr5aqtJV 2m86ytSaroPleqeocDqFpDz+rf9wbyiLedXxHr3/m7pdQ2+0z2P8QiM520sRjJkI2b8cl8wD1fw twaMc37W3Nc8AoK2uk9usGWc8ayvGhvJWgvyxeHlHgQQMJU9+a3ZtiidAYG1evu3cPduP1ySjpA yHu2lraeRGS59wg7QSZA62Zdcp6cjzl+ZOOG4Ms+FYOTNKKxZm1BiZHkKuQ/FK7OtQ1nSQfODzF bRF33UuNgtbXi1AwVubX4i82h/IDg35CrBLxYXGxdJFph/lvBZHtNIg/4GYPCVnqXaCaOIXubjW H+oBPDyPr/No2Yn7mCb4zbpDVYVQoRCYSMb9r07FGJO5cPipkPBxn74oJ4HdlhywSnbTllurHtT qO+LerXZOrC/gVm6Vpsngs3ClZK/nl0AMH/mgIHCWjJoAgCYE2a03BL4EsodeXKuBq7RKOb1TWg rQi2zdstkYQtarjeFlvqU8c5z/X3kIqPEErK/sGPfL6KEEaINBJwxkU2BpawJw954KDCX//fvGj YFKtYLdkpFViO5w== 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 With the information of the interval frame length it is now possible to calculate the number of usb requests by the frame duration. Based on the request size 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. We keep the current req_size calculation as a fallback, if the interval callbacks did not set the interval property. Signed-off-by: Michael Grzeschik --- 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 | 35 ++++++++++++++++++++++++++------- drivers/usb/gadget/function/uvc_video.c | 2 +- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index 2414d78b031f4..ab04df0e4f360 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -44,7 +44,9 @@ 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; + struct usb_composite_dev *cdev = video->uvc->func.config->cdev; + unsigned int interval_duration = video->ep->desc->bInterval * 1250; + unsigned int req_size, max_req_size, header_size; unsigned int nreq; if (*nbuffers > UVC_MAX_VIDEO_BUFFERS) @@ -54,15 +56,34 @@ static int uvc_queue_setup(struct vb2_queue *vq, sizes[0] = video->imagesize; - req_size = video->ep->maxpacket + 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); + + max_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); + if (!req_size) { + req_size = max_req_size; + + /* 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); + } else 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 + */ + return -EINVAL; + } video->req_size = req_size; video->uvc_num_requests = nreq; diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 9d3cfa96b1350..fd2195f7153d9 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -307,7 +307,7 @@ static int uvcg_video_usb_req_queue(struct uvc_video *video, if (list_empty(&video->req_free) || ureq->last_buf || !req->length || !(video->req_int_count % - DIV_ROUND_UP(video->uvc_num_requests, 4))) { + clamp(DIV_ROUND_UP(video->uvc_num_requests, 4), 4U, 16U))) { video->req_int_count = 0; req->no_interrupt = 0; } else { From patchwork Fri Jul 26 22:02: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: 814757 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 7F3CA14A08F for ; Fri, 26 Jul 2024 22:02:54 +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=1722031378; cv=none; b=qafB/DPbVwfJFGtwHvxxb7FXHSuN2wLX9y0OdZdWocTjW5p4/YMBCaitKskLY9ubudh5gTDa/YSaREdhtl2p/i31tYDJhg8DO66zEvFmjLef/FMBpfNc7GPHvXxUEsQ1MVewlQcbHKTA8yHzlo85MEPxUiOeKe5dBkBmP3DyMNY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722031378; c=relaxed/simple; bh=Xp1Vap8cEke4S3pNDtwJUBr4HLRTDgdAQ6d4cgu7+Hk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=anTDbdTYEmmxjR7LfMqlY4iPEC2cmyPhOHsCeucd9jdcyO76ujjudk2lUyvyec0jTbV0+y2Cyd6XJ7gpTMwtCszeYSNLz+dFQ/YqFsZ/z9Ipq21+F1kb6Khx3LvVDb21baXPLaf03QcNpe3QKa4HU0JvJrzbo43nhTeYkXi+11o= 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 1sXT1Q-0005Ms-SQ; Sat, 27 Jul 2024 00:02:44 +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 1sXT1P-002Qi1-Vy; Sat, 27 Jul 2024 00:02: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 1sXT1P-00FdLn-2i; Sat, 27 Jul 2024 00:02:43 +0200 From: Michael Grzeschik Date: Sat, 27 Jul 2024 00:02:44 +0200 Subject: [PATCH v3 09/10] 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-v3-9-4da7033dd488@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh 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=4201; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=Xp1Vap8cEke4S3pNDtwJUBr4HLRTDgdAQ6d4cgu7+Hk=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmpB0DDvtXCJOa/eaeLIwfNldVJSFpSlADqcnQj qEmm1r7QXSJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZqQdAwAKCRC/aVhE+XH0 qzSkD/44HnMgCN7nvly6PyJO3tI4p9vACyybRJ7JxKnKKMDMgLwF9T9qhJ3ZJgm0VSBLZ2HRDtw w4myv3G73FlPwRImO4oysKQkPFDeDHx/F/y2+uhS5BcELvN9iF3ZsaZYM8xHEIGqZWGKbQvjCAo /PLK18/wnJpq9UaNgfKUiB3ZmbvT4UL2uh3NAtKMP4JKH3gyoNiqdJLSG0hg4hecp8MczjrfUX6 Lnin0aGyhlT5iXV9ciAc9NMgF8YwsDlAsjlqtu14rDYfVosOdL9R0svMyTzqQRzc7xr2vDlMuvy BcX0qUC2kHM21z0EqPJUHbHnm5Xc7/AVfFd4Ey1L+YS2Ag0o5cOdn664+CtlcScFyWCWoXgx2ye +wystngiwKndo4aQ4dvWqYWC5Z+RkNDWBzjeZisLpD9SHVmTP1llC+7w0CrZzZ9u1EQI4azuwPk POlxaAMdEXuTEiNjt40xKzOZK+HfFcMeMo7JyV6RwBxp46fWcTPV8RAcm6DTScoS5v6WsIccXWV Bcur/a4q6c/DT9tvzyOH3kCbYfbhulos7BoE5sk34ZzeWNLaa48NB/MunGNqIE9MZhgcqqYbizR a1HcACpH099S6WouvM2gb+Lc5TMSEflDl14ydFb1PwRo6kPSLH+ajXMFjXd+eEOSpCOHJPKZKMW 5X62/TJnYQJ5HsA== 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 For uncompressed formats it makes sense to fill the requests with its maximum since the amount of requests and its size is calculated for this exact amount. 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 even better to scatter that smaller data over all requests. Signed-off-by: Michael Grzeschik --- v1 -> v3: new patch --- drivers/usb/gadget/function/uvc_queue.c | 9 ++++++++- drivers/usb/gadget/function/uvc_queue.h | 1 + drivers/usb/gadget/function/uvc_video.c | 13 ++++++------- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index ab04df0e4f360..e33ce72325031 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -94,6 +94,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); @@ -116,8 +117,14 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb) buf->length = vb2_plane_size(vb, 0); if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) buf->bytesused = 0; - else + else { + unsigned int nreq; + nreq = DIV_ROUND_UP(video->interval, video->ep->desc->bInterval * 1250); buf->bytesused = vb2_get_plane_payload(vb, 0); + buf->req_payload_size = + DIV_ROUND_UP(buf->bytesused + + (nreq * UVCG_REQUEST_HEADER_LEN), nreq); + } return 0; } diff --git a/drivers/usb/gadget/function/uvc_queue.h b/drivers/usb/gadget/function/uvc_queue.h index 41f87b917f6bc..a7355442dd6cd 100644 --- a/drivers/usb/gadget/function/uvc_queue.h +++ b/drivers/usb/gadget/function/uvc_queue.h @@ -39,6 +39,7 @@ struct uvc_buffer { unsigned int offset; unsigned int length; unsigned int bytesused; + 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 fd2195f7153d9..f6911f124be4b 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; @@ -145,16 +145,15 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video, sg_init_table(sg, ureq->sgt.nents); /* Init the header. */ - header_len = uvc_video_encode_header(video, buf, ureq->header, - video->req_size); + header_len = uvc_video_encode_header(video, buf, ureq->header, len); 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 +201,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 +213,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) { From patchwork Fri Jul 26 22:02: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: 814866 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 F15EB15A849 for ; Fri, 26 Jul 2024 22:03:19 +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=1722031401; cv=none; b=f7k4YDrWN94VnqznNZy01C7Xvoiud0CupS3SgxyUHIEELnzNmepw0BxU6ZKlld7b1X7lC7XGRUS3DqUZms0TE7nex011j8LQZrDecWXfOLLZlUH48B5YR5ZZNz1Y4szPobEULBGPcM9oGXIe9JiA1Zr7LuYtuurZJACqewB9Nh4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722031401; c=relaxed/simple; bh=JpVyBCvXbR+bijgysqnCR5c1wnLhUDG1b+V58uqS5S8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Y4V8ymebevr3FTzgKhFEL688ulZu9ldZUKz4O/ptvSWGDuw9kPQ2t24yZWp9PB+Kw23rgpLz4EGm7zQFOfIYlwTsXhc3qMoP6e107fwVTcfoJF2nM68+ALrXOlnpL/qWOA/ElprYu/8QlNd7ocH2iWmRp2PS9xXo3SettzGuycI= 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 1sXT1x-0005jI-Dz; Sat, 27 Jul 2024 00:03:17 +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 1sXT1w-002QjR-S1; Sat, 27 Jul 2024 00:03:16 +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 1sXT1P-00FdLn-2j; Sat, 27 Jul 2024 00:02:43 +0200 From: Michael Grzeschik Date: Sat, 27 Jul 2024 00:02:45 +0200 Subject: [PATCH v3 10/10] usb: gadget: uvc: add min g_ctrl vidioc and set min buffs to 4 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-v3-10-4da7033dd488@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v3-0-4da7033dd488@pengutronix.de> To: Laurent Pinchart , Daniel Scally , Greg Kroah-Hartman , Avichal Rakesh 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=2791; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=JpVyBCvXbR+bijgysqnCR5c1wnLhUDG1b+V58uqS5S8=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmpB0DaYLtFlQJJ8cqaOw5eL/8c9CeyZh/7Kspg WKpXQiuoX2JAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZqQdAwAKCRC/aVhE+XH0 qy3MEACSA3D57LqbAuWIHEmcOTPgi2X68CWbXTxMB/LgJtAhHKcu2x97lItkxAeW1tOEIAY+kfv RSQ1gaw0i6KIjpgEV+D7BEFzYYD9NHuzdiZD0/QYh6VVH/A86bjvZyultRv39siDNUu/4aXzZxa ZQha6G7cvn1HNgzjf4ff8CLcmMWq9LwFTwafeC3eKzrNHPVaf4fHsD6aK8xhOKLp/9YeVTkUXPY 7siaaOtJ9DREc+W242Jccc8Z2JvTcxTjME2JmA5O16ECJw60bMEgXXLVXko5oOr+4S8vCL+29yl 6Xf0KGxDkuJ/pmsvK4EdJfgKECD4Wzsb31KWKHJvvG7tc3Fpnf4igEe7YE4MrlapP84lRc6ytxT +ZINoyJtVwLoP2cPlCF3KUfy6LsPAAUxYWW/1YmcdnvS8K/KJV/XJttYXbPzIzm4VlEt+ZIQb3i yKf6LO5xD43gXW5tRgMlAZ8VPznJxhtXZ2OW2rKG+TpGONXxWVN8wRldqpafRtCrkTrkoR2e6Ce 6dwirtt/EA4kkMSnpVHd+rgvhplwtYHl61A7IKLLZGR95d/dpHC6aoWhhm70zWOT59o0URl1D4F MUHoUnPoQO8qirLqzOixgraYRRHqztkB241z1GhbpNF+3oz5RSeC+IOXwUTWEaNmDaKBmjFEtux zlCPoFqpQCuS3Gw== 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 increase the minimum amount of v4l2 buffers that will be possibly enqueued into the hardware and allocate at least UVCG_STREAMING_MIN_BUFFERS amount of requests. This way the driver has also more requests available to prefill the isoc hardware with. Signed-off-by: Michael Grzeschik --- v1 -> v3: new patch --- drivers/usb/gadget/function/uvc.h | 2 ++ drivers/usb/gadget/function/uvc_queue.c | 3 ++- drivers/usb/gadget/function/uvc_v4l2.c | 13 +++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index f6bc58fb02b84..e0b1f78fdbc65 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -71,6 +71,8 @@ extern unsigned int uvc_gadget_trace_param; #define UVCG_REQUEST_HEADER_LEN 12 +#define UVCG_STREAMING_MIN_BUFFERS 4 + /* ------------------------------------------------------------------------ * Structures */ diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index e33ce72325031..157e7f7d49c7a 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. @@ -86,7 +87,7 @@ static int uvc_queue_setup(struct vb2_queue *vq, } video->req_size = req_size; - video->uvc_num_requests = nreq; + video->uvc_num_requests = nreq * UVCG_STREAMING_MIN_BUFFERS; return 0; } diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 392fb400aad14..f96074f2c2824 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -357,6 +357,18 @@ static int uvc_v4l2_s_parm(struct file *file, void *fh, return 0; } +static int uvc_g_ctrl(struct file *file, void *priv, struct v4l2_control *vc) +{ + int ret = -EINVAL; + + if (vc->id == V4L2_CID_MIN_BUFFERS_FOR_OUTPUT) { + vc->value = UVCG_STREAMING_MIN_BUFFERS; + ret = 0; + } + + return ret; +} + static int uvc_v4l2_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival) @@ -629,6 +641,7 @@ const struct v4l2_ioctl_ops uvc_v4l2_ioctl_ops = { .vidioc_streamoff = uvc_v4l2_streamoff, .vidioc_s_parm = uvc_v4l2_s_parm, .vidioc_g_parm = uvc_v4l2_g_parm, + .vidioc_g_ctrl = uvc_g_ctrl, .vidioc_subscribe_event = uvc_v4l2_subscribe_event, .vidioc_unsubscribe_event = uvc_v4l2_unsubscribe_event, .vidioc_default = uvc_v4l2_ioctl_default,