drm: Introduce drm_gem_object_{get,put}()
authorThierry Reding <treding@nvidia.com>
Tue, 28 Feb 2017 14:46:41 +0000 (15:46 +0100)
committerThierry Reding <treding@nvidia.com>
Tue, 28 Feb 2017 15:16:43 +0000 (16:16 +0100)
For consistency with other reference counting APIs in the kernel, add
drm_gem_object_get() and drm_gem_object_put(), as well as an unlocked
variant of the latter, to reference count GEM buffer objects.

Compatibility aliases are added to keep existing code working. To help
speed up the transition, all the instances of the old functions in the
DRM core are already replaced in this commit.

The existing semantic patch for the DRM subsystem-wide conversion is
extended to account for these new helpers.

Reviewed-by: Sean Paul <seanpaul@chromium.org>
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170228144643.5668-6-thierry.reding@gmail.com
Documentation/gpu/drm-mm.rst
drivers/gpu/drm/drm_fb_cma_helper.c
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_gem_cma_helper.c
drivers/gpu/drm/drm_prime.c
include/drm/drm_gem.h
scripts/coccinelle/api/drm-get-put.cocci

index f5760b140f13f19a3e27a037355e2875ea67006c..fd35998acefc1d96ee39013827d202eb472b6625 100644 (file)
@@ -183,14 +183,12 @@ GEM Objects Lifetime
 --------------------
 
 All GEM objects are reference-counted by the GEM core. References can be
-acquired and release by :c:func:`calling
-drm_gem_object_reference()` and
-:c:func:`drm_gem_object_unreference()` respectively. The caller
-must hold the :c:type:`struct drm_device <drm_device>`
-struct_mutex lock when calling
-:c:func:`drm_gem_object_reference()`. As a convenience, GEM
-provides :c:func:`drm_gem_object_unreference_unlocked()`
-functions that can be called without holding the lock.
+acquired and release by :c:func:`calling drm_gem_object_get()` and
+:c:func:`drm_gem_object_put()` respectively. The caller must hold the
+:c:type:`struct drm_device <drm_device>` struct_mutex lock when calling
+:c:func:`drm_gem_object_get()`. As a convenience, GEM provides
+:c:func:`drm_gem_object_put_unlocked()` functions that can be called without
+holding the lock.
 
 When the last reference to a GEM object is released the GEM core calls
 the :c:type:`struct drm_driver <drm_driver>` gem_free_object
index 920bb5764cd64e6ae2a06a2433d02734eb16a756..be6d90664e50138d0b1ee84aa458c5d2bf8abc17 100644 (file)
@@ -102,7 +102,7 @@ void drm_fb_cma_destroy(struct drm_framebuffer *fb)
 
        for (i = 0; i < 4; i++) {
                if (fb_cma->obj[i])
-                       drm_gem_object_unreference_unlocked(&fb_cma->obj[i]->base);
+                       drm_gem_object_put_unlocked(&fb_cma->obj[i]->base);
        }
 
        drm_framebuffer_cleanup(fb);
@@ -190,7 +190,7 @@ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev,
                if (!obj) {
                        dev_err(dev->dev, "Failed to lookup GEM object\n");
                        ret = -ENXIO;
-                       goto err_gem_object_unreference;
+                       goto err_gem_object_put;
                }
 
                min_size = (height - 1) * mode_cmd->pitches[i]
@@ -198,9 +198,9 @@ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev,
                         + mode_cmd->offsets[i];
 
                if (obj->size < min_size) {
-                       drm_gem_object_unreference_unlocked(obj);
+                       drm_gem_object_put_unlocked(obj);
                        ret = -EINVAL;
-                       goto err_gem_object_unreference;
+                       goto err_gem_object_put;
                }
                objs[i] = to_drm_gem_cma_obj(obj);
        }
@@ -208,14 +208,14 @@ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev,
        fb_cma = drm_fb_cma_alloc(dev, mode_cmd, objs, i, funcs);
        if (IS_ERR(fb_cma)) {
                ret = PTR_ERR(fb_cma);
-               goto err_gem_object_unreference;
+               goto err_gem_object_put;
        }
 
        return &fb_cma->fb;
 
