mirror of https://gitee.com/openkylin/linux.git
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: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
parent
5e3a81d42e
commit
6e8c09bb8d
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue