V4L/DVB: videobuf: prepare to make locking optional in videobuf
authorHans Verkuil <hverkuil@xs4all.nl>
Mon, 20 Sep 2010 20:24:30 +0000 (17:24 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 21 Oct 2010 03:06:14 +0000 (01:06 -0200)
Currently videobuf uses the vb_lock mutex to lock its data structures.
But this locking will (optionally) move into the v4l2 core, which means
that in that case vb_lock shouldn't be used since the external lock is already
held.

Prepare for this by adding a pointer to such an external mutex and
don't lock if that pointer is set.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/v4l2-mem2mem.c
drivers/media/video/videobuf-core.c
drivers/media/video/videobuf-dma-contig.c
drivers/media/video/videobuf-dma-sg.c
drivers/media/video/videobuf-vmalloc.c
include/media/videobuf-core.h

index f45f940..ac832a2 100644 (file)
@@ -421,8 +421,8 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
        src_q = v4l2_m2m_get_src_vq(m2m_ctx);
        dst_q = v4l2_m2m_get_dst_vq(m2m_ctx);
 
-       mutex_lock(&src_q->vb_lock);
-       mutex_lock(&dst_q->vb_lock);
+       videobuf_queue_lock(src_q);
+       videobuf_queue_lock(dst_q);
 
        if (src_q->streaming && !list_empty(&src_q->stream))
                src_vb = list_first_entry(&src_q->stream,
@@ -450,8 +450,8 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
        }
 
 end:
-       mutex_unlock(&dst_q->vb_lock);
-       mutex_unlock(&src_q->vb_lock);
+       videobuf_queue_unlock(dst_q);
+       videobuf_queue_unlock(src_q);
        return rc;
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_poll);
index ce1595b..2930665 100644 (file)
@@ -350,9 +350,9 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
 int videobuf_mmap_free(struct videobuf_queue *q)
 {
        int ret;
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
        ret = __videobuf_free(q);
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
        return ret;
 }
 EXPORT_SYMBOL_GPL(videobuf_mmap_free);
@@ -407,9 +407,9 @@ int videobuf_mmap_setup(struct videobuf_queue *q,
                        enum v4l2_memory memory)
 {
        int ret;
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
        ret = __videobuf_mmap_setup(q, bcount, bsize, memory);
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
        return ret;
 }
 EXPORT_SYMBOL_GPL(videobuf_mmap_setup);
@@ -432,7 +432,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
                return -EINVAL;
        }
 
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
        if (req->type != q->type) {
                dprintk(1, "reqbufs: queue type invalid\n");
                retval = -EINVAL;
@@ -469,7 +469,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
        retval = 0;
 
  done:
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
        return retval;
 }
 EXPORT_SYMBOL_GPL(videobuf_reqbufs);
@@ -478,7 +478,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
 {
        int ret = -EINVAL;
 
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
        if (unlikely(b->type != q->type)) {
                dprintk(1, "querybuf: Wrong type.\n");
                goto done;
@@ -496,7 +496,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
 
        ret = 0;
 done:
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
        return ret;
 }
 EXPORT_SYMBOL_GPL(videobuf_querybuf);
@@ -513,7 +513,7 @@ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b)
        if (b->memory == V4L2_MEMORY_MMAP)
                down_read(&current->mm->mmap_sem);
 
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
        retval = -EBUSY;
        if (q->reading) {
                dprintk(1, "qbuf: Reading running...\n");
@@ -605,7 +605,7 @@ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b)
        wake_up_interruptible_sync(&q->wait);
 
 done:
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
 
        if (b->memory == V4L2_MEMORY_MMAP)
                up_read(&current->mm->mmap_sem);
@@ -635,14 +635,14 @@ checks:
                        dprintk(2, "next_buffer: waiting on buffer\n");
 
                        /* Drop lock to avoid deadlock with qbuf */
-                       mutex_unlock(&q->vb_lock);
+                       videobuf_queue_unlock(q);
 
                        /* Checking list_empty and streaming is safe without
                         * locks because we goto checks to validate while
                         * holding locks before proceeding */
                        retval = wait_event_interruptible(q->wait,
                                !list_empty(&q->stream) || !q->streaming);
-                       mutex_lock(&q->vb_lock);
+                       videobuf_queue_lock(q);
 
                        if (retval)
                                goto done;
@@ -687,7 +687,7 @@ int videobuf_dqbuf(struct videobuf_queue *q,
        MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
 
        memset(b, 0, sizeof(*b));
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
 
        retval = stream_next_buffer(q, &buf, nonblocking);
        if (retval < 0) {
@@ -713,7 +713,7 @@ int videobuf_dqbuf(struct videobuf_queue *q,
        buf->state = VIDEOBUF_IDLE;
        b->flags &= ~V4L2_BUF_FLAG_DONE;
 done:
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
        return retval;
 }
 EXPORT_SYMBOL_GPL(videobuf_dqbuf);
@@ -724,7 +724,7 @@ int videobuf_streamon(struct videobuf_queue *q)
        unsigned long flags = 0;
        int retval;
 
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
        retval = -EBUSY;
        if (q->reading)
                goto done;
@@ -740,7 +740,7 @@ int videobuf_streamon(struct videobuf_queue *q)
 
        wake_up_interruptible_sync(&q->wait);
 done:
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
        return retval;
 }
 EXPORT_SYMBOL_GPL(videobuf_streamon);
@@ -760,9 +760,9 @@ int videobuf_streamoff(struct videobuf_queue *q)
 {
        int retval;
 
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
        retval = __videobuf_streamoff(q);
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
 
        return retval;
 }
@@ -868,7 +868,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
 
        MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
 
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
 
        q->ops->buf_setup(q, &nbufs, &size);
 
@@ -938,7 +938,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
        }
 
 done:
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
        return retval;
 }
 EXPORT_SYMBOL_GPL(videobuf_read_one);