-err_gem_object_unreference:
+err_gem_object_put:
        for (i--; i >= 0; i--)
-               drm_gem_object_unreference_unlocked(&objs[i]->base);
+               drm_gem_object_put_unlocked(&objs[i]->base);
        return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(drm_fb_cma_create_with_funcs);
@@ -477,7 +477,7 @@ err_cma_destroy:
 err_fb_info_destroy:
        drm_fb_helper_fini(helper);
 err_gem_free_object:
-       drm_gem_object_unreference_unlocked(&obj->base);
+       drm_gem_object_put_unlocked(&obj->base);
        return ret;
 }
 
index bc93de3086730fa056842f211583d646c91ecdfa..b1e28c9446370928fc82e9c17e8c9531937eedf9 100644 (file)
@@ -218,7 +218,7 @@ static void drm_gem_object_exported_dma_buf_free(struct drm_gem_object *obj)
 }
 
 static void
-drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj)
+drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        bool final = false;
@@ -241,7 +241,7 @@ drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj)
        mutex_unlock(&dev->object_name_lock);
 
        if (final)
-               drm_gem_object_unreference_unlocked(obj);
+               drm_gem_object_put_unlocked(obj);
 }
 
 /*
@@ -262,7 +262,7 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
        if (dev->driver->gem_close_object)
                dev->driver->gem_close_object(obj, file_priv);
 
-       drm_gem_object_handle_unreference_unlocked(obj);
+       drm_gem_object_handle_put_unlocked(obj);
 
        return 0;
 }
@@ -352,7 +352,7 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
 
        WARN_ON(!mutex_is_locked(&dev->object_name_lock));
        if (obj->handle_count++ == 0)
-               drm_gem_object_reference(obj);
+               drm_gem_object_get(obj);
 
        /*
         * Get the user-visible handle using idr.  Preload and perform
@@ -392,7 +392,7 @@ err_remove:
        idr_remove(&file_priv->object_idr, handle);
        spin_unlock(&file_priv->table_lock);
 err_unref:
-       drm_gem_object_handle_unreference_unlocked(obj);
+       drm_gem_object_handle_put_unlocked(obj);
        return ret;
 }
 
@@ -606,7 +606,7 @@ drm_gem_object_lookup(struct drm_file *filp, u32 handle)
        /* Check if we currently have a reference on the object */
        obj = idr_find(&filp->object_idr, handle);
        if (obj)
-               drm_gem_object_reference(obj);
+               drm_gem_object_get(obj);
 
        spin_unlock(&filp->table_lock);
 
@@ -683,7 +683,7 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
 
 err:
        mutex_unlock(&dev->object_name_lock);
-       drm_gem_object_unreference_unlocked(obj);
+       drm_gem_object_put_unlocked(obj);
        return ret;
 }
 
@@ -713,7 +713,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
        mutex_lock(&dev->object_name_lock);
        obj = idr_find(&dev->object_name_idr, (int) args->name);
        if (obj) {
-               drm_gem_object_reference(obj);
+               drm_gem_object_get(obj);
        } else {
                mutex_unlock(&dev->object_name_lock);
                return -ENOENT;
@@ -721,7 +721,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
 
        /* drm_gem_handle_create_tail unlocks dev->object_name_lock. */
        ret = drm_gem_handle_create_tail(file_priv, obj, &handle);
-       drm_gem_object_unreference_unlocked(obj);
+       drm_gem_object_put_unlocked(obj);
        if (ret)
                return ret;
 
@@ -809,16 +809,16 @@ drm_gem_object_free(struct kref *kref)
 EXPORT_SYMBOL(drm_gem_object_free);
 
 /**
- * drm_gem_object_unreference_unlocked - release a GEM BO reference
+ * drm_gem_object_put_unlocked - drop a GEM buffer object reference
  * @obj: GEM buffer object
  *
  * This releases a reference to @obj. Callers must not hold the
  * &drm_device.struct_mutex lock when calling this function.
  *
- * See also __drm_gem_object_unreference().
+ * See also __drm_gem_object_put().
  */
 void
-drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)
+drm_gem_object_put_unlocked(struct drm_gem_object *obj)
 {
        struct drm_device *dev;
 
@@ -834,10 +834,10 @@ drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)
                                &dev->struct_mutex))
                mutex_unlock(&dev->struct_mutex);
 }
