dma-buf: cleanup dma_buf_export() to make it easily extensible
authorSumit Semwal <sumit.semwal@linaro.org>
Fri, 23 Jan 2015 07:23:43 +0000 (12:53 +0530)
committerSumit Semwal <sumit.semwal@linaro.org>
Tue, 21 Apr 2015 09:17:16 +0000 (14:47 +0530)
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 <maarten.lankhorst@canonical.com>
Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
Acked-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Acked-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
15 files changed:
Documentation/dma-buf-sharing.txt
drivers/dma-buf/dma-buf.c
drivers/gpu/drm/armada/armada_gem.c
drivers/gpu/drm/drm_prime.c
drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
drivers/gpu/drm/i915/i915_gem_dmabuf.c
drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
drivers/gpu/drm/tegra/gem.c
drivers/gpu/drm/ttm/ttm_object.c
drivers/gpu/drm/udl/udl_dmabuf.c
drivers/media/v4l2-core/videobuf2-dma-contig.c
drivers/media/v4l2-core/videobuf2-dma-sg.c
drivers/media/v4l2-core/videobuf2-vmalloc.c
drivers/staging/android/ion/ion.c
include/linux/dma-buf.h

index bb9753b635a3a5e8d8f794814a83584878b550e5..480c8de3c2c44786174e112795f61b2381d3b09f 100644 (file)
@@ -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
 
index 5be225c2ba98d5ea11760217d9afdfa5240215d3..c5a9138a6a8d69508c2a062a48baf359379928ef 100644 (file)
@@ -265,43 +265,40 @@ 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);
        }
 
@@ -309,10 +306,10 @@ struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,
        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;
@@ -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);
@@ -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
index ef5feeecec8489d9c816b3d74e5c7f539850afc9..580e10acaa3ace493c16305eabecd75394c6e49a 100644 (file)
@@ -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 *
index 7482b06cd08fc60f35da2099ed0d3ed88cf11802..7fec191b45f757737ec9525d51298d844cbd29d4 100644 (file)
@@ -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);
 
index 3833bf8ca0258be7919ecfb690868b8c53b11837..cd485c091b30dcf3219ef1edc778a1aa17c4fdfa 100644 (file)
@@ -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,
index 82a1f4b57778e29a105316b1b74b7be654be2550..7998da27c500744c78fd0897193b19f778244ca7 100644 (file)
@@ -230,6 +230,13 @@ 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);
@@ -237,8 +244,7 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
                        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)
index b46dabd9faf75690c6782b20a7dd0b1c501bc160..344fd789170d763264cb4b8585d612745daddff6 100644 (file)
@@ -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,
index cfb481943b6b5741e6538fa4ebf1bc5b56c9d4a7..1217272a51f2cf64173f632690123a9920233097 100644 (file)
@@ -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,
index 12c87110db3ad2bf4aca3a9ca0c7daed0a26bef7..4f5fa8d65fe932a7e10803d10d0e0fc3090a7d59 100644 (file)
@@ -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.
@@ -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,
index ac8a66b4dfc2053ec8b8f7314601bb4d30d49e6a..e2243edd1ce31d6aeaa98e7e1f3ea7bc2ebb31cf 100644 (file)
@@ -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,
index 69e0483adfee02e569f89ece65a31f73c0a96f35..644dec73d2203fdffa67a035231f6fe7450278d2 100644 (file)
@@ -402,6 +402,12 @@ 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);
@@ -409,7 +415,7 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags)
        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;
 
index b1838abb6d0056c38d7fefbce57b3bf2a154328b..45c708e463b93e84721e0c3a65a7a3f52aa33f92 100644 (file)
@@ -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;
 
index bcde88572429fe1e2a5b113183cad15d8077971b..657ab302a5cf457549e151e603b3cc60e5f90be1 100644 (file)
@@ -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;
 
index 0e3d8c7add24e1955e2bd480075df0caf09b1a94..b94d69feff46fbea5f2e4227686fd78befcf6b77 100644 (file)
@@ -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);
@@ -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;
index 694e1fe1c4b4fa8996cab8dcf9fbfa74198f1aed..2f0b431b73e0a7a2c8807a694c8c89a4e4b61a29 100644 (file)
@@ -162,6 +162,33 @@ struct dma_buf_attachment {
        void *priv;
 };
 
+/**
+ * struct dma_buf_export_info - holds information needed to export a dma_buf
+ * @exp_name:  name of the exporting module - useful for debugging.
+ * @ops:       Attach allocator-defined dma buf ops to the new buffer
+ * @size:      Size of the buffer
+ * @flags:     mode flags for the file
+ * @resv:      reservation-object, NULL to allocate default one
+ * @priv:      Attach private data of allocator to this buffer
+ *
+ * This structure holds the information required to export the buffer. Used
+ * with dma_buf_export() only.
+ */
+struct dma_buf_export_info {
+       const char *exp_name;
+       const struct dma_buf_ops *ops;
+       size_t size;
+       int flags;
+       struct reservation_object *resv;
+       void *priv;
+};
+
+/**
+ * helper macro for exporters; zeros and fills in most common values
+ */
+#define DEFINE_DMA_BUF_EXPORT_INFO(a)  \
+       struct dma_buf_export_info a = { .exp_name = KBUILD_MODNAME }
+
 /**
  * get_dma_buf - convenience wrapper for get_file.
  * @dmabuf:    [in]    pointer to dma_buf
@@ -181,12 +208,7 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
 void dma_buf_detach(struct dma_buf *dmabuf,
                                struct dma_buf_attachment *dmabuf_attach);
 
-struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,
-                              size_t size, int flags, const char *,
-                              struct reservation_object *);
-
-#define dma_buf_export(priv, ops, size, flags, resv)   \
-       dma_buf_export_named(priv, ops, size, flags, KBUILD_MODNAME, resv)
+struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info);
 
 int dma_buf_fd(struct dma_buf *dmabuf, int flags);
 struct dma_buf *dma_buf_get(int fd);