This is an automatic generated email to let you know that the following patch 
were queued:

Subject: media: hdpvr: fix locking and a missing msleep
Author:  Hans Verkuil <[email protected]>
Date:    Thu Jun 20 07:43:41 2019 -0400

This driver has three locking issues:

- The wait_event_interruptible() condition calls hdpvr_get_next_buffer(dev)
  which uses a mutex, which is not allowed. Rewrite with list_empty_careful()
  that doesn't need locking.

- In hdpvr_read() the call to hdpvr_stop_streaming() didn't lock io_mutex,
  but it should have since stop_streaming expects that.

- In hdpvr_device_release() io_mutex was locked when calling flush_work(),
  but there it shouldn't take that mutex since the work done by flush_work()
  also wants to lock that mutex.

There are also two other changes (suggested by Keith):

- msecs_to_jiffies(4000); (a NOP) should have been msleep(4000).
- Change v4l2_dbg to v4l2_info to always log if streaming had to be restarted.

Reported-by: Keith Pyle <[email protected]>
Suggested-by: Keith Pyle <[email protected]>
Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>

 drivers/media/usb/hdpvr/hdpvr-video.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

---

diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c 
b/drivers/media/usb/hdpvr/hdpvr-video.c
index 3786ddcc0d18..5b3e67b80627 100644
--- a/drivers/media/usb/hdpvr/hdpvr-video.c
+++ b/drivers/media/usb/hdpvr/hdpvr-video.c
@@ -435,7 +435,7 @@ static ssize_t hdpvr_read(struct file *file, char __user 
*buffer, size_t count,
        /* wait for the first buffer */
        if (!(file->f_flags & O_NONBLOCK)) {
                if (wait_event_interruptible(dev->wait_data,
-                                            hdpvr_get_next_buffer(dev)))
+                                            
!list_empty_careful(&dev->rec_buff_list)))
                        return -ERESTARTSYS;
        }
 
@@ -461,10 +461,17 @@ static ssize_t hdpvr_read(struct file *file, char __user 
*buffer, size_t count,
                                goto err;
                        }
                        if (!err) {
-                               v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
-                                       "timeout: restart streaming\n");
+                               v4l2_info(&dev->v4l2_dev,
+                                         "timeout: restart streaming\n");
+                               mutex_lock(&dev->io_mutex);
                                hdpvr_stop_streaming(dev);
-                               msecs_to_jiffies(4000);
+                               mutex_unlock(&dev->io_mutex);
+                               /*
+                                * The FW needs about 4 seconds after streaming
+                                * stopped before it is ready to restart
+                                * streaming.
+                                */
+                               msleep(4000);
                                err = hdpvr_start_streaming(dev);
                                if (err) {
                                        ret = err;
@@ -1124,9 +1131,7 @@ static void hdpvr_device_release(struct video_device 
*vdev)
        struct hdpvr_device *dev = video_get_drvdata(vdev);
 
        hdpvr_delete(dev);
-       mutex_lock(&dev->io_mutex);
        flush_work(&dev->worker);
-       mutex_unlock(&dev->io_mutex);
 
        v4l2_device_unregister(&dev->v4l2_dev);
        v4l2_ctrl_handler_free(&dev->hdl);

_______________________________________________
linuxtv-commits mailing list
[email protected]
https://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to