diff mbox series

[1/3] usb: gadget: uvc: stop pump thread on video disable

Message ID 20230911002451.2860049-2-m.grzeschik@pengutronix.de (mailing list archive)
State Superseded
Headers show
Series usb: gadget: uvc: restart fixes | expand

Commit Message

Michael Grzeschik Sept. 11, 2023, 12:24 a.m. UTC
Since the uvc-video gadget driver is using the v4l2 interface,
the streamon and streamoff can be triggered at any times. To ensure
that the pump worker will be closed as soon the userspace is
calling streamoff we synchronize the state of the gadget ensuring
the pump worker to bail out.

Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
 drivers/usb/gadget/function/uvc_video.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

kernel test robot Sept. 11, 2023, 4:35 a.m. UTC | #1
Hi Michael,

kernel test robot noticed the following build errors:

[auto build test ERROR on usb/usb-testing]
[also build test ERROR on usb/usb-next usb/usb-linus westeri-thunderbolt/next media-tree/master linus/master v6.6-rc1 next-20230911]
[cannot apply to sailus-media-tree/streams]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Michael-Grzeschik/usb-gadget-uvc-stop-pump-thread-on-video-disable/20230911-082623
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
patch link:    https://lore.kernel.org/r/20230911002451.2860049-2-m.grzeschik%40pengutronix.de
patch subject: [PATCH 1/3] usb: gadget: uvc: stop pump thread on video disable
config: x86_64-randconfig-005-20230911 (https://download.01.org/0day-ci/archive/20230911/202309111200.k58A3yiK-lkp@intel.com/config)
compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230911/202309111200.k58A3yiK-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202309111200.k58A3yiK-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/usb/gadget/function/uvc_video.c:502:3: error: use of undeclared identifier 'uvc'
                   uvc->state = UVC_STATE_CONNECTED;
                   ^
   drivers/usb/gadget/function/uvc_video.c:529:2: error: use of undeclared identifier 'uvc'
           uvc->state = UVC_STATE_STREAMING;
           ^
   2 errors generated.


vim +/uvc +502 drivers/usb/gadget/function/uvc_video.c

   486	
   487	/*
   488	 * Enable or disable the video stream.
   489	 */
   490	int uvcg_video_enable(struct uvc_video *video, int enable)
   491	{
   492		unsigned int i;
   493		int ret;
   494	
   495		if (video->ep == NULL) {
   496			uvcg_info(&video->uvc->func,
   497				  "Video enable failed, device is uninitialized.\n");
   498			return -ENODEV;
   499		}
   500	
   501		if (!enable) {
 > 502			uvc->state = UVC_STATE_CONNECTED;
   503	
   504			cancel_work_sync(&video->pump);
   505			uvcg_queue_cancel(&video->queue, 0);
   506	
   507			for (i = 0; i < video->uvc_num_requests; ++i)
   508				if (video->ureq && video->ureq[i].req)
   509					usb_ep_dequeue(video->ep, video->ureq[i].req);
   510	
   511			uvc_video_free_requests(video);
   512			uvcg_queue_enable(&video->queue, 0);
   513			return 0;
   514		}
   515	
   516		if ((ret = uvcg_queue_enable(&video->queue, 1)) < 0)
   517			return ret;
   518	
   519		if ((ret = uvc_video_alloc_requests(video)) < 0)
   520			return ret;
   521	
   522		if (video->max_payload_size) {
   523			video->encode = uvc_video_encode_bulk;
   524			video->payload_size = 0;
   525		} else
   526			video->encode = video->queue.use_sg ?
   527				uvc_video_encode_isoc_sg : uvc_video_encode_isoc;
   528	
   529		uvc->state = UVC_STATE_STREAMING;
   530	
   531		video->req_int_count = 0;
   532	
   533		queue_work(video->async_wq, &video->pump);
   534	
   535		return ret;
   536	}
   537
kernel test robot Sept. 11, 2023, 8:05 a.m. UTC | #2
Hi Michael,

kernel test robot noticed the following build errors:

[auto build test ERROR on usb/usb-testing]
[also build test ERROR on usb/usb-next usb/usb-linus westeri-thunderbolt/next media-tree/master linus/master v6.6-rc1 next-20230911]
[cannot apply to sailus-media-tree/streams]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Michael-Grzeschik/usb-gadget-uvc-stop-pump-thread-on-video-disable/20230911-082623
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
patch link:    https://lore.kernel.org/r/20230911002451.2860049-2-m.grzeschik%40pengutronix.de
patch subject: [PATCH 1/3] usb: gadget: uvc: stop pump thread on video disable
config: alpha-allyesconfig (https://download.01.org/0day-ci/archive/20230911/202309111506.64B9KHI7-lkp@intel.com/config)
compiler: alpha-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230911/202309111506.64B9KHI7-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202309111506.64B9KHI7-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/usb/gadget/function/uvc_video.c: In function 'uvcg_video_enable':
>> drivers/usb/gadget/function/uvc_video.c:502:17: error: 'uvc' undeclared (first use in this function)
     502 |                 uvc->state = UVC_STATE_CONNECTED;
         |                 ^~~
   drivers/usb/gadget/function/uvc_video.c:502:17: note: each undeclared identifier is reported only once for each function it appears in


vim +/uvc +502 drivers/usb/gadget/function/uvc_video.c

   486	
   487	/*
   488	 * Enable or disable the video stream.
   489	 */
   490	int uvcg_video_enable(struct uvc_video *video, int enable)
   491	{
   492		unsigned int i;
   493		int ret;
   494	
   495		if (video->ep == NULL) {
   496			uvcg_info(&video->uvc->func,
   497				  "Video enable failed, device is uninitialized.\n");
   498			return -ENODEV;
   499		}
   500	
   501		if (!enable) {
 > 502			uvc->state = UVC_STATE_CONNECTED;
   503	
   504			cancel_work_sync(&video->pump);
   505			uvcg_queue_cancel(&video->queue, 0);
   506	
   507			for (i = 0; i < video->uvc_num_requests; ++i)
   508				if (video->ureq && video->ureq[i].req)
   509					usb_ep_dequeue(video->ep, video->ureq[i].req);
   510	
   511			uvc_video_free_requests(video);
   512			uvcg_queue_enable(&video->queue, 0);
   513			return 0;
   514		}
   515	
   516		if ((ret = uvcg_queue_enable(&video->queue, 1)) < 0)
   517			return ret;
   518	
   519		if ((ret = uvc_video_alloc_requests(video)) < 0)
   520			return ret;
   521	
   522		if (video->max_payload_size) {
   523			video->encode = uvc_video_encode_bulk;
   524			video->payload_size = 0;
   525		} else
   526			video->encode = video->queue.use_sg ?
   527				uvc_video_encode_isoc_sg : uvc_video_encode_isoc;
   528	
   529		uvc->state = UVC_STATE_STREAMING;
   530	
   531		video->req_int_count = 0;
   532	
   533		queue_work(video->async_wq, &video->pump);
   534	
   535		return ret;
   536	}
   537
diff mbox series

Patch

diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
index 91af3b1ef0d412..4b6e854e30c58c 100644
--- a/drivers/usb/gadget/function/uvc_video.c
+++ b/drivers/usb/gadget/function/uvc_video.c
@@ -384,13 +384,14 @@  static void uvcg_video_pump(struct work_struct *work)
 	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 uvc_device *uvc = video->uvc;
 	struct usb_request *req = NULL;
 	struct uvc_buffer *buf;
 	unsigned long flags;
 	bool buf_done;
 	int ret;
 
-	while (video->ep->enabled) {
+	while (video->ep->enabled && uvc->state == UVC_STATE_STREAMING) {
 		/*
 		 * Retrieve the first available USB request, protected by the
 		 * request lock.
@@ -498,6 +499,8 @@  int uvcg_video_enable(struct uvc_video *video, int enable)
 	}
 
 	if (!enable) {
+		uvc->state = UVC_STATE_CONNECTED;
+
 		cancel_work_sync(&video->pump);
 		uvcg_queue_cancel(&video->queue, 0);
 
@@ -523,6 +526,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;
 
+	uvc->state = UVC_STATE_STREAMING;
+
 	video->req_int_count = 0;
 
 	queue_work(video->async_wq, &video->pump);