linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Javier Martinez Canillas <javier@osg.samsung.com>
To: linux-kernel@vger.kernel.org
Cc: Marek Szyprowski <m.szyprowski@samsung.com>,
	Mauro Carvalho Chehab <mchehab@s-opensource.com>,
	Kyungmin Park <kyungmin.park@samsung.com>,
	Pawel Osciak <pawel@osciak.com>,
	linux-media@vger.kernel.org, Hans Verkuil <hverkuil@xs4all.nl>,
	Shuah Khan <shuahkh@osg.samsung.com>,
	Nicolas Dufresne <nicolas.dufresne@collabora.com>,
	Luis de Bethencourt <luisbg@osg.samsung.com>,
	Javier Martinez Canillas <javier@osg.samsung.com>
Subject: [PATCH] [media] vb2: map dmabuf for planes on driver queue instead of vidioc_qbuf
Date: Fri, 15 Jul 2016 12:26:06 -0400	[thread overview]
Message-ID: <1468599966-31988-1-git-send-email-javier@osg.samsung.com> (raw)

The buffer planes' dma-buf are currently mapped when buffers are queued
from userspace but it's more appropriate to do the mapping when buffers
are queued in the driver since that's when the actual DMA operation are
going to happen.

Suggested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>

---

Hello,

A side effect of this change is that if the dmabuf map fails for some
reasons (i.e: a driver using the DMA contig memory allocator but CMA
not being enabled), the fail will no longer happen on VIDIOC_QBUF but
later (i.e: in VIDIOC_STREAMON).

I don't know if that's an issue though but I think is worth mentioning.

Best regards,
Javier

 drivers/media/v4l2-core/videobuf2-core.c | 88 ++++++++++++++++++++------------
 1 file changed, 54 insertions(+), 34 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index ca8ffeb56d72..3fdf882bf279 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -186,7 +186,7 @@ module_param(debug, int, 0644);
 })
 
 static void __vb2_queue_cancel(struct vb2_queue *q);
-static void __enqueue_in_driver(struct vb2_buffer *vb);
+static int __enqueue_in_driver(struct vb2_buffer *vb);
 
 /**
  * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
@@ -1271,20 +1271,6 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const void *pb)
 		vb->planes[plane].mem_priv = mem_priv;
 	}
 
-	/* TODO: This pins the buffer(s) with  dma_buf_map_attachment()).. but
-	 * really we want to do this just before the DMA, not while queueing
-	 * the buffer(s)..
-	 */
-	for (plane = 0; plane < vb->num_planes; ++plane) {
-		ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv);
-		if (ret) {
-			dprintk(1, "failed to map dmabuf for plane %d\n",
-				plane);
-			goto err;
-		}
-		vb->planes[plane].dbuf_mapped = 1;
-	}
-
 	/*
 	 * Now that everything is in order, copy relevant information
 	 * provided by userspace.
@@ -1296,51 +1282,79 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const void *pb)
 		vb->planes[plane].data_offset = planes[plane].data_offset;
 	}
 
-	if (reacquired) {
-		/*
-		 * Call driver-specific initialization on the newly acquired buffer,
-		 * if provided.
-		 */
-		ret = call_vb_qop(vb, buf_init, vb);
+	return 0;
+err:
+	/* In case of errors, release planes that were already acquired */
+	__vb2_buf_dmabuf_put(vb);
+
+	return ret;
+}
+
+/**
+ * __buf_map_dmabuf() - map dmabuf for buffer planes
+ */
+static int __buf_map_dmabuf(struct vb2_buffer *vb)
+{
+	int ret;
+	unsigned int plane;
+
+	for (plane = 0; plane < vb->num_planes; ++plane) {
+		ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv);
 		if (ret) {
-			dprintk(1, "buffer initialization failed\n");
-			goto err;
+			dprintk(1, "failed to map dmabuf for plane %d\n",
+				plane);
+			return ret;
 		}
+		vb->planes[plane].dbuf_mapped = 1;
+	}
+
+	/*
+	 * Call driver-specific initialization on the newly
+	 * acquired buffer, if provided.
+	 */
+	ret = call_vb_qop(vb, buf_init, vb);
+	if (ret) {
+		dprintk(1, "buffer initialization failed\n");
+		return ret;
 	}
 
 	ret = call_vb_qop(vb, buf_prepare, vb);
 	if (ret) {
 		dprintk(1, "buffer preparation failed\n");
 		call_void_vb_qop(vb, buf_cleanup, vb);
-		goto err;
+		return ret;
 	}
 
 	return 0;
