Hello everyone, The patcheset adds support for DMABUF [1] importing to vmalloc allocator in videobuf2 stack. This is an incremental patch to 'Integration of videobuf2 with dmabuf' patchset [2]. This patch makes use of vmap extension for dmabuf proposed by Dave Airlie [3].
The vmap was preferred over the kmap extension. The reason is that VIVI driver requires the memory to be mapped into a contiguous block of virtual memory accessible by kernel. The workaround could be mapping all pages into kernel memory but the dmabuf-kmap interface does guarantee that consecutive pages are mapped into consecutive addresses.
[1] https://lkml.org/lkml/2011/12/26/29 [2] http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/46586 [3] http://cgit.freedesktop.org/~airlied/linux/commit/?h=drm-dmabuf2&id=c481...
Dave Airlie (1): dma-buf: add vmap interface
Tomasz Stanislawski (2): v4l: vb2-vmalloc: add support for dmabuf importing v4l: vivi: support for dmabuf importing
drivers/base/dma-buf.c | 29 ++++++++++++++++ drivers/media/video/Kconfig | 1 + drivers/media/video/videobuf2-vmalloc.c | 56 +++++++++++++++++++++++++++++++ drivers/media/video/vivi.c | 2 +- include/linux/dma-buf.h | 16 +++++++++ 5 files changed, 103 insertions(+), 1 deletions(-)
From: Dave Airlie airlied@redhat.com
Add vmap to dmabuf interface.
Signed-off-by: Dave Airlie airlied@redhat.com --- drivers/base/dma-buf.c | 29 +++++++++++++++++++++++++++++ include/linux/dma-buf.h | 16 ++++++++++++++++ 2 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 07cbbc6..3068258 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c @@ -406,3 +406,32 @@ void dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long page_num, dmabuf->ops->kunmap(dmabuf, page_num, vaddr); } EXPORT_SYMBOL_GPL(dma_buf_kunmap); + +/** + * dma_buf_vmap - Create virtual mapping for the buffer object into kernel address space. The same restrictions as for vmap and friends apply. + * @dma_buf: [in] buffer to vmap + * + * This call may fail due to lack of virtual mapping address space. + */ +void *dma_buf_vmap(struct dma_buf *dmabuf) +{ + WARN_ON(!dmabuf); + + if (dmabuf->ops->vmap) + return dmabuf->ops->vmap(dmabuf); + return NULL; +} +EXPORT_SYMBOL(dma_buf_vmap); + +/** + * dma_buf_vunmap - Unmap a page obtained by dma_buf_vmap. + * @dma_buf: [in] buffer to vmap + */ +void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) +{ + WARN_ON(!dmabuf); + + if (dmabuf->ops->vunmap) + dmabuf->ops->vunmap(dmabuf, vaddr); +} +EXPORT_SYMBOL(dma_buf_vunmap); diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 3efbfc2..4a6b371 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -92,6 +92,9 @@ struct dma_buf_ops { void (*kunmap_atomic)(struct dma_buf *, unsigned long, void *); void *(*kmap)(struct dma_buf *, unsigned long); void (*kunmap)(struct dma_buf *, unsigned long, void *); + + void *(*vmap)(struct dma_buf *); + void (*vunmap)(struct dma_buf *, void *vaddr); };
/** @@ -167,6 +170,9 @@ void *dma_buf_kmap_atomic(struct dma_buf *, unsigned long); void dma_buf_kunmap_atomic(struct dma_buf *, unsigned long, void *); void *dma_buf_kmap(struct dma_buf *, unsigned long); void dma_buf_kunmap(struct dma_buf *, unsigned long, void *); + +void *dma_buf_vmap(struct dma_buf *); +void dma_buf_vunmap(struct dma_buf *, void *vaddr); #else
static inline struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, @@ -248,6 +254,16 @@ static inline void dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long pnum, void *vaddr) { } + +static inline void *dma_buf_vmap(struct dma_buf *dmabuf) +{ + return NULL; +} + +static inline void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) +{ +} + #endif /* CONFIG_DMA_SHARED_BUFFER */
#endif /* __DMA_BUF_H__ */
Hi,
On 04/10/2012 12:11 PM, Tomasz Stanislawski wrote:
From: Dave Airlieairlied@redhat.com
Add vmap to dmabuf interface.
Signed-off-by: Dave Airlieairlied@redhat.com
drivers/base/dma-buf.c | 29 +++++++++++++++++++++++++++++ include/linux/dma-buf.h | 16 ++++++++++++++++ 2 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 07cbbc6..3068258 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c @@ -406,3 +406,32 @@ void dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long page_num, dmabuf->ops->kunmap(dmabuf, page_num, vaddr); } EXPORT_SYMBOL_GPL(dma_buf_kunmap);
+/**
- dma_buf_vmap - Create virtual mapping for the buffer object into kernel address space. The same restrictions as for vmap and friends apply.
- @dma_buf: [in] buffer to vmap
- This call may fail due to lack of virtual mapping address space.
- */
+void *dma_buf_vmap(struct dma_buf *dmabuf) +{
- WARN_ON(!dmabuf);
How about replacing this with:
if (WARN_ON(!dmabuf)) return NULL;
to avoid null pointer dereference right below ?
- if (dmabuf->ops->vmap)
return dmabuf->ops->vmap(dmabuf);
- return NULL;
+} +EXPORT_SYMBOL(dma_buf_vmap);
+/**
- dma_buf_vunmap - Unmap a page obtained by dma_buf_vmap.
- @dma_buf: [in] buffer to vmap
- */
+void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) +{
- WARN_ON(!dmabuf);
and here if (WARN_ON(!dmabuf)) return; ?
- if (dmabuf->ops->vunmap)
dmabuf->ops->vunmap(dmabuf, vaddr);
+} +EXPORT_SYMBOL(dma_buf_vunmap);
--
Regards, Sylwester
This patch adds support for importing DMABUF files for vmalloc allocator in Videobuf2.
Signed-off-by: Tomasz Stanislawski t.stanislaws@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com --- drivers/media/video/videobuf2-vmalloc.c | 56 +++++++++++++++++++++++++++++++ 1 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/drivers/media/video/videobuf2-vmalloc.c b/drivers/media/video/videobuf2-vmalloc.c index 6b5ca6c..305032f 100644 --- a/drivers/media/video/videobuf2-vmalloc.c +++ b/drivers/media/video/videobuf2-vmalloc.c @@ -29,6 +29,7 @@ struct vb2_vmalloc_buf { unsigned int n_pages; atomic_t refcount; struct vb2_vmarea_handler handler; + struct dma_buf *dbuf; };
static void vb2_vmalloc_put(void *buf_priv); @@ -206,11 +207,66 @@ static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma) return 0; }
+/*********************************************/ +/* callbacks for DMABUF buffers */ +/*********************************************/ + +static int vb2_vmalloc_map_dmabuf(void *mem_priv) +{ + struct vb2_vmalloc_buf *buf = mem_priv; + + buf->vaddr = dma_buf_vmap(buf->dbuf); + + return buf->vaddr ? 0 : -EFAULT; +} + +static void vb2_vmalloc_unmap_dmabuf(void *mem_priv) +{ + struct vb2_vmalloc_buf *buf = mem_priv; + + dma_buf_vunmap(buf->dbuf, buf->vaddr); + buf->vaddr = NULL; +} + +static void vb2_vmalloc_detach_dmabuf(void *mem_priv) +{ + struct vb2_vmalloc_buf *buf = mem_priv; + + if (buf->vaddr) + dma_buf_vunmap(buf->dbuf, buf->vaddr); + + kfree(buf); +} + +static void *vb2_vmalloc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf, + unsigned long size, int write) +{ + struct vb2_vmalloc_buf *buf; + + if (dbuf->size < size) + return ERR_PTR(-EFAULT); + + buf = kzalloc(sizeof *buf, GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + buf->dbuf = dbuf; + buf->write = write; + buf->size = size; + + return buf; +} + + const struct vb2_mem_ops vb2_vmalloc_memops = { .alloc = vb2_vmalloc_alloc, .put = vb2_vmalloc_put, .get_userptr = vb2_vmalloc_get_userptr, .put_userptr = vb2_vmalloc_put_userptr, + .map_dmabuf = vb2_vmalloc_map_dmabuf, + .unmap_dmabuf = vb2_vmalloc_unmap_dmabuf, + .attach_dmabuf = vb2_vmalloc_attach_dmabuf, + .detach_dmabuf = vb2_vmalloc_detach_dmabuf, .vaddr = vb2_vmalloc_vaddr, .mmap = vb2_vmalloc_mmap, .num_users = vb2_vmalloc_num_users,
This patch enhances VIVI driver with a support for importing a buffer from DMABUF file descriptors.
Signed-off-by: Tomasz Stanislawski t.stanislaws@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com --- drivers/media/video/Kconfig | 1 + drivers/media/video/vivi.c | 2 +- 2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index f2479c5..d6294d6 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -625,6 +625,7 @@ config VIDEO_VIVI depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE select FONT_8x16 select VIDEOBUF2_VMALLOC + select DMA_SHARED_BUFFER default n ---help--- Enables a virtual video driver. This device shows a color bar diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 5e8b071..489d685 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -1289,7 +1289,7 @@ static int __init vivi_create_instance(int inst) q = &dev->vb_vidq; memset(q, 0, sizeof(dev->vb_vidq)); q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; q->drv_priv = dev; q->buf_struct_size = sizeof(struct vivi_buffer); q->ops = &vivi_video_qops;
linaro-mm-sig@lists.linaro.org