From patchwork Tue Aug 13 09:09:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 820051 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 7CA5917BB34 for ; Tue, 13 Aug 2024 09:09:40 +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=1723540182; cv=none; b=q+BBTPOkH9ZOrzVq0uYNrr+1rxpHbU87GAoljQj2Dx3LXikDSwWG/9n8tJ9z5V4u0iTYO4FTOsQdIiQ136MzjSAMecMSSha1R7dwYjx3oZhJ6DChBhez0aas0m7hrDPUKNdp2sWesgk1u6gIlTjHzcRyiLL4DcGjGYRGxDtR8v0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723540182; c=relaxed/simple; bh=V2Yg1K6uq3EvyDknOFm++29HuHf8ClJtAHIq6pWIOJk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mLOQGfkj1jIMQGUp7NfM6EY7YrvibHxxBn9hUAcydsop2uSyOaD+4NpX0I9TGbyUhd/Xvp3ClPmUXEnKXj+sk0ebMj1bdgT6/9FXNDdQqi4K3//9y5/T+Dd9wbJE6+hURdJs7mtnGgMaGi3Jywj0QtSC4tPKL0McpOP/C6JY2Ks= 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 1sdnX4-0002CI-SF; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-0005of-6f; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-00G1eS-0G; Tue, 13 Aug 2024 11:09:34 +0200 From: Michael Grzeschik Date: Tue, 13 Aug 2024 11:09:25 +0200 Subject: [PATCH v4 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-v4-1-ca22f334226e@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@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=992; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=V2Yg1K6uq3EvyDknOFm++29HuHf8ClJtAHIq6pWIOJk=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmuyLKSSExtNbuUUMoqae99KcjxOhVaaLhCebWv t+FBaNFbiyJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZrsiygAKCRC/aVhE+XH0 qx/XD/9YiB/CgVkhOBRfztk6YsPjovjZRSCipVTgxN2AYls+g+SuaJBYLtP1uR2vnTW4TQEXzBw blEFgzkhe3ui8RKd7l6gYFEq1tX8/nMFpsXED2DYYZw/la6S0aBrmWg+w/HngVasDt07yAJ3JVR QHo62S2qHqlKNwhUkxNHzsRBqJkf6j7FZcjkjc8gPfpc/Q7Gqu9XuTUGS4JKhF6ECbVlk1n0EPa DejCc6BjcXwzovAHIVlZAny2pLe/r3WQBy/vLkP1gDL2PrNhUz/4Agv6U5GxOdKsWu4kj8/wSI2 8qXtQrWVMeZZJhgCbZarw+iOmW0ZzEv3ePfSy4rcHkHo1f39zy3arjx56Hk9ekakDKgDUpe2lXL +JYeoUgJLI1Asf7YX1e5g8dwyphYsjmWzpXzconqtobusUFk74uk0G2kua0euGkOg6eVqJfWaM7 hqb1reEB6cgZBNLS7pBADFtEM7r9jlUGLPYdb2S35iqTfoq9A5+nSEyWwZ4Gq4iaVJb1Aite9St Hba5dhxWylRUusKReg02KuzJyt6IRpH5JNQY/xXcSkKNxopUxcuGhgaQ3mNzOFMZV1goOip2H2A 9Jz1eHeArdjC90mRJV+tpCx/ENPe+PLBWjmhP0cETpMAGaRY84ephRNaSnV7PvMN+n+uJcN2FVZ 1OziOdTDRGG4pWw== 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 --- v3 -> v4: - 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 Tue Aug 13 09:09:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 819082 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 79D3D17BB2A for ; Tue, 13 Aug 2024 09:09:40 +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=1723540182; cv=none; b=HR9u3K3ZtRCdVE0S+zggscLbA8bqKjP7Ij5/EsRKxdVaEyShfIzrVnWMVznOe0LXzK3/IrwrNrT3+w75AYq4OpscgBsN6KdjLJ1h+5f+0el9BfK7EEUFGKd7EvD6gxdn0ObWBN5tnv8HbDN+jnyNg7WKayCWyCS3ucVvvnKydnQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723540182; c=relaxed/simple; bh=t4rn2tx6pz+7/aMEqxto9Mmqdr+OuwOa+HF2o3tdYeQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=p0Q0vZeIH83/epbCtnSNnkEhj7A2ea8t/zBUP5YLK2t1YT5bKWqRa1ZaGzGBxsvgxX0V1LGjBSsA6ZxUnoG/vTAGHaSikrR2tHUoXBgz1TqbcXiRTu+FQT4HYNAAVKrHwneaNvlSO5AF/rVjn1MR6OTUvoK2VThBCty3c/2PLtA= 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 1sdnX4-0002CL-SD; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-0005og-7M; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-00G1eS-0H; Tue, 13 Aug 2024 11:09:34 +0200 From: Michael Grzeschik Date: Tue, 13 Aug 2024 11:09:26 +0200 Subject: [PATCH v4 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-v4-2-ca22f334226e@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@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=2528; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=t4rn2tx6pz+7/aMEqxto9Mmqdr+OuwOa+HF2o3tdYeQ=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmuyLK3bg6sQ0kq9/4e3OENc6X8vS+Ap0IOUHj9 KX81K3fMG2JAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZrsiygAKCRC/aVhE+XH0 q5KID/9Bb8sfCucOUhL2eCTK0eY7W2lJbYRpq8SdeviwI1j5Jn6i6d6TUEr3tMi+/kKaTwNid1h zf9R2UJ20q3WJG4ksCa1pxcrWkF5jjEIalaDGX2xi6Xax5x3nhwIsc8YVRlf7Wd8lLuarQkLwEI YRF4nD68bFyULWccd/SPPd8sR4FTZFnj0X64aNwTexKz22RMxFqrStOI4RIOQFpvVhnTCVHJGyg 2Q6r1db5++VEWmDndCM295+qwTNTTNtDU2W/FUSMErPtNDQ4Sv39TGNtvbEGEw5YpBAy5z/+qDz 1zFA7g2ekeSQ7TY7w0nu1p9KdEFBNLVW1/lrfMugvOqnNWG2T5k7M9jBbbSkW5l8Hvj+/PEKcvq bZeYC9bQ5U09r6jmksmH+5z/hDt5vc20Jcm6vGALjrHXI7eHDUxjbwkyV4362sQ8Tymw/I2Uj4+ Rf2yZ03qAxb2d5sDPVFvK/K32MP80haumCRZG3cFnO3NtF9rcEiaioHi98rou06wLey/kH1q2G0 dGEgEbyiH+TwqlzI3aXkKxGYBFhYLspB72LkBlDIAvleH6wmpSKG5IvEHSqQfMRDycTQLk2E8qx VQPhLs7U61+uHv7yCCWXjHj717sLIok5FmVWZoc2jWE3pe1lytI4sWFv0NNAYamLzhvnBiFqWwI j/D86Ol7e54IQig== 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 --- v3 -> v4: - 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 Tue Aug 13 09:09:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 820050 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 79DE217BB2F for ; Tue, 13 Aug 2024 09:09:40 +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=1723540183; cv=none; b=sh+08R5egSrd/cL9t5xgGpTs5dkZkt+an9qZBePGVmdgYjw0QfL4Ns4saR0hmrCmNTw/CSRJGnY4Eh3Lbak4mvZuVRtS9glrAYCrER5e2BBO1Jjem7TtSVVwaFLPqu5r5n3B45wsa0dZ4t5LtyqdgBfZh2ZzVTduEwleR2PkM9s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723540183; c=relaxed/simple; bh=TlNFmUlB6A1ZL6sefujk/ACyJS6GxVDK0ModATmG4xw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hdL6pUkZMa2VweCT4LQPH8yzOirY+JHU0IxBvqfQVdf/uXzvvrynQyZwv9oWb/twgT0HtG3kFIsVwBJ+Dj5khqriQbN1TY0yXY6LMXdbpbcGhOJ6DDBjTXIZvwiKI3LCnaQAnKmrxsnhQlbk/8G9amdqWicEJITD/il8PAzsmzE= 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 1sdnX4-0002CO-SE; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-0005oh-7S; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-00G1eS-0I; Tue, 13 Aug 2024 11:09:34 +0200 From: Michael Grzeschik Date: Tue, 13 Aug 2024 11:09:27 +0200 Subject: [PATCH v4 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-v4-3-ca22f334226e@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@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=8659; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=TlNFmUlB6A1ZL6sefujk/ACyJS6GxVDK0ModATmG4xw=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmuyLL4YCrloiQa9JdeEqNWEKqiSExnx2Ad8RDt h2XJO6sCLSJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZrsiywAKCRC/aVhE+XH0 q5CWEAC4DGfBfHfTLGeAttOBlcufOMR/OjFvFxs7bTfrA7K9vGt9j8lyHmc6REzK8n1j5FkyOwv ij05nMypboPvJWDlTIi56qqTtLzyGDHqAmiU98p8U4xjc3G2he7b/N2j8AT6zVwHEvY/vueULwO F3gEIpyb3iakJItPb+uUw7LKlM3NvVjmMwi7UVEuBrpwRfH7Ef0fKJNPpYjAi0CAo+Puzww9rAe 0fNSpuWB+mORFr/AVNc0pLSx87NbLbRO1Dyy9dXK7rjgv4YX7ClZkRDgok5Fv8gJh3o9Wai5jrT FNJWKpj6CBgpCPG7aaWT5AlvEnLgNMnJFfwfTpCk1dyV4UQP118aQdJBRKqexIyytcHBcjAC01V x0SkomC57e5JAGsMgfAFY9FsreR7MrqhE4A5SrPDxrnpmUinQrMu9mvFnh42ffOOswlXb57sbsX 9l+yLNY4GRYMOCqYoITJTpPWHKysgRr639erA9xUkHjBSetbFuwkPVDpJku/qr5IXOfKlCg7iI4 /tmFOs4NZ1mnHlgYKET44+Iv3E6FMpq5TxGIrIPg3qELILAWWCPox4aK7t7XO/GFp/Yp23iuUte GwLGFnfN3r5C5MpjC9sAS8UIFGllg87a+lxWnq0wEMv+4t/V8nTMNg2Kp4upBx9YyBGGBmwZltP M62DAM6zvniVczA== 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 --- v3 -> v4: fixed exit path in uvc_enqueue_buffer by exceptionally call cleanup code on break 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 | 53 ++++++++------------------------- drivers/usb/gadget/function/uvc_video.h | 1 + 6 files changed, 18 insertions(+), 51 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..5b0bf8069d48f 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 @@ -633,15 +606,22 @@ static void uvcg_video_pump(struct work_struct *work) if (ret < 0) { uvcg_queue_cancel(queue, 0); - break; + goto cleanup; } } + + return 0; + +cleanup: + spin_lock_irqsave(&video->req_lock, flags); if (video->is_enabled) list_add_tail(&req->list, &video->req_free); else uvc_video_free_request(req->context, video->ep); spin_unlock_irqrestore(&video->req_lock, flags); + + return 0; } /* @@ -681,7 +661,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 +754,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 Tue Aug 13 09:09:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 819081 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 52F6717B4FA for ; Tue, 13 Aug 2024 09:09:40 +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=1723540182; cv=none; b=U0Cox5A9FLwolXAccehpA2t7V+K8Ypyh98PA97Nt7zFo7IKJDyDSf0mjA56m00kub34IY08oaULv6LXlZKaE+efOPKhJw2Bcos92C7oY9ynx0r4f8mJ21B4+jPQjXspj1BsUqp42S1tlBWt5WpgeLEtI7W0vUkfm7I3FEDZCdkc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723540182; c=relaxed/simple; bh=SkZsPxCbDN43LHxyvk94Y4g+KqeuNu68KsIeoOP6vGM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=A164+t26kRvq/9PgH6gP06FfOrF9XqgR8+dzCH8YJZawS8u5X95gfVbNPVQFJmQsdilCGuWKoYo5Ah/EMMCkekVsuJSJ81a4frlEjSqvR+svb/f+RfGypDrLD8U65GRb6LuDJHUe7n9DGelcsEINMVAVecd16F9eK4IUCyNvC3k= 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 1sdnX4-0002CN-SE; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-0005oi-7a; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-00G1eS-0J; Tue, 13 Aug 2024 11:09:34 +0200 From: Michael Grzeschik Date: Tue, 13 Aug 2024 11:09:28 +0200 Subject: [PATCH v4 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-v4-4-ca22f334226e@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@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=8172; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=SkZsPxCbDN43LHxyvk94Y4g+KqeuNu68KsIeoOP6vGM=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmuyLLLQ+WRpi7mVeN6VsERbrrfYXqlJ37Ck25d d3p6cd9Cw6JAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZrsiywAKCRC/aVhE+XH0 qw9oEACynR6NT41ltfX2ipnDFkcOH0Ik4WVCrEvYvnziPQOaJhQhODs45BiG0iOtXvV7y23WeNI bPIesIXgXbipv1Lv7qEUzI+jLAHlk+xx03B4WUOETfSt8an9sNNmhryo16Jn7DCBU6A6+k4eKgw ZvBfCiqvhyXSClZPQp1cRle5ODZoQkFDGpViGtRJksOkWbpL4oqZtgNVQCi6JIdexgydQGygOn0 UiXGs2ha3yQGYtu2ypmkHxXwzBsUxSUQemLVEvV/k+Q22N0zDdXkYE+yjzUjDgCETV/haAfNlnJ ypMEgN9GpM+VvOiGZE4PEnjxXumyhnZmHNGLhnREJNx0odm2w74/oYFTs6BEfB6kxqEma6yWhK+ lAW/430MogLawfyKeJlU1pmUCqkSR73OdkejfKspA1vMLpY/0+tYznWgm736GeVffpqlexAncQn CvQaNkdhfqrDWvZZy/BlvD965yrMi2mNhRUv4GVFy5sxIExE7XGRKJWDn/FtrseWEjurFmzYSGU 0J/AC+sG7q2DbQC/Tp1DSEQuEKUxUfxocvCpyjTRkvGZPiTn3/eb7gz9xaasNAuPmr3ilDrc5df 8n/s+zs/QEOylrk4OXVwtnbDMSFa6BK7Rvb76KO+L4Z9iHiI0x1QDTscIrXUd/MfcA5chitRHdf 5+7A3sTAkVFWrQw== 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 --- v3 -> v4: - 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 5b0bf8069d48f..a51e95e3b717c 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 @@ -755,6 +776,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 Tue Aug 13 09:09:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 820052 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 52FBF17B515 for ; Tue, 13 Aug 2024 09:09:40 +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=1723540182; cv=none; b=FNlqAddr/hdZ2MAG3M3NgBGF5BOfRYN5Kzq/psSh4YMAwe9cVyaxJzbEPC181e6JAQ7R0m9z+BQ2UvaguyInZk1MMYpG8lDZ3de5q4nvAqKYXp8yQR+hjt83FMjOAMQdFO6NCrS4W+EK2gFQnTOVUSRDdm3hGQNP4bzkac+dHGQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723540182; c=relaxed/simple; bh=bU0k/xA07ACWz48gmJ42M7Hs1NAUBpxOmkkbzuZRjN8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VLOCXS1MW2a2t1BjizHhGgfbgWablKxOt/0Cc9KqxEAvvMACnn6HP88t2a39uelWQ07rt3xTcIZwspBhpJmrrrtJOMmfa8KHjLSlrryjenCi1IB85NG6VYeF3JswTn2CcGiFb6XNRzMYOxvW9K3bijhg2lH2qYDtEy9S3NuAmb4= 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 1sdnX4-0002CM-SF; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-0005oj-6p; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-00G1eS-0K; Tue, 13 Aug 2024 11:09:34 +0200 From: Michael Grzeschik Date: Tue, 13 Aug 2024 11:09:29 +0200 Subject: [PATCH v4 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-v4-5-ca22f334226e@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@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=2689; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=bU0k/xA07ACWz48gmJ42M7Hs1NAUBpxOmkkbzuZRjN8=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmuyLMTSl44hvf3GoKX7pI+zynBN69r+UQKm880 jmhC+CVow+JAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZrsizAAKCRC/aVhE+XH0 qxLQEACbMBbolqOo1GGLT8rKUlXOH//bO16YaFaMvajC94L6p2zk5LaJiglZ+qNrYK+psyLbdbY sGtmJJ6iQjwqLrFU86G4Xyem2aU2YGI9kP55wd+JauWzcs3GK/IJjz23JUBamEi42aXM4f8GPB/ tf4edTnRtoaX4ISK5vJaa0th0ObUH+/ibk0d7imFk+bcBgnsSeL/TKhS3G3F0ZmSm5B8qIihFZN amGcVEEPKwo9sl66BBUXBIFAEenLGY86+LfnskxyT3U1y0o5KM3eVmLNS70zqsDtTJAirz2qfyE 15Bh3I/8RNOlE/tk1x3AZP/v/XnVLmcVColp5kqLSQlhaitYe+9VmxDcBmmozvY72nezBdtDJZa YTpruc2vK1D9FCPO+Hl6yWYakhu60dD/LRBYqqz54d6bicVbN6/RO4DVJLZ5C4kC9/6WcN/REeL 2qsQP1NJLSd/odIzGLwhA0AHXFnH8i/fsU1zFly1psl/164xE61BgQ8GxJ+qpHfOUjWLYu1qwQR eNsXzS6K2axUtLb68WktjvT7iaFJz0H98VWUoRwb2kbJdOjeZ5Kw3emtnPmJg/1KYTtV/bxODo5 P7T6Vy2h17/IV0YZHt/0b/PbgLKcxYRRcSqpUq/ofXTcEkqkXMR0adGwbfV5h94e+JtpjNnNZ+v 6JUMNoaTp69lERg== 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 --- v3 -> v4: - 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 a51e95e3b717c..259920ae36843 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) { @@ -760,8 +716,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 Tue Aug 13 09:09:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 820048 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 9FBA817C21C for ; Tue, 13 Aug 2024 09:09:40 +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=1723540183; cv=none; b=hNGXPA11Ssox7H+o30BI50pmKI+qRFYfrs8H7kuDCTaa5PJkaGKxji5Svb4vdTSvR2qu79TiPSPlpYjU8ohp71Q7bEdLbnpfjlkJdCfbxCAlO9T3QuHtyZbMPqsiHs++N47+X4n6ehk8NZqKIWh7+8SwfleOSSC1zqVjNZJQJOc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723540183; c=relaxed/simple; bh=K7t59qAyTIATX7DJedngWZpU2GfYXp1lk2+YQczMvcs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lJohutGYMaY99wUKbN6mPGEIFd0fyMuIt4Y3+WtqyMqRD1R2QSia6CHieC70ivXFi0iGSdEzi65uIDQrJvVUT4VIQVqSGbklRm0iZ/bZ66nu3l2JcIlLr0CJCStFnClvUHfwRipdEUtfvki+EmtPijs2HUDNmg1YM9ungaJKDM4= 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 1sdnX4-0002CJ-SF; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-0005ok-6t; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-00G1eS-0L; Tue, 13 Aug 2024 11:09:34 +0200 From: Michael Grzeschik Date: Tue, 13 Aug 2024 11:09:30 +0200 Subject: [PATCH v4 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-v4-6-ca22f334226e@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@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=3153; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=K7t59qAyTIATX7DJedngWZpU2GfYXp1lk2+YQczMvcs=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmuyLMSrlkkD3TmD3KVN4id4mXSqJ0ko85jWmpD ju3uRie1kmJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZrsizAAKCRC/aVhE+XH0 qxKgD/95caa3oirK+foxJ4+2ywouWBfIcoI+7MQISTVMuAQg2k4FzEnnqOWMlqiJMn64dykoFQ3 +oDEqvCuLjNQ/2jcTyIHv1miQi6DnP/nWsuSm07AUiGENCVHjzmAH0fviSTANE7UTrfUFNif5Er yMGvi5gJGTPdDcpolhQfW741WB0j7sOG6M2JWgg9k6BuVtNlo7v4bgEaYm+MmeMnyrdtyJTrCgE X2fthPr1hBKjQfyTzs7tLzIu3LrViehMG/3fGipDfPac3Rr5tsN82X6b4hrR85EQNsveXfSH4KR irzb/LgzJw9ILX5vF7Gim2d0MeXcvSE0t6sAXLGcbh5lutbVxujSemm0TbTE1mL8buWwUzeUJ0b EdJ4VF/NoZuI6EOq25R06r//qDzldZ7P932Knz9Co2AAJeHV57JlWnErDGjrQoWRlUBoHumSbrP skrCPu485WTXPwpuIcx0h2dEaI4GkXn6STuPFd2/npj6kMhux+Wo/vIvaoqAVAlbp4Xh3vMDsjs z6kWgV1Kd7XYRr1p3Dar5QTz2jlru15BtXsICaEUnEDlcFNDpNB21qF+rga6/K1Ef4txoh9h8AV Oon9+7lVvIVj0eTHxtQyzivR+kUlFqhIZhAcT8g70PBt0/hRAp1S0+ftpj+PxNy6pIGx9k7OCAd QXq4qNbe38jwrUA== 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 --- v3 -> v4: - 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 259920ae36843..a6786beef91ad 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: @@ -663,7 +653,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 Tue Aug 13 09:09:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 820049 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 A1BC517C228 for ; Tue, 13 Aug 2024 09:09:40 +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=1723540183; cv=none; b=E2HOK30vsMonMlTP6QXVvZfIjrWxC0Ewupx+TZ4chT13WCXFPBlgVRPP2SmqW+gM8wxq6odMM4Qkmg7NGhRbwA5qPIg78MzBv/F0UyAmjS+M83JJuO06x8XM0r6jpEr39AtUpbgBI/wbcf7bF9OUGzI42o6vg9ioNa+6RrMMs4k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723540183; c=relaxed/simple; bh=vizf3BCyAp+bdXKWP0jZafipoaaeHSiEHekalxjIRoo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jvbWaMrz7LWRgrmE4C1rotgwLTasYmEmmuwPrvOI5CHXRyGgsADT174rgYbGy7Dc8WbkgVUcQZMKS5nIieWIKhBpB4B84gdn1K8dY1/W19XF+ZFIalAeSouC10lZVH+xhESMkngKm/MQc3Rt+u6JY2OsU7y2L+WZOVAcVPkVSEQ= 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 1sdnX4-0002CK-SD; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-0005ol-7Y; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-00G1eS-0M; Tue, 13 Aug 2024 11:09:34 +0200 From: Michael Grzeschik Date: Tue, 13 Aug 2024 11:09:31 +0200 Subject: [PATCH v4 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-v4-7-ca22f334226e@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@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=3322; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=vizf3BCyAp+bdXKWP0jZafipoaaeHSiEHekalxjIRoo=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmuyLMrP8JVi5j+/oarxSCs7BRCbEw40rPTDbJW hDhd9nVAlKJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZrsizAAKCRC/aVhE+XH0 q1KaD/0RRbEx7JWRzxxBm0Id1xfS3AM85j9AUDae3HZEg1CAKBaNuMUtMT024XMxFItAAjt82Z9 3+8mJDR+4Kal54CkQxiM2v8iCoCAULWzYAIQVy0T149ARF8WM5Hx/6vinNb++jiGUlP2YiZys4u dr7HMyfbVkOImjwxsAQjyIDkEDgtDt1BFZleRzBMYDXp3pK5BOUZ/hEvGP3p/nZlEuELFBqo4C7 EDoDFugC2aWQRl2/AEZyfFAT+iNzdPaj0oAmt0xfGCPBiSIwDrwmiAkVtY5TCLtCsG6EyF37VW4 GU7v3rqPa8ReYXIo5bX59zQHhxXq+BigxRI9o+cMqWo8shTmcqqPK5bNzBxxxuJ27JEmQyl0TGN NEnSzNkMNPiKxBuylyb047g6F0cz96VHTYelJ75FcDmXD9V+8qg2god8fUfMDYK3+46YMR6L/h4 7OolZxy7QHQTJcr9ICHSYMfRTNFFNi4oUVCmYDy1tJWJ5CcF/MJ9fbT5wSOaPA4HhaYL630QXMR ahBWKq8TBw2DCcZec5J216XcqrSDffqwFXRg4a9rF68jWhd1pKnJfYpXi+lX8wj+p3pVVVf5tKE BObjRm8HQwVIuVSIZTZP6wEX4oVF+3YTg4riMMFcKVFkD4/cCqYsDmGsIQhJH38oYMwW5QKALU3 086eIb27/yHbDtg== 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 --- v3 -> v4: - 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 Tue Aug 13 09:09:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 819078 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 A336817C235 for ; Tue, 13 Aug 2024 09:09:40 +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=1723540184; cv=none; b=mOoyP/n1Qv+G1KfYi+wHH7C5MI+y1e/U1XF6mL66i7sixLmaclzjUkNFzuvpLXOjz8HFHDRGna2QBTJ62lQSnMwLJ6k65V3g1jSgTGXvoKsSpt4gqyUl5MpdWCNMGl54qmqHqpG6bGA97TqQTsfELx44SHKfx4+ygq+TcBCehxk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723540184; c=relaxed/simple; bh=8l1+q6211Afpcbv3xFB7a1zxAwc7hRSt2YKTP95MoOc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YvVXZNlw71Y9uyEMgxdX4fn/XlJAXnP/AjRZAnE/IgDnBnWwQLn3Rm1j883YxJCmtVGcqL9Pr9iRwiwgtOOVavXFuIPp/Y7tH48OF5xTjrOR1mfKMW88JVlbhKe5JpMPiwoVrteHuMY0veM5JhmQkA0Ro9bDlyJkocT6kBZ5a10= 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 1sdnX4-0002CQ-SE; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-0005om-82; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-00G1eS-0N; Tue, 13 Aug 2024 11:09:34 +0200 From: Michael Grzeschik Date: Tue, 13 Aug 2024 11:09:32 +0200 Subject: [PATCH v4 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-v4-8-ca22f334226e@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@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=3520; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=8l1+q6211Afpcbv3xFB7a1zxAwc7hRSt2YKTP95MoOc=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmuyLNps9UYKxnwlGUb4uOd2KKGzvXbUavYapaF ancs9Mso2mJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZrsizQAKCRC/aVhE+XH0 q/MhD/sFGRhkhzYW059mkerJVbDVmNjG6/zlmugvLr7mUsBjKJFdESs8s/NLOlhtB6HvelkPHt5 NOMD27mQzDqMtsINsyGtYDNnPxuF28JF16Ti/btd3bXWSngZNrQ0c4PbYNohc4iw06eZa8kCv+r ohdf+tBZYcLzJgaW+IfIPqlGYDTTP+u3//r8F0/6y9Qrwc2OvVrO/f/Z8ctx3GoXadUcNFZIBKq ke+1bsUxdH2vb/Jb57bWGuJW6XLZlEuP3dTZVZPy3TFERBCl7koKT8VmYupS2hfVDmBbvwV3sez duu4V/46rlcM3VsPEmkn3SgvXiiVcfpcXjRYsRvu/iWdnrqhGrFzPVSndMbStm6go/6IDUJT6/3 Vt1TAevdb5QIJq/8MROzSFdMKDhv6wKT0A4bpzYHiXcaD3u/Yp5vVM4HoM8wQ4RyqdtjwFws1KF tq9RmvRPcXhxurst6M5qtqTdFZec8Ku9cp7E40YuZZuvFiTDe5QF96GV3rRU7gUe2+9g+R6Msoa 3+N8bPiOAcMbgiwNUwg6LmXO7P3nGmx7cJZqZJWjNDc6+pqMWYcwTmET6TR+0gSfdbx0si3Dw0j UloLhaitXoSQTMzvNKI45mCTWPO1YrsryiIW/ILKl5Zq4lg9ecaagJc3LCrTeQN9QM91boUw8YA nx1z1M0DgK6CnKw== 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 --- 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 | 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 a6786beef91ad..fe19608b57720 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 Tue Aug 13 09:09:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 819080 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 677DD17BB19 for ; Tue, 13 Aug 2024 09:09:40 +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=1723540183; cv=none; b=hC47SoWBpEbJjKQukNYvjwJfvcvAMHdmB6teo6WnFWYJK88AWzGBGIebK0v0NAwQZyTpI1eu507dMbUYF4TcNnuLP+UcURkj3Bppf12Y3NsZ/INS0y9f6L/rKVzEkVI/H6hR+ZcvXME8FK8UjhdsrFW6UHlEHgRjp22WufAv/Z0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723540183; c=relaxed/simple; bh=pR9Q1xJIQp6r4a68/d9PCSwj+85Vq81NrZV56hszM7Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nbR7IS5nV+xMxTbf9mwbY5lcAHcJz2jSVWF0g0BnNtJqf66PfYJARpcyheKrsIJHs+CkCX/hqgE7ZRHf2+pTiwK2rUmlF6vLJgUqCiDou0aK42hmbnen9Q1WsAdnyUuXLNCtBoAHpYxvwMU6vhZQFmhQDgJMaVvKpt0apWc9JJA= 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 1sdnX4-0002CP-SF; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-0005on-83; Tue, 13 Aug 2024 11:09:34 +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 1sdnX4-00G1eS-0O; Tue, 13 Aug 2024 11:09:34 +0200 From: Michael Grzeschik Date: Tue, 13 Aug 2024 11:09:33 +0200 Subject: [PATCH v4 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-v4-9-ca22f334226e@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@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=4214; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=pR9Q1xJIQp6r4a68/d9PCSwj+85Vq81NrZV56hszM7Q=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmuyLN797r8Eswpj0toyqDidEtNCqQT+lBsIcH7 eNMTNImexmJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZrsizQAKCRC/aVhE+XH0 q57yEACSN4eXjVOdmtSeMKQSkLpt2z6CiLpauhPyFSwisNfdzhM2T0M+wjNlfEKuzI5Ju7F+7br FYAhiSI1OfO1jK5+D4GvgzIQOhktKjBjHGB1NtDDpFslBHTCRToI4hnCvBxfEG5aSHucgGXs73s 0RyqLfFFe9r4EyW8SKtGyE5DrzLyqgyXGY4tHr8teRKvUZkglzVY0PcMvwQA+bxRTiwN8R3p9Jc PAjH2bBYFNAgwQwxTSZZXHJwETn5TxmyE6EwRthkEYXQ4eDmEGuvZJ16UsjUABEX6zhZYLvBo9i Dn2Vg9pfhMJkMRN2m/c/LPtkKZ4skAHEyOi+usIhohP+m8F1i9W+kH638Lf/21hxeJqHkrvvs73 r9bzSMH1eY1Nyxg6tNPa/WKUdmKgFisLHrKxO/usFJyadtfStTXeM06gPJAQKtxef5QhJAQe5lo r+GqRgKgxoTKbFjZAKUFiA6EtHq9dRBJoybu21cUVDiscaeKz4zGyHFLc9nN5p0Wc50EXYH4gaC LJpr/xDNRvril3F9I843muw/QBvSQKZRePKCM+a9fgufz/BJLgXitjvV7NleKkMak0hNIfr7jSE jO2+py3l37K+hl2Uv2fsgEY2CDK99mQqoPlw7e+WJTVvjnYNYEvjj25xZ3jhu1B/nHmNsbouhjB q1RTjlSfRPKb+lQ== 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 --- v3 -> v4: - 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 fe19608b57720..a5cf4dbdc5d59 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 Tue Aug 13 09:09:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Grzeschik X-Patchwork-Id: 820047 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 82E9F17E44F for ; Tue, 13 Aug 2024 09:34:33 +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=1723541675; cv=none; b=VZo/hbnp/MKJdTahH7NE2UGZfzgPQ1dhgCm4jOzg4xSDlavX2FXdR07WQzkM+e7eJcUGvb9sLT5qIGjkDJG/D3dT5uwNNDlyRmTuQhb29nsA7wmePg2BBRyzlKQIpHWx8qp5o95TrzEbQNd5QFzO8dTXEntKpaV60hSzd9CNhNw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723541675; c=relaxed/simple; bh=rj9b7K0Nbm9lGAMTKb9Y09pi8U+HR6hJCCBIdBSG5FA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JxsEpQd/JynXk+li/NwBZvRZ+VCXBwkW6hLXNEVM/wcXM/mVpw6a2aISwHTa8M1b4Sx2IBapc6+mVy2xXuN4aVSML2CqjL4AXRRoSDhtzYXnr/ZBMAwo19dVRzPfu78WdI/+g6VbTmYwo8C3KCPwcN2irad8XwKBxwEodzpLNJg= 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 1sdnv9-0004A5-UD; Tue, 13 Aug 2024 11:34:27 +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 1sdnv9-0005yY-FB; Tue, 13 Aug 2024 11:34:27 +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 1sdnX4-00G1eS-0P; Tue, 13 Aug 2024 11:09:34 +0200 From: Michael Grzeschik Date: Tue, 13 Aug 2024 11:09:34 +0200 Subject: [PATCH v4 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-v4-10-ca22f334226e@pengutronix.de> References: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@pengutronix.de> In-Reply-To: <20240403-uvc_request_length_by_interval-v4-0-ca22f334226e@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=2804; i=m.grzeschik@pengutronix.de; h=from:subject:message-id; bh=rj9b7K0Nbm9lGAMTKb9Y09pi8U+HR6hJCCBIdBSG5FA=; b=owEBbQKS/ZANAwAKAb9pWET5cfSrAcsmYgBmuyLNqZfMBw7L5B5aKx0UULdgxEbrn+BT9FeHo wBP/cH2TNaJAjMEAAEKAB0WIQQV2+2Fpbqd6fvv0Gi/aVhE+XH0qwUCZrsizQAKCRC/aVhE+XH0 qz7CD/9FEpRSh8VyQlqZG6f1NIn9XdkLGB2o/hBgZDugNSIMCWZJhIOEZMSqdxsTnZ5LlzmRuIE p/KhrHeVrt4OeRolSnxjTrlfDUfBnvKwyRO/5gnQ+QLnHrmu28Jtnn1CQTpT+uPR45ovjiXCJdA JhnqDZBkp1DyDJi3ZBWHvgxIgfYV5LB1TsYD2TCNIEZ0B1IPac4TgXLtqhYpeme3RRaw4XZ0vXl U//AvkY2mJh0Ncb6jA9ZWMlhs2W/+7kPfXBaDmlD8Be0kAFThNTh3R2311vdOLwQbNfvrK+iMie pRpFRc2RCrJP4swbxxLabEugCxY1CcALGgD7memCCXXCH1JH9d2Wdhe1ijzIM7xKt7+a1iN4fYS wWYX7cpVSC3O8TxwFjfTJ8wX2Rh2CYQLtmwxlEj/BSbZ3mRCD5HaXVeEkMroNPuD4cTWp9VKU7L Sj/d7JNSQI3JTXISiQ4nPWoQGrn6g2xxhzWA8VyeHl57RIQphzNebcTEm6YCkPXu23YuagvuVBr APCXKLlMqATZqIrKnXj9Cbr9nbQPzXyo+lzwa3dYQcxAscQ9orEidZWz+oQthFNRHHNSw53wl/I MgVhk+8sbXK2OojoCXoBQosU/ZqJnS3VzGfLbUCNI6Y1bLwR7OKTwcMErVVfcIdXZ+ZddB3X2ui IwmsKPnwgcLNevA== 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 --- v3 -> v4: - 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,