Commit 4e55969f authored by Ezequiel Garcia's avatar Ezequiel Garcia Committed by Mauro Carvalho Chehab

media: davinci_vpfe: Add video_device and vb2_queue locks

Currently, this driver does not serialize its video4linux
ioctls, which is a bug, as race conditions might appear.

In addition, video_device and vb2_queue locks are now both
mandatory. Add them, and implement wait_prepare and
wait_finish.

To stay on the safe side, this commit uses a single mutex
for both locks. Better latency can be obtained by separating
these if needed.
Signed-off-by: default avatarEzequiel Garcia <ezequiel@collabora.com>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent e5e4c9c9
...@@ -1312,6 +1312,8 @@ static const struct vb2_ops video_qops = { ...@@ -1312,6 +1312,8 @@ static const struct vb2_ops video_qops = {
.stop_streaming = vpfe_stop_streaming, .stop_streaming = vpfe_stop_streaming,
.buf_cleanup = vpfe_buf_cleanup, .buf_cleanup = vpfe_buf_cleanup,
.buf_queue = vpfe_buffer_queue, .buf_queue = vpfe_buffer_queue,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
}; };
/* /*
...@@ -1357,6 +1359,7 @@ static int vpfe_reqbufs(struct file *file, void *priv, ...@@ -1357,6 +1359,7 @@ static int vpfe_reqbufs(struct file *file, void *priv,
q->buf_struct_size = sizeof(struct vpfe_cap_buffer); q->buf_struct_size = sizeof(struct vpfe_cap_buffer);
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->dev = vpfe_dev->pdev; q->dev = vpfe_dev->pdev;
q->lock = &video->lock;
ret = vb2_queue_init(q); ret = vb2_queue_init(q);
if (ret) { if (ret) {
...@@ -1598,17 +1601,18 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name) ...@@ -1598,17 +1601,18 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name)
return -EINVAL; return -EINVAL;
} }
/* Initialize field of video device */ /* Initialize field of video device */
mutex_init(&video->lock);
video->video_dev.release = video_device_release; video->video_dev.release = video_device_release;
video->video_dev.fops = &vpfe_fops; video->video_dev.fops = &vpfe_fops;
video->video_dev.ioctl_ops = &vpfe_ioctl_ops; video->video_dev.ioctl_ops = &vpfe_ioctl_ops;
video->video_dev.minor = -1; video->video_dev.minor = -1;
video->video_dev.tvnorms = 0; video->video_dev.tvnorms = 0;
video->video_dev.lock = &video->lock;
snprintf(video->video_dev.name, sizeof(video->video_dev.name), snprintf(video->video_dev.name, sizeof(video->video_dev.name),
"DAVINCI VIDEO %s %s", name, direction); "DAVINCI VIDEO %s %s", name, direction);
spin_lock_init(&video->irqlock); spin_lock_init(&video->irqlock);
spin_lock_init(&video->dma_queue_lock); spin_lock_init(&video->dma_queue_lock);
mutex_init(&video->lock);
ret = media_entity_pads_init(&video->video_dev.entity, ret = media_entity_pads_init(&video->video_dev.entity,
1, &video->pad); 1, &video->pad);
if (ret < 0) if (ret < 0)
......
...@@ -128,7 +128,7 @@ struct vpfe_video_device { ...@@ -128,7 +128,7 @@ struct vpfe_video_device {
spinlock_t irqlock; spinlock_t irqlock;
/* IRQ lock for DMA queue */ /* IRQ lock for DMA queue */
spinlock_t dma_queue_lock; spinlock_t dma_queue_lock;
/* lock used to access this structure */ /* lock used to serialize all video4linux ioctls */
struct mutex lock; struct mutex lock;
/* number of users performing IO */ /* number of users performing IO */
u32 io_usrs; u32 io_usrs;
......
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