-err:
-	/* In case of errors, release planes that were already acquired */
-	__vb2_buf_dmabuf_put(vb);
-
-	return ret;
 }
 
 /**
  * __enqueue_in_driver() - enqueue a vb2_buffer in driver for processing
  */
-static void __enqueue_in_driver(struct vb2_buffer *vb)
+static int __enqueue_in_driver(struct vb2_buffer *vb)
 {
 	struct vb2_queue *q = vb->vb2_queue;
 	unsigned int plane;
+	int ret;
 
 	vb->state = VB2_BUF_STATE_ACTIVE;
 	atomic_inc(&q->owned_by_drv_count);
 
 	trace_vb2_buf_queue(q, vb);
 
+	if (q->memory == VB2_MEMORY_DMABUF) {
+		ret = __buf_map_dmabuf(vb);
+		if (ret)
+			return ret;
+	}
+
 	/* sync buffers */
 	for (plane = 0; plane < vb->num_planes; ++plane)
 		call_void_memop(vb, prepare, vb->planes[plane].mem_priv);
 
 	call_void_vb_qop(vb, buf_queue, vb);
+
+	return 0;
 }
 
 static int __buf_prepare(struct vb2_buffer *vb, const void *pb)
@@ -1438,8 +1452,11 @@ static int vb2_start_streaming(struct vb2_queue *q)
 	 * If any buffers were queued before streamon,
 	 * we can now pass them to driver for processing.
 	 */
-	list_for_each_entry(vb, &q->queued_list, queued_entry)
-		__enqueue_in_driver(vb);
+	list_for_each_entry(vb, &q->queued_list, queued_entry) {
+		ret = __enqueue_in_driver(vb);
+		if (ret < 0)
+			return ret;
+	}
 
 	/* Tell the driver to start streaming */
 	q->start_streaming_called = 1;
@@ -1540,8 +1557,11 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb)
 	 * If already streaming, give the buffer to driver for processing.
 	 * If not, the buffer will be given to driver on next streamon.
 	 */
-	if (q->start_streaming_called)
-		__enqueue_in_driver(vb);
+	if (q->start_streaming_called) {
+		ret = __enqueue_in_driver(vb);
+		if (ret)
+			return ret;
+	}
 
 	/* Fill buffer information for the userspace */
 	if (pb)
-- 
2.5.5

             reply	other threads:[~2016-07-15 16:26 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-15 16:26 Javier Martinez Canillas [this message]
2016-07-15 19:42 ` [PATCH] [media] vb2: map dmabuf for planes on driver queue instead of vidioc_qbuf Shuah Khan
2016-07-15 21:50   ` Javier Martinez Canillas
2016-07-16 12:15 ` Luis de Bethencourt
2016-07-18  8:01 ` Michael Olbrich
2016-07-18  8:34 ` Hans Verkuil
2016-07-18 13:30   ` Nicolas Dufresne
2016-07-18 14:15   ` Javier Martinez Canillas
2016-09-06 18:27   ` Nicolas Dufresne
2016-07-18 10:27 ` Marek Szyprowski
2016-09-06 18:31   ` Nicolas Dufresne
2016-07-20 13:20 ` Sakari Ailus
2016-07-20 14:06   ` Javier Martinez Canillas
2016-07-20 14:12     ` Hans Verkuil
2016-07-20 14:19       ` Javier Martinez Canillas
2016-09-06 18:34   ` Nicolas Dufresne

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1468599966-31988-1-git-send-email-javier@osg.samsung.com \
    --to=javier@osg.samsung.com \
    --cc=hverkuil@xs4all.nl \
    --cc=kyungmin.park@samsung.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=luisbg@osg.samsung.com \
    --cc=m.szyprowski@samsung.com \
    --cc=mchehab@s-opensource.com \
    --cc=nicolas.dufresne@collabora.com \
    --cc=pawel@osciak.com \
    --cc=shuahkh@osg.samsung.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).