media: vivid: fix (partially) timing issues
authorHans Verkuil <hverkuil-cisco@xs4all.nl>
Fri, 2 Oct 2020 14:48:03 +0000 (16:48 +0200)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Mon, 16 Nov 2020 09:31:08 +0000 (10:31 +0100)
The vivid driver is a bit flaky w.r.t. the kthread timing, esp. when
running inside a virtual machine.

This is caused by calling schedule_timeout_uninterruptible(1) which can
actually take more than one jiffie. A while loop with schedule() turns out
to be a lot more precise. Also, if mutex_trylock() fails, then just call
schedule() instead of schedule_timeout_uninterruptible(1). There is no need
to wait until the next jiffer, just schedule(), then try to get the lock
again.

This is still not precise enough, it is still relatively easy to get missed
frames. This really should be converted to use a proper timer, but for now
this solves the worst problems.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/media/test-drivers/vivid/vivid-kthread-cap.c
drivers/media/test-drivers/vivid/vivid-kthread-out.c
drivers/media/test-drivers/vivid/vivid-kthread-touch.c
drivers/media/test-drivers/vivid/vivid-sdr-cap.c

index 01a9d671b9477a417815e2ceeb491496c405006f..67fb3c00f9ad5f8ef3e7ac205af1e72ff60e14f5 100644 (file)
@@ -819,7 +819,7 @@ static int vivid_thread_vid_cap(void *data)
                        break;
 
                if (!mutex_trylock(&dev->mutex)) {
-                       schedule_timeout_uninterruptible(1);
+                       schedule();
                        continue;
                }
 
@@ -888,7 +888,9 @@ static int vivid_thread_vid_cap(void *data)
                        next_jiffies_since_start = jiffies_since_start;
 
                wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-               schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+               while (jiffies - cur_jiffies < wait_jiffies &&
+                      !kthread_should_stop())
+                       schedule();
        }
        dprintk(dev, 1, "Video Capture Thread End\n");
        return 0;
index 6780687978f933214b20ab0f6f5a7dce5d44a8cf..79c57d14ac4e4710661fc274511e65e3a2c92a3a 100644 (file)
@@ -167,7 +167,7 @@ static int vivid_thread_vid_out(void *data)
                        break;
 
                if (!mutex_trylock(&dev->mutex)) {
-                       schedule_timeout_uninterruptible(1);
+                       schedule();
                        continue;
                }
 
@@ -233,7 +233,9 @@ static int vivid_thread_vid_out(void *data)
                        next_jiffies_since_start = jiffies_since_start;
 
                wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-               schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+               while (jiffies - cur_jiffies < wait_jiffies &&
+                      !kthread_should_stop())
+                       schedule();
        }
        dprintk(dev, 1, "Video Output Thread End\n");
        return 0;
index 674507b5ccb52f1e08094b2c375f14ef21b9b478..38fdfee794986add40261960436ea7440fe90d2d 100644 (file)
@@ -69,7 +69,7 @@ static int vivid_thread_touch_cap(void *data)
                        break;
 
                if (!mutex_trylock(&dev->mutex)) {
-                       schedule_timeout_uninterruptible(1);
+                       schedule();
                        continue;
                }
                cur_jiffies = jiffies;
@@ -128,7 +128,9 @@ static int vivid_thread_touch_cap(void *data)
                        next_jiffies_since_start = jiffies_since_start;
 
                wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-               schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+               while (jiffies - cur_jiffies < wait_jiffies &&
+                      !kthread_should_stop())
+                       schedule();
        }
        dprintk(dev, 1, "Touch Capture Thread End\n");
        return 0;
index 2b7522e16efcda176ac0097db38770f0c052cb82..a1e52708b7caee12124bad97baa9d179fb03f6cd 100644 (file)
@@ -142,7 +142,7 @@ static int vivid_thread_sdr_cap(void *data)
                        break;
 
                if (!mutex_trylock(&dev->mutex)) {
-                       schedule_timeout_uninterruptible(1);
+                       schedule();
                        continue;
                }
 
@@ -201,7 +201,9 @@ static int vivid_thread_sdr_cap(void *data)
                        next_jiffies_since_start = jiffies_since_start;
 
                wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-               schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+               while (jiffies - cur_jiffies < wait_jiffies &&
+                      !kthread_should_stop())
+                       schedule();
        }
        dprintk(dev, 1, "SDR Capture Thread End\n");
        return 0;