Commit 6e8c09bb authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

media: vivid: fix (partially) timing issues

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: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 5e3a81d4
...@@ -819,7 +819,7 @@ static int vivid_thread_vid_cap(void *data) ...@@ -819,7 +819,7 @@ static int vivid_thread_vid_cap(void *data)
break; break;
if (!mutex_trylock(&dev->mutex)) { if (!mutex_trylock(&dev->mutex)) {
schedule_timeout_uninterruptible(1); schedule();
continue; continue;
} }
...@@ -888,7 +888,9 @@ static int vivid_thread_vid_cap(void *data) ...@@ -888,7 +888,9 @@ static int vivid_thread_vid_cap(void *data)
next_jiffies_since_start = jiffies_since_start; next_jiffies_since_start = jiffies_since_start;
wait_jiffies = 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"); dprintk(dev, 1, "Video Capture Thread End\n");
return 0; return 0;
......
...@@ -167,7 +167,7 @@ static int vivid_thread_vid_out(void *data) ...@@ -167,7 +167,7 @@ static int vivid_thread_vid_out(void *data)
break; break;
if (!mutex_trylock(&dev->mutex)) { if (!mutex_trylock(&dev->mutex)) {
schedule_timeout_uninterruptible(1); schedule();
continue; continue;
} }
...@@ -233,7 +233,9 @@ static int vivid_thread_vid_out(void *data) ...@@ -233,7 +233,9 @@ static int vivid_thread_vid_out(void *data)
next_jiffies_since_start = jiffies_since_start; next_jiffies_since_start = jiffies_since_start;
wait_jiffies = 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"); dprintk(dev, 1, "Video Output Thread End\n");
return 0; return 0;
......
...@@ -69,7 +69,7 @@ static int vivid_thread_touch_cap(void *data) ...@@ -69,7 +69,7 @@ static int vivid_thread_touch_cap(void *data)
break; break;
if (!mutex_trylock(&dev->mutex)) { if (!mutex_trylock(&dev->mutex)) {
schedule_timeout_uninterruptible(1); schedule();
continue; continue;
} }
cur_jiffies = jiffies; cur_jiffies = jiffies;
...@@ -128,7 +128,9 @@ static int vivid_thread_touch_cap(void *data) ...@@ -128,7 +128,9 @@ static int vivid_thread_touch_cap(void *data)
next_jiffies_since_start = jiffies_since_start; next_jiffies_since_start = jiffies_since_start;
wait_jiffies = 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"); dprintk(dev, 1, "Touch Capture Thread End\n");
return 0; return 0;
......
...@@ -142,7 +142,7 @@ static int vivid_thread_sdr_cap(void *data) ...@@ -142,7 +142,7 @@ static int vivid_thread_sdr_cap(void *data)
break; break;
if (!mutex_trylock(&dev->mutex)) { if (!mutex_trylock(&dev->mutex)) {
schedule_timeout_uninterruptible(1); schedule();
continue; continue;
} }
...@@ -201,7 +201,9 @@ static int vivid_thread_sdr_cap(void *data) ...@@ -201,7 +201,9 @@ static int vivid_thread_sdr_cap(void *data)
next_jiffies_since_start = jiffies_since_start; next_jiffies_since_start = jiffies_since_start;
wait_jiffies = 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"); dprintk(dev, 1, "SDR Capture Thread End\n");
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment