Skip to content

Commit

Permalink
dma-buf: cleanup dma_buf_export() to make it easily extensible
Browse files Browse the repository at this point in the history
At present, dma_buf_export() takes a series of parameters, which
makes it difficult to add any new parameters for exporters, if required.

Make it simpler by moving all these parameters into a struct, and pass
the struct * as parameter to dma_buf_export().

While at it, unite dma_buf_export_named() with dma_buf_export(), and
change all callers accordingly.

Reviewed-by: Maarten Lankhorst <[email protected]>
Reviewed-by: Daniel Thompson <[email protected]>
Acked-by: Mauro Carvalho Chehab <[email protected]>
Acked-by: Dave Airlie <[email protected]>
Signed-off-by: Sumit Semwal <[email protected]>
  • Loading branch information
sumitsemwal committed Apr 21, 2015
1 parent 646da63 commit d8fbe34
Show file tree
Hide file tree
Showing 15 changed files with 152 additions and 63 deletions.
23 changes: 12 additions & 11 deletions Documentation/dma-buf-sharing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,26 @@ The dma_buf buffer sharing API usage contains the following steps:
The buffer exporter announces its wish to export a buffer. In this, it
connects its own private buffer data, provides implementation for operations
that can be performed on the exported dma_buf, and flags for the file
associated with this buffer.
associated with this buffer. All these fields are filled in struct
dma_buf_export_info, defined via the DEFINE_DMA_BUF_EXPORT_INFO macro.

Interface:
struct dma_buf *dma_buf_export_named(void *priv, struct dma_buf_ops *ops,
size_t size, int flags,
const char *exp_name)
DEFINE_DMA_BUF_EXPORT_INFO(exp_info)
struct dma_buf *dma_buf_export(struct dma_buf_export_info *exp_info)

If this succeeds, dma_buf_export_named allocates a dma_buf structure, and
If this succeeds, dma_buf_export allocates a dma_buf structure, and
returns a pointer to the same. It also associates an anonymous file with this
buffer, so it can be exported. On failure to allocate the dma_buf object,
it returns NULL.

'exp_name' is the name of exporter - to facilitate information while
debugging.
'exp_name' in struct dma_buf_export_info is the name of exporter - to
facilitate information while debugging. It is set to KBUILD_MODNAME by
default, so exporters don't have to provide a specific name, if they don't
wish to.

DEFINE_DMA_BUF_EXPORT_INFO macro defines the struct dma_buf_export_info,
zeroes it out and pre-populates exp_name in it.

Exporting modules which do not wish to provide any specific name may use the
helper define 'dma_buf_export()', with the same arguments as above, but
without the last argument; a KBUILD_MODNAME pre-processor directive will be
inserted in place of 'exp_name' instead.

2. Userspace gets a handle to pass around to potential buffer-users

Expand Down
47 changes: 22 additions & 25 deletions drivers/dma-buf/dma-buf.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,54 +265,51 @@ static inline int is_dma_buf_file(struct file *file)
}

/**
* dma_buf_export_named - Creates a new dma_buf, and associates an anon file
* dma_buf_export - Creates a new dma_buf, and associates an anon file
* with this buffer, so it can be exported.
* Also connect the allocator specific data and ops to the buffer.
* Additionally, provide a name string for exporter; useful in debugging.
*
* @priv: [in] Attach private data of allocator to this buffer
* @ops: [in] Attach allocator-defined dma buf ops to the new buffer.
* @size: [in] Size of the buffer
* @flags: [in] mode flags for the file.
* @exp_name: [in] name of the exporting module - useful for debugging.
* @resv: [in] reservation-object, NULL to allocate default one.
* @exp_info: [in] holds all the export related information provided
* by the exporter. see struct dma_buf_export_info
* for further details.
*
* Returns, on success, a newly created dma_buf object, which wraps the
* supplied private data and operations for dma_buf_ops. On either missing
* ops, or error in allocating struct dma_buf, will return negative error.
*
*/
struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,
size_t size, int flags, const char *exp_name,
struct reservation_object *resv)
struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
{
struct dma_buf *dmabuf;
struct reservation_object *resv = exp_info->resv;
struct file *file;
size_t alloc_size = sizeof(struct dma_buf);
if (!resv)
if (!exp_info->resv)
alloc_size += sizeof(struct reservation_object);
else
/* prevent &dma_buf[1] == dma_buf->resv */
alloc_size += 1;

if (WARN_ON(!priv || !ops
|| !ops->map_dma_buf
|| !ops->unmap_dma_buf
|| !ops->release
|| !ops->kmap_atomic
|| !ops->kmap
|| !ops->mmap)) {
if (WARN_ON(!exp_info->priv
|| !exp_info->ops
|| !exp_info->ops->map_dma_buf
|| !exp_info->ops->unmap_dma_buf
|| !exp_info->ops->release
|| !exp_info->ops->kmap_atomic
|| !exp_info->ops->kmap
|| !exp_info->ops->mmap)) {
return ERR_PTR(-EINVAL);
}

dmabuf = kzalloc(alloc_size, GFP_KERNEL);
if (dmabuf == NULL)
return ERR_PTR(-ENOMEM);

dmabuf->priv = priv;
dmabuf->ops = ops;
dmabuf->size = size;
dmabuf->exp_name = exp_name;
dmabuf->priv = exp_info->priv;
dmabuf->ops = exp_info->ops;
dmabuf->size = exp_info->size;
dmabuf->exp_name = exp_info->exp_name;
init_waitqueue_head(&dmabuf->poll);
dmabuf->cb_excl.poll = dmabuf->cb_shared.poll = &dmabuf->poll;
dmabuf->cb_excl.active = dmabuf->cb_shared.active = 0;
Expand All @@ -323,7 +320,8 @@ struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,
}
dmabuf->resv = resv;

file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf, flags);
file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf,
exp_info->flags);
if (IS_ERR(file)) {
kfree(dmabuf);
return ERR_CAST(file);
Expand All @@ -341,8 +339,7 @@ struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,

return dmabuf;
}
EXPORT_SYMBOL_GPL(dma_buf_export_named);