-EXPORT_SYMBOL(drm_gem_object_unreference_unlocked);
+EXPORT_SYMBOL(drm_gem_object_put_unlocked);
 
 /**
- * drm_gem_object_unreference - release a GEM BO reference
+ * drm_gem_object_put - release a GEM buffer object reference
  * @obj: GEM buffer object
  *
  * This releases a reference to @obj. Callers must hold the
@@ -845,10 +845,10 @@ EXPORT_SYMBOL(drm_gem_object_unreference_unlocked);
  * driver doesn't use &drm_device.struct_mutex for anything.
  *
  * For drivers not encumbered with legacy locking use
- * drm_gem_object_unreference_unlocked() instead.
+ * drm_gem_object_put_unlocked() instead.
  */
 void
-drm_gem_object_unreference(struct drm_gem_object *obj)
+drm_gem_object_put(struct drm_gem_object *obj)
 {
        if (obj) {
                WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex));
@@ -856,7 +856,7 @@ drm_gem_object_unreference(struct drm_gem_object *obj)
                kref_put(&obj->refcount, drm_gem_object_free);
        }
 }
-EXPORT_SYMBOL(drm_gem_object_unreference);
+EXPORT_SYMBOL(drm_gem_object_put);
 
 /**
  * drm_gem_vm_open - vma->ops->open implementation for GEM
@@ -869,7 +869,7 @@ void drm_gem_vm_open(struct vm_area_struct *vma)
 {
        struct drm_gem_object *obj = vma->vm_private_data;
 
-       drm_gem_object_reference(obj);
+       drm_gem_object_get(obj);
 }
 EXPORT_SYMBOL(drm_gem_vm_open);
 
@@ -884,7 +884,7 @@ void drm_gem_vm_close(struct vm_area_struct *vma)
 {
        struct drm_gem_object *obj = vma->vm_private_data;
 
-       drm_gem_object_unreference_unlocked(obj);
+       drm_gem_object_put_unlocked(obj);
 }
 EXPORT_SYMBOL(drm_gem_vm_close);
 
@@ -935,7 +935,7 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
         * (which should happen whether the vma was created by this call, or
         * by a vm_open due to mremap or partial unmap or whatever).
         */
-       drm_gem_object_reference(obj);
+       drm_gem_object_get(obj);
 
        return 0;
 }
@@ -992,14 +992,14 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
                return -EINVAL;
 
        if (!drm_vma_node_is_allowed(node, priv)) {
-               drm_gem_object_unreference_unlocked(obj);
+               drm_gem_object_put_unlocked(obj);
                return -EACCES;
        }
 
        ret = drm_gem_mmap_obj(obj, drm_vma_node_size(node) << PAGE_SHIFT,
                               vma);
 
-       drm_gem_object_unreference_unlocked(obj);
+       drm_gem_object_put_unlocked(obj);
 
        return ret;
 }
index 5cf38a4748457ee5d2af7b84d37e4438019ecc9a..906984d4bec234dfd1de742f5cfb38ea7ec64860 100644 (file)
@@ -121,7 +121,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
        return cma_obj;
 
 error:
-       drm_gem_object_unreference_unlocked(&cma_obj->base);
+       drm_gem_object_put_unlocked(&cma_obj->base);
        return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(drm_gem_cma_create);
@@ -163,7 +163,7 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv,
         */
        ret = drm_gem_handle_create(file_priv, gem_obj, handle);
        /* drop reference from allocate - handle holds it now. */
-       drm_gem_object_unreference_unlocked(gem_obj);
+       drm_gem_object_put_unlocked(gem_obj);
        if (ret)
                return ERR_PTR(ret);
 
@@ -293,7 +293,7 @@ int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv,
 
        *offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
 