@@ -999,9 +999,9 @@ int videobuf_read_start(struct videobuf_queue *q)
 {
        int rc;
 
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
        rc = __videobuf_read_start(q);
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
 
        return rc;
 }
@@ -1009,15 +1009,15 @@ EXPORT_SYMBOL_GPL(videobuf_read_start);
 
 void videobuf_read_stop(struct videobuf_queue *q)
 {
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
        __videobuf_read_stop(q);
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
 }
 EXPORT_SYMBOL_GPL(videobuf_read_stop);
 
 void videobuf_stop(struct videobuf_queue *q)
 {
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
 
        if (q->streaming)
                __videobuf_streamoff(q);
@@ -1025,7 +1025,7 @@ void videobuf_stop(struct videobuf_queue *q)
        if (q->reading)
                __videobuf_read_stop(q);
 
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
 }
 EXPORT_SYMBOL_GPL(videobuf_stop);
 
@@ -1039,7 +1039,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
        MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
 
        dprintk(2, "%s\n", __func__);
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
        retval = -EBUSY;
        if (q->streaming)
                goto done;
@@ -1097,7 +1097,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
        }
 
 done:
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
        return retval;
 }
 EXPORT_SYMBOL_GPL(videobuf_read_stream);
@@ -1109,7 +1109,7 @@ unsigned int videobuf_poll_stream(struct file *file,
        struct videobuf_buffer *buf = NULL;
        unsigned int rc = 0;
 
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
        if (q->streaming) {
                if (!list_empty(&q->stream))
                        buf = list_entry(q->stream.next,
@@ -1147,7 +1147,7 @@ unsigned int videobuf_poll_stream(struct file *file,
                        }
                }
        }
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
        return rc;
 }
 EXPORT_SYMBOL_GPL(videobuf_poll_stream);
@@ -1164,7 +1164,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma)
                return -EINVAL;
        }
 
-       mutex_lock(&q->vb_lock);
+       videobuf_queue_lock(q);
        for (i = 0; i < VIDEO_MAX_FRAME; i++) {
                struct videobuf_buffer *buf = q->bufs[i];
 
@@ -1174,7 +1174,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma)
                        break;
                }
        }
-       mutex_unlock(&q->vb_lock);
+       videobuf_queue_unlock(q);
 
        return rc;
 }
index 6ff9e4b..047054f 100644 (file)
@@ -63,7 +63,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
                struct videobuf_dma_contig_memory *mem;
 
                dev_dbg(q->dev, "munmap %p q=%p\n", map, q);
-               mutex_lock(&q->vb_lock);
+               videobuf_queue_lock(q);
 
                /* We need first to cancel streams, before unmapping */
                if (q->streaming)
@@ -103,7 +103,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
 
                kfree(map);
 
-               mutex_unlock(&q->vb_lock);
+               videobuf_queue_unlock(q);
        }
 }
 
index 2ad0bc2..515ae88 100644 (file)
@@ -358,7 +358,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
        map->count--;
        if (0 == map->count) {
                dprintk(1, "munmap %p q=%p\n", map, q);
-               mutex_lock(&q->vb_lock);
+               videobuf_queue_lock(q);
                for (i = 0; i < VIDEO_MAX_FRAME; i++) {
                        if (NULL == q->bufs[i])
                                continue;
@@ -374,7 +374,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
                        q->bufs[i]->baddr = 0;
                        q->ops->buf_release(q, q->bufs[i]);
                }
-               mutex_unlock(&q->vb_lock);
+               videobuf_queue_unlock(q);
                kfree(map);
        }
        return;
index e7fe31d..91348b3 100644 (file)
@@ -75,7 +75,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
                struct videobuf_vmalloc_memory *mem;
 
                dprintk(1, "munmap %p q=%p\n", map, q);
-               mutex_lock(&q->vb_lock);
+               videobuf_queue_lock(q);
 
                /* We need first to cancel streams, before unmapping */
                if (q->streaming)
@@ -114,7 +114,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
 
                kfree(map);
 
-               mutex_unlock(&q->vb_lock);
+               videobuf_queue_unlock(q);
        }
 
        return;
index f2c41ce..f5eb2cb 100644 (file)
@@ -139,6 +139,7 @@ struct videobuf_qtype_ops {
 
 struct videobuf_queue {
        struct mutex               vb_lock;
+       struct mutex               *ext_lock;
        spinlock_t                 *irqlock;
        struct device              *dev;
 
@@ -167,6 +168,18 @@ struct videobuf_queue {
        void                       *priv_data;
 };
 
+static inline void videobuf_queue_lock(struct videobuf_queue *q)
+{
+       if (!q->ext_lock)
+               mutex_lock(&q->vb_lock);
+}
+
+static inline void videobuf_queue_unlock(struct videobuf_queue *q)
+{
+       if (!q->ext_lock)
+               mutex_unlock(&q->vb_lock);
+}
+
 int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
 int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb,
                struct v4l2_framebuffer *fbuf);