Re: [PATCH] vivid: Add support for the dma-contig memory allocator

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On December 4, 2015 11:05:48 PM GMT+01:00, Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> wrote:
>To test buffer sharing with devices that require contiguous memory
>buffers the dma-contig allocator is required. Support it and make the
>allocator selectable through a module parameter. Support for the two
>memory allocators can also be individually selected at compile-time to
>avoid bloating the kernel with an unneeded allocator.
>
>Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
>---
> drivers/media/platform/vivid/Kconfig         | 21 ++++++++++++-
>drivers/media/platform/vivid/vivid-core.c    | 44
>++++++++++++++++++++++++----
> drivers/media/platform/vivid/vivid-core.h    |  1 +
> drivers/media/platform/vivid/vivid-sdr-cap.c |  3 ++
> drivers/media/platform/vivid/vivid-vbi-cap.c |  2 ++
> drivers/media/platform/vivid/vivid-vbi-out.c |  1 +
> drivers/media/platform/vivid/vivid-vid-cap.c |  9 ++----
> drivers/media/platform/vivid/vivid-vid-out.c |  9 ++----
> 8 files changed, 72 insertions(+), 18 deletions(-)
>
>diff --git a/drivers/media/platform/vivid/Kconfig
>b/drivers/media/platform/vivid/Kconfig
>index 0885e93ad436..ddfec721c08c 100644
>--- a/drivers/media/platform/vivid/Kconfig
>+++ b/drivers/media/platform/vivid/Kconfig
>@@ -6,7 +6,7 @@ config VIDEO_VIVID
> 	select FB_CFB_FILLRECT
> 	select FB_CFB_COPYAREA
> 	select FB_CFB_IMAGEBLIT
>-	select VIDEOBUF2_VMALLOC
>+	select VIDEO_VIVID_MEM_VMALLOC if !VIDEO_VIVID_MEM_DMA_CONTIG
> 	default n
> 	---help---
> 	  Enables a virtual video driver. This driver emulates a webcam,
>@@ -28,3 +28,22 @@ config VIDEO_VIVID_MAX_DEVS
> 	---help---
> 	  This allows you to specify the maximum number of devices supported
> 	  by the vivid driver.
>+
>+config VIDEO_VIVID_MEM_DMA_CONTIG
>+	bool "Enable DMA-CONTIG Memory Type"
>+	depends on VIDEO_VIVID
>+	select VIDEOBUF2_DMA_CONTIG
>+	default n
>+	---help---
>+	  Enable support for the DMA-CONTIG videobuf2 memory allocator. Say Y
>+	  here if you want to test buffer sharing with devices that require
>+	  contiguous memory buffers. When in doubt, say N.
>+
>+config VIDEO_VIVID_MEM_VMALLOC
>+	bool "Enable VMALLOC Memory Type"
>+	depends on VIDEO_VIVID
>+	select VIDEOBUF2_VMALLOC
>+	default y
>+	---help---
>+	  Enable support for the VMALLOC videobuf2 memory allocator. This is
>the
>+	  default memory allocator for the vivid driver. When in doubt, say
>Y.
>diff --git a/drivers/media/platform/vivid/vivid-core.c
>b/drivers/media/platform/vivid/vivid-core.c
>index f57ff1101e74..d526144151fc 100644
>--- a/drivers/media/platform/vivid/vivid-core.c
>+++ b/drivers/media/platform/vivid/vivid-core.c
>@@ -29,6 +29,7 @@
> #include <linux/platform_device.h>
> #include <linux/videodev2.h>
> #include <linux/v4l2-dv-timings.h>
>+#include <media/videobuf2-dma-contig.h>
> #include <media/videobuf2-vmalloc.h>
> #include <media/v4l2-dv-timings.h>
> #include <media/v4l2-ioctl.h>
>@@ -150,6 +151,16 @@ static bool no_error_inj;
> module_param(no_error_inj, bool, 0444);
>MODULE_PARM_DESC(no_error_inj, " if set disable the error injecting
>controls");
> 
>+enum memory_type {
>+	VIVID_MEM_VMALLOC,
>+	VIVID_MEM_DMA_CONTIG,
>+};
>+
>+static unsigned memory_type;
>+module_param(memory_type, uint, 0444);
>+MODULE_PARM_DESC(memory_type, " memory type, default is vmalloc,\n"
>+			      "\t\t    0 == vmalloc, 1 == dma-contig");
>+
> static struct vivid_dev *vivid_devs[VIVID_MAX_DEVS];
> 
> const struct v4l2_rect vivid_min_rect = {
>@@ -634,6 +645,10 @@ static void vivid_dev_release(struct v4l2_device
>*v4l2_dev)
> {
>	struct vivid_dev *dev = container_of(v4l2_dev, struct vivid_dev,
>v4l2_dev);
> 
>+	if (memory_type == VIVID_MEM_DMA_CONTIG &&
>+	    IS_ENABLED(CONFIG_VIDEO_VIVID_DMA_CONTIG))
>+		vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
>+
> 	vivid_free_controls(dev);
> 	v4l2_device_unregister(&dev->v4l2_dev);
> 	vfree(dev->scaled_line);
>@@ -659,6 +674,7 @@ static int vivid_create_instance(struct
>platform_device *pdev, int inst)
> 	struct vivid_dev *dev;
> 	struct video_device *vfd;
> 	struct vb2_queue *q;
>+	const struct vb2_mem_ops *vb2_memops;
> 	unsigned node_type = node_types[inst];
> 	v4l2_std_id tvnorms_cap = 0, tvnorms_out = 0;
> 	int ret;
>@@ -1026,6 +1042,24 @@ static int vivid_create_instance(struct
>platform_device *pdev, int inst)
> 	INIT_LIST_HEAD(&dev->sdr_cap_active);
> 
> 	/* start creating the vb2 queues */
>+	if (memory_type == VIVID_MEM_DMA_CONTIG &&
>+	    IS_ENABLED(CONFIG_VIDEO_VIVID_DMA_CONTIG)) {
>+		ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
>+		if (ret)
>+			goto unreg_dev;
>+
>+		vb2_memops = &vb2_dma_contig_memops;
>+		dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
>+	} else if (memory_type == VIVID_MEM_VMALLOC &&
>+		   IS_ENABLED(CONFIG_VIDEO_VIVID_VMALLOC)) {
>+		vb2_memops = &vb2_vmalloc_memops;
>+	} else {
>+		dev_err(&pdev->dev, "unsupported memory type %u\n",
>+			memory_type);
>+		ret = -EINVAL;
>+		goto unreg_dev;
>+	}
>+
> 	if (dev->has_vid_cap) {
> 		/* initialize vid_cap queue */
> 		q = &dev->vb_vid_cap_q;
>@@ -1035,7 +1069,7 @@ static int vivid_create_instance(struct
>platform_device *pdev, int inst)
> 		q->drv_priv = dev;
> 		q->buf_struct_size = sizeof(struct vivid_buffer);
> 		q->ops = &vivid_vid_cap_qops;
>-		q->mem_ops = &vb2_vmalloc_memops;
>+		q->mem_ops = vb2_memops;
> 		q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> 		q->min_buffers_needed = 2;
> 		q->lock = &dev->mutex;
>@@ -1054,7 +1088,7 @@ static int vivid_create_instance(struct
>platform_device *pdev, int inst)
> 		q->drv_priv = dev;
> 		q->buf_struct_size = sizeof(struct vivid_buffer);
> 		q->ops = &vivid_vid_out_qops;
>-		q->mem_ops = &vb2_vmalloc_memops;
>+		q->mem_ops = vb2_memops;
> 		q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> 		q->min_buffers_needed = 2;
> 		q->lock = &dev->mutex;
>@@ -1073,7 +1107,7 @@ static int vivid_create_instance(struct
>platform_device *pdev, int inst)
> 		q->drv_priv = dev;
> 		q->buf_struct_size = sizeof(struct vivid_buffer);
> 		q->ops = &vivid_vbi_cap_qops;
>-		q->mem_ops = &vb2_vmalloc_memops;
>+		q->mem_ops = vb2_memops;
> 		q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> 		q->min_buffers_needed = 2;
> 		q->lock = &dev->mutex;
>@@ -1092,7 +1126,7 @@ static int vivid_create_instance(struct
>platform_device *pdev, int inst)
> 		q->drv_priv = dev;
> 		q->buf_struct_size = sizeof(struct vivid_buffer);
> 		q->ops = &vivid_vbi_out_qops;
>-		q->mem_ops = &vb2_vmalloc_memops;
>+		q->mem_ops = vb2_memops;
> 		q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> 		q->min_buffers_needed = 2;
> 		q->lock = &dev->mutex;
>@@ -1110,7 +1144,7 @@ static int vivid_create_instance(struct
>platform_device *pdev, int inst)
> 		q->drv_priv = dev;
> 		q->buf_struct_size = sizeof(struct vivid_buffer);
> 		q->ops = &vivid_sdr_cap_qops;
>-		q->mem_ops = &vb2_vmalloc_memops;
>+		q->mem_ops = vb2_memops;
> 		q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> 		q->min_buffers_needed = 8;
> 		q->lock = &dev->mutex;
>diff --git a/drivers/media/platform/vivid/vivid-core.h
>b/drivers/media/platform/vivid/vivid-core.h
>index 55b304a705d5..22be49c5d5eb 100644
>--- a/drivers/media/platform/vivid/vivid-core.h
>+++ b/drivers/media/platform/vivid/vivid-core.h
>@@ -157,6 +157,7 @@ struct vivid_dev {
> 	struct v4l2_ctrl_handler	ctrl_hdl_sdr_cap;
> 	spinlock_t			slock;
> 	struct mutex			mutex;
>+	void				*alloc_ctx;
> 
> 	/* capabilities */
> 	u32				vid_cap_caps;
>diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c
>b/drivers/media/platform/vivid/vivid-sdr-cap.c
>index 082c401764ce..595501d96550 100644
>--- a/drivers/media/platform/vivid/vivid-sdr-cap.c
>+++ b/drivers/media/platform/vivid/vivid-sdr-cap.c
>@@ -217,9 +217,12 @@ static int sdr_cap_queue_setup(struct vb2_queue
>*vq, const void *parg,
> 		       unsigned *nbuffers, unsigned *nplanes,
> 		       unsigned sizes[], void *alloc_ctxs[])
> {
>+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
>+
> 	/* 2 = max 16-bit sample returned */
> 	sizes[0] = SDR_CAP_SAMPLES_PER_BUF * 2;
> 	*nplanes = 1;
>+	alloc_ctxs[0] = dev->alloc_ctx;
> 	return 0;
> }
> 
>diff --git a/drivers/media/platform/vivid/vivid-vbi-cap.c
>b/drivers/media/platform/vivid/vivid-vbi-cap.c
>index e903d023e9df..afb880fb7d5f 100644
>--- a/drivers/media/platform/vivid/vivid-vbi-cap.c
>+++ b/drivers/media/platform/vivid/vivid-vbi-cap.c
>@@ -156,6 +156,8 @@ static int vbi_cap_queue_setup(struct vb2_queue
>*vq, const void *parg,
> 		*nbuffers = 2 - vq->num_buffers;
> 
> 	*nplanes = 1;
>+	alloc_ctxs[0] = dev->alloc_ctx;
>+
> 	return 0;
> }
> 
>diff --git a/drivers/media/platform/vivid/vivid-vbi-out.c
>b/drivers/media/platform/vivid/vivid-vbi-out.c
>index 75c5709f938e..8ff5a41b9a0f 100644
>--- a/drivers/media/platform/vivid/vivid-vbi-out.c
>+++ b/drivers/media/platform/vivid/vivid-vbi-out.c
>@@ -46,6 +46,7 @@ static int vbi_out_queue_setup(struct vb2_queue *vq,
>const void *parg,
> 		*nbuffers = 2 - vq->num_buffers;
> 
> 	*nplanes = 1;
>+	alloc_ctxs[0] = dev->alloc_ctx;
> 	return 0;
> }
> 
>diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c
>b/drivers/media/platform/vivid/vivid-vid-cap.c
>index d9cb609b7381..305cf1b8b141 100644
>--- a/drivers/media/platform/vivid/vivid-vid-cap.c
>+++ b/drivers/media/platform/vivid/vivid-vid-cap.c
>@@ -156,14 +156,11 @@ static int vid_cap_queue_setup(struct vb2_queue
>*vq, const void *parg,
> 
> 	*nplanes = buffers;
> 
>-	/*
>-	 * videobuf2-vmalloc allocator is context-less so no need to set
>-	 * alloc_ctxs array.
>-	 */
>-
> 	dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);
>-	for (p = 0; p < buffers; p++)
>+	for (p = 0; p < buffers; p++) {
>+		alloc_ctxs[p] = dev->alloc_ctx;
> 		dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);
>+	}
> 
> 	return 0;
> }
>diff --git a/drivers/media/platform/vivid/vivid-vid-out.c
>b/drivers/media/platform/vivid/vivid-vid-out.c
>index b77acb6a7013..36eb2a3c8c55 100644
>--- a/drivers/media/platform/vivid/vivid-vid-out.c
>+++ b/drivers/media/platform/vivid/vivid-vid-out.c
>@@ -97,14 +97,11 @@ static int vid_out_queue_setup(struct vb2_queue
>*vq, const void *parg,
> 
> 	*nplanes = planes;
> 
>-	/*
>-	 * videobuf2-vmalloc allocator is context-less so no need to set
>-	 * alloc_ctxs array.
>-	 */
>-
> 	dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);
>-	for (p = 0; p < planes; p++)
>+	for (p = 0; p < planes; p++) {
>+		alloc_ctxs[p] = dev->alloc_ctx;
> 		dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);
>+	}
> 	return 0;
> }
> 

Apologies for top posting, I'm sending this from my Android phone.

Laurent, did you test this on a regular pc? I've tried this before, but failed since I couldn't make it work on a pc. I didn't spend a huge amount of time on it,  though. 

Just want to make sure that this case is covered. 

Regards, 
Hans 

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux