You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
3.7 KiB
116 lines
3.7 KiB
From e97b4ddf1ef9881560bc60f196adc840cc9de3f4 Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
From: Evgeni Raikhel <evgeni.raikhel@intel.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Reported-by: syzbot+736c3aae4af7b50d9683@syzkaller.appspotmail.com
|
|
Date: Sun, 3 Nov 2019 12:41:09 +0200
|
|
Subject: [PATCH] Backporting hotfix patch
|
|
https://patchwork.kernel.org/patch/11095737/
|
|
|
|
The patch is a backporting of Hans Verkuil proposal to circumvent
|
|
video buffer de/allocation sync issues by preventing buffers queue operation
|
|
during v4l2_streamoff. Without the patch during streamoff operation
|
|
the buffers queue continues to change that results
|
|
https://patchwork.kernel.org/patch/11095737/
|
|
|
|
---
|
|
drivers/media/v4l2-core/videobuf2-core.c | 30 ++++++++++++++++++++++++
|
|
include/media/videobuf2-core.h | 1 +
|
|
2 files changed, 31 insertions(+)
|
|
|
|
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
|
|
index 8ce9c63dfc59..09a653dd83a6 100644
|
|
--- a/drivers/media/v4l2-core/videobuf2-core.c
|
|
+++ b/drivers/media/v4l2-core/videobuf2-core.c
|
|
@@ -581,6 +581,11 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
|
|
return -EBUSY;
|
|
}
|
|
|
|
+ if (q->in_stop_streaming) {
|
|
+ dprintk(1, "reqbufs while the stream is being stopped\n");
|
|
+ return -EBUSY;
|
|
+ }
|
|
+
|
|
if (*count == 0 || q->num_buffers != 0 || q->memory != memory) {
|
|
/*
|
|
* We already have buffers allocated, so first check if they
|
|
@@ -1363,6 +1368,11 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb)
|
|
struct vb2_buffer *vb;
|
|
int ret;
|
|
|
|
+ if (q->in_stop_streaming) {
|
|
+ dprintk(1, "qbuf while the stream is being stopped\n");
|
|
+ return -EBUSY;
|
|
+ }
|
|
+
|
|
if (q->error) {
|
|
dprintk(1, "fatal error occurred on queue\n");
|
|
return -EIO;
|
|
@@ -1454,6 +1464,11 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ if (q->in_stop_streaming) {
|
|
+ dprintk(1, "the stream is being stopped, will not wait for buffers\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
if (q->error) {
|
|
dprintk(1, "Queue in error state, will not wait for buffers\n");
|
|
return -EIO;
|
|
@@ -1665,12 +1680,18 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
|
|
{
|
|
unsigned int i;
|
|
|
|
+ if (WARN_ON(q->in_stop_streaming))
|
|
+ return;
|
|
/*
|
|
* Tell driver to stop all transactions and release all queued
|
|
* buffers.
|
|
*/
|
|
if (q->start_streaming_called)
|
|
+ {
|
|
+ q->in_stop_streaming = 1;
|
|
call_void_qop(q, stop_streaming, q);
|
|
+ q->in_stop_streaming = 0;
|
|
+ }
|
|
|
|
/*
|
|
* If you see this warning, then the driver isn't cleaning up properly
|
|
@@ -1732,6 +1753,11 @@ int vb2_core_streamon(struct vb2_queue *q, unsigned int type)
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ if (q->in_stop_streaming) {
|
|
+ dprintk(1, "streamon while the stream is being stopped\n");
|
|
+ return -EBUSY;
|
|
+ }
|
|
+
|
|
if (q->streaming) {
|
|
dprintk(3, "already streaming\n");
|
|
return 0;
|
|
@@ -1795,6 +1821,10 @@ int vb2_core_streamoff(struct vb2_queue *q, unsigned int type)
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ if (q->in_stop_streaming) {
|
|
+ dprintk(1, "streamoff while the stream is being stopped\n");
|
|
+ return -EBUSY;
|
|
+ }
|
|
/*
|
|
* Cancel will pause streaming and remove all buffers from the driver
|
|
* and videobuf, effectively returning control over them to userspace.
|
|
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
|
|
index d4227a8a2a23..2c2304882b41 100644
|
|
--- a/include/media/videobuf2-core.h
|
|
+++ b/include/media/videobuf2-core.h
|
|
@@ -475,6 +475,7 @@ struct vb2_queue {
|
|
|
|
unsigned int streaming:1;
|
|
unsigned int start_streaming_called:1;
|
|
+ unsigned int in_stop_streaming:1;
|
|
unsigned int error:1;
|
|
unsigned int waiting_for_buffers:1;
|
|
unsigned int is_multiplanar:1;
|
|
2.24.0
|