-       drm_gem_object_unreference_unlocked(gem_obj);
+       drm_gem_object_put_unlocked(gem_obj);
 
        return 0;
 }
@@ -416,13 +416,13 @@ unsigned long drm_gem_cma_get_unmapped_area(struct file *filp,
                return -EINVAL;
 
        if (!drm_vma_node_is_allowed(node, priv)) {
-               drm_gem_object_unreference_unlocked(obj);
+               drm_gem_object_put_unlocked(obj);
                return -EACCES;
        }
 
        cma_obj = to_drm_gem_cma_obj(obj);
 
-       drm_gem_object_unreference_unlocked(obj);
+       drm_gem_object_put_unlocked(obj);
 
        return cma_obj->vaddr ? (unsigned long)cma_obj->vaddr : -EINVAL;
 }
index 25aa4558f1b5cb276d16f6d43430ed98fafcc566..866b294e7c6137d7ede59c55eb95ad9ec9849879 100644 (file)
@@ -318,7 +318,7 @@ struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev,
                return dma_buf;
 
        drm_dev_ref(dev);
-       drm_gem_object_reference(exp_info->priv);
+       drm_gem_object_get(exp_info->priv);
 
        return dma_buf;
 }
@@ -339,7 +339,7 @@ void drm_gem_dmabuf_release(struct dma_buf *dma_buf)
        struct drm_device *dev = obj->dev;
 
        /* drop the reference on the export fd holds */
-       drm_gem_object_unreference_unlocked(obj);
+       drm_gem_object_put_unlocked(obj);
 
        drm_dev_unref(dev);
 }
@@ -585,7 +585,7 @@ out_have_handle:
 fail_put_dmabuf:
        dma_buf_put(dmabuf);
 out:
-       drm_gem_object_unreference_unlocked(obj);
+       drm_gem_object_put_unlocked(obj);
 out_unlock:
        mutex_unlock(&file_priv->prime.lock);
 
@@ -616,7 +616,7 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
                         * Importing dmabuf exported from out own gem increases
                         * refcount on gem itself instead of f_count of dmabuf.
                         */
-                       drm_gem_object_reference(obj);
+                       drm_gem_object_get(obj);
                        return obj;
                }
        }
@@ -704,7 +704,7 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev,
 
        /* _handle_create_tail unconditionally unlocks dev->object_name_lock. */
        ret = drm_gem_handle_create_tail(file_priv, obj, handle);
-       drm_gem_object_unreference_unlocked(obj);
+       drm_gem_object_put_unlocked(obj);
        if (ret)
                goto out_put;
 
