From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Avichal Rakesh <arakesh@google.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Sasha Levin <sashal@kernel.org>,
laurent.pinchart@ideasonboard.com, balbi@kernel.org,
linux-usb@vger.kernel.org
Subject: [PATCH AUTOSEL 6.4 06/40] usb: gadget: uvc: queue empty isoc requests if no video buffer is available
Date: Sun, 23 Jul 2023 21:31:06 -0400 [thread overview]
Message-ID: <20230724013140.2327815-6-sashal@kernel.org> (raw)
In-Reply-To: <20230724013140.2327815-1-sashal@kernel.org>
From: Avichal Rakesh <arakesh@google.com>
[ Upstream commit c3ff12a92bd7072170978b8b41c2fa41b038139a ]
ISOC transfers expect a certain cadence of requests being queued. Not
keeping up with the expected rate of requests results in missed ISOC
transfers (EXDEV). The application layer may or may not produce video
frames to match this expectation, so uvc gadget driver must handle cases
where the application is not queuing up buffers fast enough to fulfill
ISOC requirements.
Currently, uvc gadget driver waits for new video buffer to become available
before queuing up usb requests. With this patch the gadget driver queues up
0 length usb requests whenever there are no video buffers available. The
USB controller's complete callback is used as the limiter for how quickly
the 0 length packets will be queued. Video buffers are still queued as
soon as they become available.
Link: https://lore.kernel.org/CAMHf4WKbi6KBPQztj9FA4kPvESc1fVKrC8G73-cs6tTeQby9=w@mail.gmail.com/
Signed-off-by: Avichal Rakesh <arakesh@google.com>
Link: https://lore.kernel.org/r/20230508231103.1621375-1-arakesh@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/uvc_video.c | 32 ++++++++++++++++++-------
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
index dd1c6b2ca7c6f..e81865978299c 100644
--- a/drivers/usb/gadget/function/uvc_video.c
+++ b/drivers/usb/gadget/function/uvc_video.c
@@ -386,6 +386,9 @@ static void uvcg_video_pump(struct work_struct *work)
struct uvc_buffer *buf;
unsigned long flags;
int ret;
+ bool buf_int;
+ /* video->max_payload_size is only set when using bulk transfer */
+ bool is_bulk = video->max_payload_size;
while (video->ep->enabled) {
/*
@@ -408,20 +411,35 @@ static void uvcg_video_pump(struct work_struct *work)
*/
spin_lock_irqsave(&queue->irqlock, flags);
buf = uvcg_queue_head(queue);
- if (buf == NULL) {
+
+ if (buf != NULL) {
+ video->encode(req, video, buf);
+ /* Always interrupt for the last request of a video buffer */
+ buf_int = buf->state == UVC_BUF_STATE_DONE;
+ } else if (!(queue->flags & UVC_QUEUE_DISCONNECTED) && !is_bulk) {
+ /*
+ * No video buffer available; the queue is still connected and
+ * we're traferring over ISOC. Queue a 0 length request to
+ * prevent missed ISOC transfers.
+ */
+ req->length = 0;
+ buf_int = false;
+ } else {
+ /*
+ * Either queue has been disconnected or no video buffer
+ * available to bulk transfer. Either way, stop processing
+ * further.
+ */
spin_unlock_irqrestore(&queue->irqlock, flags);
break;
}
- video->encode(req, video, buf);
-
/*
* With usb3 we have more requests. This will decrease the
* interrupt load to a quarter but also catches the corner
* cases, which needs to be handled.
*/
- if (list_empty(&video->req_free) ||
- buf->state == UVC_BUF_STATE_DONE ||
+ if (list_empty(&video->req_free) || buf_int ||
!(video->req_int_count %
DIV_ROUND_UP(video->uvc_num_requests, 4))) {
video->req_int_count = 0;
@@ -441,8 +459,7 @@ static void uvcg_video_pump(struct work_struct *work)
/* Endpoint now owns the request */
req = NULL;
- if (buf->state != UVC_BUF_STATE_DONE)
- video->req_int_count++;
+ video->req_int_count++;
}
if (!req)
@@ -527,4 +544,3 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc)
V4L2_BUF_TYPE_VIDEO_OUTPUT, &video->mutex);
return 0;
}
-
--
2.39.2
next prev parent reply other threads:[~2023-07-24 1:37 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20230724013140.2327815-1-sashal@kernel.org>
2023-07-24 1:31 ` [PATCH AUTOSEL 6.4 05/40] usb: gadget: u_serial: Avoid spinlock recursion in __gs_console_push Sasha Levin
2023-07-24 1:31 ` Sasha Levin [this message]
2023-07-24 1:31 ` [PATCH AUTOSEL 6.4 09/40] xhci: Don't require a valid get_quirks() function pointer during xhci setup Sasha Levin
2023-07-24 1:31 ` [PATCH AUTOSEL 6.4 10/40] xhci: get rid of XHCI_PLAT quirk that used to prevent MSI setup Sasha Levin
2023-07-24 1:31 ` [PATCH AUTOSEL 6.4 11/40] usb: chipidea: imx: don't request QoS for imx8ulp Sasha Levin
2023-07-24 1:31 ` [PATCH AUTOSEL 6.4 12/40] usb: cdns2: Device side header file for CDNS2 driver Sasha Levin
2023-07-24 4:09 ` Greg Kroah-Hartman
2023-07-24 1:31 ` [PATCH AUTOSEL 6.4 13/40] usb: chipidea: imx: turn off vbus comparator when suspend Sasha Levin
2023-07-24 1:31 ` [PATCH AUTOSEL 6.4 14/40] usb: chipidea: imx: add missing USB PHY DPDM wakeup setting Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230724013140.2327815-6-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=arakesh@google.com \
--cc=balbi@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).