[PATCH v3 5/5] usb: gadget: uvc: decrease the interrupt load to a quarter
From: Michael Grzeschik <hidden>
Date: 2021-06-28 15:55:43
Subsystem:
the rest, usb subsystem, usb webcam gadget · Maintainers:
Linus Torvalds, Greg Kroah-Hartman
With usb3 we handle many more requests. Decrease the interrupt load by only enabling the interrupt every quarter of the allocated requests. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Michael Grzeschik <redacted> -- v1 -> v2: - edited patch description - removed extra parantheses - added a comment for the logic - using unsigned int instead of int - reinitializing req_int_count in uvcg_video_enable v2 -> v3: - --- drivers/usb/gadget/function/uvc.h | 2 ++ drivers/usb/gadget/function/uvc_video.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+)
diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h
index 36b78f8b3cd4c..255a61bd6a6a8 100644
--- a/drivers/usb/gadget/function/uvc.h
+++ b/drivers/usb/gadget/function/uvc.h@@ -101,6 +101,8 @@ struct uvc_video { struct list_head req_free; spinlock_t req_lock; + unsigned int req_int_count; + void (*encode) (struct usb_request *req, struct uvc_video *video, struct uvc_buffer *buf);
diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
index 2cefb8bd4f15b..b4a763e5f70e1 100644
--- a/drivers/usb/gadget/function/uvc_video.c
+++ b/drivers/usb/gadget/function/uvc_video.c@@ -360,6 +360,19 @@ static void uvcg_video_pump(struct work_struct *work) 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 || + !(video->req_int_count % + DIV_ROUND_UP(video->uvc_num_requests, 4))) { + video->req_int_count = 0; + req->no_interrupt = 0; + } else { + req->no_interrupt = 1; + } + /* Queue the USB request */ ret = uvcg_video_ep_queue(video, req); spin_unlock_irqrestore(&queue->irqlock, flags);
@@ -368,6 +381,7 @@ static void uvcg_video_pump(struct work_struct *work) uvcg_queue_cancel(queue, 0); break; } + video->req_int_count++; } spin_lock_irqsave(&video->req_lock, flags);
@@ -416,6 +430,8 @@ int uvcg_video_enable(struct uvc_video *video, int enable) video->encode = video->queue.use_sg ? uvc_video_encode_isoc_sg : uvc_video_encode_isoc; + video->req_int_count = 0; + schedule_work(&video->pump); return ret;
--
2.30.2