index 449a41b56ffc4443f41c1e53813a60d053adfe3e..3b2a28f7f49fbd5174a13e2c9daf86a1cf16be50 100644 (file)
@@ -48,9 +48,9 @@ struct drm_gem_object {
         *
         * Reference count of this object
         *
-        * Please use drm_gem_object_reference() to acquire and
-        * drm_gem_object_unreference() or drm_gem_object_unreference_unlocked()
-        * to release a reference to a GEM buffer object.
+        * Please use drm_gem_object_get() to acquire and drm_gem_object_put()
+        * or drm_gem_object_put_unlocked() to release a reference to a GEM
+        * buffer object.
         */
        struct kref refcount;
 
@@ -187,42 +187,90 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
 int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
 
 /**
- * drm_gem_object_reference - acquire a GEM BO reference
+ * drm_gem_object_get - acquire a GEM buffer object reference
  * @obj: GEM buffer object
  *
- * This acquires additional reference to @obj. It is illegal to call this
- * without already holding a reference. No locks required.
+ * This function acquires an additional reference to @obj. It is illegal to
+ * call this without already holding a reference. No locks required.
  */
-static inline void
-drm_gem_object_reference(struct drm_gem_object *obj)
+static inline void drm_gem_object_get(struct drm_gem_object *obj)
 {
        kref_get(&obj->refcount);
 }
 
 /**
- * __drm_gem_object_unreference - raw function to release a GEM BO reference
+ * __drm_gem_object_put - raw function to release a GEM buffer object reference
  * @obj: GEM buffer object
  *
  * This function is meant to be used by drivers which are not encumbered with
  * &drm_device.struct_mutex legacy locking and which are using the
  * gem_free_object_unlocked callback. It avoids all the locking checks and
- * locking overhead of drm_gem_object_unreference() and
- * drm_gem_object_unreference_unlocked().
+ * locking overhead of drm_gem_object_put() and drm_gem_object_put_unlocked().
  *
  * Drivers should never call this directly in their code. Instead they should
- * wrap it up into a ``driver_gem_object_unreference(struct driver_gem_object
- * *obj)`` wrapper function, and use that. Shared code should never call this, to
+ * wrap it up into a ``driver_gem_object_put(struct driver_gem_object *obj)``
+ * wrapper function, and use that. Shared code should never call this, to
  * avoid breaking drivers by accident which still depend upon
  * &drm_device.struct_mutex locking.
  */
 static inline void
-__drm_gem_object_unreference(struct drm_gem_object *obj)
+__drm_gem_object_put(struct drm_gem_object *obj)
 {
        kref_put(&obj->refcount, drm_gem_object_free);
 }
 
-void drm_gem_object_unreference_unlocked(struct drm_gem_object *obj);
-void drm_gem_object_unreference(struct drm_gem_object *obj);
+void drm_gem_object_put_unlocked(struct drm_gem_object *obj);
+void drm_gem_object_put(struct drm_gem_object *obj);
+
+/**
+ * drm_gem_object_reference - acquire a GEM buffer object reference
+ * @obj: GEM buffer object
+ *
+ * This is a compatibility alias for drm_gem_object_get() and should not be
+ * used by new code.
+ */
+static inline void drm_gem_object_reference(struct drm_gem_object *obj)
+{
+       drm_gem_object_get(obj);
+}
+
+/**
+ * __drm_gem_object_unreference - raw function to release a GEM buffer object
+ *                                reference
+ * @obj: GEM buffer object
+ *
+ * This is a compatibility alias for __drm_gem_object_put() and should not be
+ * used by new code.
+ */
+static inline void __drm_gem_object_unreference(struct drm_gem_object *obj)
+{
+       __drm_gem_object_put(obj);
+}
+
+/**
+ * drm_gem_object_unreference_unlocked - release a GEM buffer object reference
+ * @obj: GEM buffer object
+ *
+ * This is a compatibility alias for drm_gem_object_put_unlocked() and should
+ * not be used by new code.
+ */
+static inline void
+drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)
+{
+       drm_gem_object_put_unlocked(obj);
+}
+
+/**
+ * drm_gem_object_unreference - release a GEM buffer object reference
+ * @obj: GEM buffer object
+ *
+ * This is a compatibility alias for drm_gem_object_put() and should not be
+ * used by new code.
+ */
+static inline void drm_gem_object_unreference(struct drm_gem_object *obj)
+{
+       drm_gem_object_put(obj);
+}
 
 int drm_gem_handle_create(struct drm_file *file_priv,
                          struct drm_gem_object *obj,
index fd298c24a46511090aaf227a59c7f3cd9918c282..24882547b4d121f875770d9d17b05141faec6077 100644 (file)
@@ -32,6 +32,18 @@ expression object;
 |
 - drm_framebuffer_unreference(object)
 + drm_framebuffer_put(object)
+|
+- drm_gem_object_reference(object)
++ drm_gem_object_get(object)
+|
+- drm_gem_object_unreference(object)
++ drm_gem_object_put(object)
+|
+- __drm_gem_object_unreference(object)
++ __drm_gem_object_put(object)
+|
+- drm_gem_object_unreference_unlocked(object)
++ drm_gem_object_put_unlocked(object)
 )
 
 @r depends on report@
@@ -51,6 +63,14 @@ drm_connector_reference@p(object)
 drm_framebuffer_unreference@p(object)
 |
 drm_framebuffer_reference@p(object)
+|
+drm_gem_object_unreference@p(object)
+|
+drm_gem_object_reference@p(object)
+|
+__drm_gem_object_unreference(object)
+|
+drm_gem_object_unreference_unlocked(object)
 )
 
 @script:python depends on report@