media: davinci_vpfe: Add video_device and vb2_queue locks
authorEzequiel Garcia <ezequiel@collabora.com>
Fri, 15 Jun 2018 19:07:29 +0000 (15:07 -0400)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Wed, 4 Jul 2018 12:02:05 +0000 (08:02 -0400)
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: Ezequiel Garcia <ezequiel@collabora.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/staging/media/davinci_vpfe/vpfe_video.c
drivers/staging/media/davinci_vpfe/vpfe_video.h

index 390fc98..1269a98 100644 (file)
@@ -1312,6 +1312,8 @@ static const struct vb2_ops video_qops = {
        .stop_streaming         = vpfe_stop_streaming,
        .buf_cleanup            = vpfe_buf_cleanup,
        .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,
        q->buf_struct_size = sizeof(struct vpfe_cap_buffer);
        q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
        q->dev = vpfe_dev->pdev;
+       q->lock = &video->lock;
 
        ret = vb2_queue_init(q);
        if (ret) {
@@ -1598,17 +1601,18 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name)
                return -EINVAL;
        }
        /* Initialize field of video device */
+       mutex_init(&video->lock);
        video->video_dev.release = video_device_release;
        video->video_dev.fops = &vpfe_fops;
        video->video_dev.ioctl_ops = &vpfe_ioctl_ops;
        video->video_dev.minor = -1;
        video->video_dev.tvnorms = 0;
+       video->video_dev.lock = &video->lock;
        snprintf(video->video_dev.name, sizeof(video->video_dev.name),
                 "DAVINCI VIDEO %s %s", name, direction);
 
        spin_lock_init(&video->irqlock);
        spin_lock_init(&video->dma_queue_lock);
-       mutex_init(&video->lock);
        ret = media_entity_pads_init(&video->video_dev.entity,
                                1, &video->pad);
        if (ret < 0)
index 22136d3..4bbd219 100644 (file)
@@ -128,7 +128,7 @@ struct vpfe_video_device {
        spinlock_t                              irqlock;
        /* IRQ lock for DMA queue */
        spinlock_t                              dma_queue_lock;
-       /* lock used to access this structure */
+       /* lock used to serialize all video4linux ioctls */
        struct mutex                            lock;
        /* number of users performing IO */
        u32                                     io_usrs;