EXPORT_SYMBOL_GPL(dma_buf_export);

/**
* dma_buf_fd - returns a file descriptor for the given dma_buf
Expand Down
10 changes: 8 additions & 2 deletions drivers/gpu/drm/armada/armada_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -538,8 +538,14 @@ struct dma_buf *
armada_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj,
int flags)
{
return dma_buf_export(obj, &armada_gem_prime_dmabuf_ops, obj->size,
O_RDWR, NULL);
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

exp_info.ops = &armada_gem_prime_dmabuf_ops;
exp_info.size = obj->size;
exp_info.flags = O_RDWR;
exp_info.priv = obj;

return dma_buf_export(&exp_info);
}

struct drm_gem_object *
Expand Down
12 changes: 8 additions & 4 deletions drivers/gpu/drm/drm_prime.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,13 +339,17 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj, int flags)
{
struct reservation_object *robj = NULL;
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

exp_info.ops = &drm_gem_prime_dmabuf_ops;
exp_info.size = obj->size;
exp_info.flags = flags;
exp_info.priv = obj;

if (dev->driver->gem_prime_res_obj)
robj = dev->driver->gem_prime_res_obj(obj);
exp_info.resv = dev->driver->gem_prime_res_obj(obj);

return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size,
flags, robj);
return dma_buf_export(&exp_info);
}
EXPORT_SYMBOL(drm_gem_prime_export);

Expand Down
9 changes: 7 additions & 2 deletions drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,14 @@ struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev,
struct drm_gem_object *obj, int flags)
{
struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

return dma_buf_export(obj, &exynos_dmabuf_ops,
exynos_gem_obj->base.size, flags, NULL);
exp_info.ops = &exynos_dmabuf_ops;
exp_info.size = exynos_gem_obj->base.size;
exp_info.flags = flags;
exp_info.priv = obj;

return dma_buf_export(&exp_info);
}

struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
Expand Down
10 changes: 8 additions & 2 deletions drivers/gpu/drm/i915/i915_gem_dmabuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,15 +230,21 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *gem_obj, int flags)
{
struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

exp_info.ops = &i915_dmabuf_ops;
exp_info.size = gem_obj->size;
exp_info.flags = flags;
exp_info.priv = gem_obj;


if (obj->ops->dmabuf_export) {
int ret = obj->ops->dmabuf_export(obj);
if (ret)
return ERR_PTR(ret);
}

return dma_buf_export(gem_obj, &i915_dmabuf_ops, gem_obj->size, flags,
NULL);
return dma_buf_export(&exp_info);
}

static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
Expand Down
9 changes: 8 additions & 1 deletion drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,14 @@ static struct dma_buf_ops omap_dmabuf_ops = {
struct dma_buf *omap_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj, int flags)
{
return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, flags, NULL);
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

exp_info.ops = &omap_dmabuf_ops;
exp_info.size = obj->size;
exp_info.flags = flags;
exp_info.priv = obj;

return dma_buf_export(&exp_info);
}

struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
Expand Down
10 changes: 8 additions & 2 deletions drivers/gpu/drm/tegra/gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -627,8 +627,14 @@ struct dma_buf *tegra_gem_prime_export(struct drm_device *drm,
struct drm_gem_object *gem,
int flags)
{
return dma_buf_export(gem, &tegra_gem_prime_dmabuf_ops, gem->size,
flags, NULL);
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

exp_info.ops = &tegra_gem_prime_dmabuf_ops;
exp_info.size = gem->size;
exp_info.flags = flags;
exp_info.priv = gem;

return dma_buf_export(&exp_info);
}

struct drm_gem_object *tegra_gem_prime_import(struct drm_device *drm,
Expand Down
9 changes: 7 additions & 2 deletions drivers/gpu/drm/ttm/ttm_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,12 @@ int ttm_prime_handle_to_fd(struct ttm_object_file *tfile,

dma_buf = prime->dma_buf;
if (!dma_buf || !get_dma_buf_unless_doomed(dma_buf)) {
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

exp_info.ops = &tdev->ops;
exp_info.size = prime->size;
exp_info.flags = flags;
exp_info.priv = prime;

/*
* Need to create a new dma_buf, with memory accounting.
Expand All @@ -694,8 +700,7 @@ int ttm_prime_handle_to_fd(struct ttm_object_file *tfile,
goto out_unref;
}

dma_buf = dma_buf_export(prime, &tdev->ops,
prime->size, flags, NULL);
dma_buf = dma_buf_export(&exp_info);
if (IS_ERR(dma_buf)) {
ret = PTR_ERR(dma_buf);
ttm_mem_global_free(tdev->mem_glob,
Expand Down
9 changes: 8 additions & 1 deletion drivers/gpu/drm/udl/udl_dmabuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,14 @@ static struct dma_buf_ops udl_dmabuf_ops = {
struct dma_buf *udl_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj, int flags)
{
return dma_buf_export(obj, &udl_dmabuf_ops, obj->size, flags, NULL);
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

exp_info.ops = &udl_dmabuf_ops;
exp_info.size = obj->size;
exp_info.flags = flags;
exp_info.priv = obj;

return dma_buf_export(&exp_info);
}

static int udl_prime_create(struct drm_device *dev,
Expand Down
8 changes: 7 additions & 1 deletion drivers/media/v4l2-core/videobuf2-dma-contig.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,14 +402,20 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags)
{
struct vb2_dc_buf *buf = buf_priv;
struct dma_buf *dbuf;
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

exp_info.ops = &vb2_dc_dmabuf_ops;
exp_info.size = buf->size;
exp_info.flags = flags;
exp_info.priv = buf;

if (!buf->sgt_base)
buf->sgt_base = vb2_dc_get_base_sgt(buf);

if (WARN_ON(!buf->sgt_base))
return NULL;

dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, flags, NULL);
dbuf = dma_buf_export(&exp_info);
if (IS_ERR(dbuf))
return NULL;

Expand Down
8 changes: 7 additions & 1 deletion drivers/media/v4l2-core/videobuf2-dma-sg.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,11 +583,17 @@ static struct dma_buf *vb2_dma_sg_get_dmabuf(void *buf_priv, unsigned long flags
{
struct vb2_dma_sg_buf *buf = buf_priv;
struct dma_buf *dbuf;
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

exp_info.ops = &vb2_dma_sg_dmabuf_ops;
exp_info.size = buf->size;
exp_info.flags = flags;
exp_info.priv = buf;

if (WARN_ON(!buf->dma_sgt))
return NULL;

dbuf = dma_buf_export(buf, &vb2_dma_sg_dmabuf_ops, buf->size, flags, NULL);
dbuf = dma_buf_export(&exp_info);
if (IS_ERR(dbuf))
return NULL;

Expand Down
8 changes: 7 additions & 1 deletion drivers/media/v4l2-core/videobuf2-vmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,11 +368,17 @@ static struct dma_buf *vb2_vmalloc_get_dmabuf(void *buf_priv, unsigned long flag
{
struct vb2_vmalloc_buf *buf = buf_priv;
struct dma_buf *dbuf;
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

exp_info.ops = &vb2_vmalloc_dmabuf_ops;
exp_info.size = buf->size;
exp_info.flags = flags;
exp_info.priv = buf;

if (WARN_ON(!buf->vaddr))
return NULL;

dbuf = dma_buf_export(buf, &vb2_vmalloc_dmabuf_ops, buf->size, flags, NULL);
dbuf = dma_buf_export(&exp_info);
if (IS_ERR(dbuf))
return NULL;

Expand Down
9 changes: 7 additions & 2 deletions drivers/staging/android/ion/ion.c
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,12 @@ struct dma_buf *ion_share_dma_buf(struct ion_client *client,
struct ion_buffer *buffer;
struct dma_buf *dmabuf;
bool valid_handle;
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

exp_info.ops = &dma_buf_ops;
exp_info.size = buffer->size;
exp_info.flags = O_RDWR;
exp_info.priv = buffer;

mutex_lock(&client->lock);
valid_handle = ion_handle_validate(client, handle);
Expand All @@ -1118,8 +1124,7 @@ struct dma_buf *ion_share_dma_buf(struct ion_client *client,
ion_buffer_get(buffer);
mutex_unlock(&client->lock);

dmabuf = dma_buf_export(buffer, &dma_buf_ops, buffer->size, O_RDWR,
NULL);
dmabuf = dma_buf_export(&exp_info);
if (IS_ERR(dmabuf)) {
ion_buffer_put(buffer);
return dmabuf;
Expand Down
Loading

0 comments on commit d8fbe34

Please sign in to comment.