[PATCH 1/2] drm: Do not call kref utility functions from static inline code

Andy Ritger aritger at nvidia.com
Tue Apr 18 17:55:03 UTC 2017


Commit 10383aea2f44 ("kref: Implement 'struct kref' using refcount_t")
updated the kref implementation to use refcount_t.  Commit 29dee3c03abc
("locking/refcounts: Out-of-line everything") changed the refcount_t
utility functions from static inline to EXPORT_SYMBOL_GPL functions.

Through a chain of drm -> kref -> refcount static inline utility
functions, drm drivers can inadvertently pick up a reference to the
EXPORT_SYMBOL_GPL refcount_t functions.

refcount_t is an internal implementation detail and not intended as
an interface.  Thus, EXPORT_SYMBOL_GPL seems reasonable for it.

Higher-level drm functions, on the other hand, are intended as an
interface exposed to drm drivers.  So, it arguably seems reasonable that
drm functions do not require EXPORT_SYMBOL_GPL.

Move drm functions from static inline to EXPORT_SYMBOL functions, to
make the interface boundary clear.

Specifically:

Move:
  drm_crtc_commit_get
  drm_crtc_commit_put
  drm_atomic_state_get
  drm_atomic_state_put
from drm_atomic.h to drm_atomic.c.

Move
  drm_framebuffer_read_refcount
from drm_framebuffer.h to drm_framebuffer.c.

Move
  drm_gem_object_reference
  __drm_gem_object_unreference
from drm_gem.h to drm_gem.c.

Signed-off-by: Andy Ritger <aritger at nvidia.com>
---
 drivers/gpu/drm/drm_atomic.c      | 51 +++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_framebuffer.c | 12 +++++++++
 drivers/gpu/drm/drm_gem.c         | 35 +++++++++++++++++++++++++++
 include/drm/drm_atomic.h          | 50 +++-----------------------------------
 include/drm/drm_framebuffer.h     | 12 +--------
 include/drm/drm_gem.h             | 36 ++-------------------------
 6 files changed, 105 insertions(+), 91 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index a5673107db26..84cc92035a97 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -45,6 +45,31 @@ void __drm_crtc_commit_free(struct kref *kref)
 EXPORT_SYMBOL(__drm_crtc_commit_free);
 
 /**
+ * drm_crtc_commit_get - acquire a reference to the CRTC commit
+ * @commit: CRTC commit
+ *
+ * Increases the reference of @commit.
+ */
+void drm_crtc_commit_get(struct drm_crtc_commit *commit)
+{
+	kref_get(&commit->ref);
+}
+EXPORT_SYMBOL(drm_crtc_commit_get);
+
+/**
+ * drm_crtc_commit_put - release a reference to the CRTC commmit
+ * @commit: CRTC commit
+ *
+ * This releases a reference to @commit which is freed after removing the
+ * final reference. No locking required and callable from any context.
+ */
+void drm_crtc_commit_put(struct drm_crtc_commit *commit)
+{
+	kref_put(&commit->ref, __drm_crtc_commit_free);
+}
+EXPORT_SYMBOL(drm_crtc_commit_put);
+
+/**
  * drm_atomic_state_default_release -
  * release memory initialized by drm_atomic_state_init
  * @state: atomic state
@@ -239,6 +264,32 @@ void __drm_atomic_state_free(struct kref *ref)
 EXPORT_SYMBOL(__drm_atomic_state_free);
 
 /**
+ * drm_atomic_state_get - acquire a reference to the atomic state
+ * @state: The atomic state
+ *
+ * Returns a new reference to the @state
+ */
+struct drm_atomic_state *drm_atomic_state_get(struct drm_atomic_state *state)
+{
+	kref_get(&state->ref);
+	return state;
+}
+EXPORT_SYMBOL(drm_atomic_state_get);
+
+/**
+ * drm_atomic_state_put - release a reference to the atomic state
+ * @state: The atomic state
+ *
+ * This releases a reference to @state which is freed after removing the
+ * final reference. No locking required and callable from any context.
+ */
+void drm_atomic_state_put(struct drm_atomic_state *state)
+{
+	kref_put(&state->ref, __drm_atomic_state_free);
+}
+EXPORT_SYMBOL(drm_atomic_state_put);
+
+/**
  * drm_atomic_get_crtc_state - get crtc state
  * @state: global atomic state object
  * @crtc: crtc to get state object for
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 28a0108a1ab8..6f24ba5e3866 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -837,3 +837,15 @@ int drm_framebuffer_plane_height(int height,
 	return height / fb->format->vsub;
 }
 EXPORT_SYMBOL(drm_framebuffer_plane_height);
+
+/**
+ * drm_framebuffer_read_refcount - read the framebuffer reference count.
+ * @fb: framebuffer
+ *
+ * This functions returns the framebuffer's reference count.
+ */
+uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb)
+{
+	return kref_read(&fb->base.refcount);
+}
+EXPORT_SYMBOL(drm_framebuffer_read_refcount);
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index bc93de308673..d189b5720bcb 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -1004,3 +1004,38 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
 	return ret;
 }
 EXPORT_SYMBOL(drm_gem_mmap);
+
+/**
+ * drm_gem_object_reference - acquire a GEM BO 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.
+ */
+void drm_gem_object_reference(struct drm_gem_object *obj)
+{
+	kref_get(&obj->refcount);
+}
+EXPORT_SYMBOL(drm_gem_object_reference);
+
+/**
+ * __drm_gem_object_unreference - raw function to release a GEM BO 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().
+ *
+ * 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 avoid breaking drivers by accident which still depend upon
+ * &drm_device.struct_mutex locking.
+ */
+void __drm_gem_object_unreference(struct drm_gem_object *obj)
+{
+	kref_put(&obj->refcount, drm_gem_object_free);
+}
+EXPORT_SYMBOL(__drm_gem_object_unreference);
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 052ab161b239..60f93d084fe4 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -192,59 +192,17 @@ struct drm_atomic_state {
 
 void __drm_crtc_commit_free(struct kref *kref);
 
-/**
- * drm_crtc_commit_get - acquire a reference to the CRTC commit
- * @commit: CRTC commit
- *
- * Increases the reference of @commit.
- */
-static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit)
-{
-	kref_get(&commit->ref);
-}
-
-/**
- * drm_crtc_commit_put - release a reference to the CRTC commmit
- * @commit: CRTC commit
- *
- * This releases a reference to @commit which is freed after removing the
- * final reference. No locking required and callable from any context.
- */
-static inline void drm_crtc_commit_put(struct drm_crtc_commit *commit)
-{
-	kref_put(&commit->ref, __drm_crtc_commit_free);
-}
+void drm_crtc_commit_get(struct drm_crtc_commit *commit);
+void drm_crtc_commit_put(struct drm_crtc_commit *commit);
 
 struct drm_atomic_state * __must_check
 drm_atomic_state_alloc(struct drm_device *dev);
 void drm_atomic_state_clear(struct drm_atomic_state *state);
 
-/**
- * drm_atomic_state_get - acquire a reference to the atomic state
- * @state: The atomic state
- *
- * Returns a new reference to the @state
- */
-static inline struct drm_atomic_state *
-drm_atomic_state_get(struct drm_atomic_state *state)
-{
-	kref_get(&state->ref);
-	return state;
-}
-
 void __drm_atomic_state_free(struct kref *ref);
 
-/**
- * drm_atomic_state_put - release a reference to the atomic state
- * @state: The atomic state
- *
- * This releases a reference to @state which is freed after removing the
- * final reference. No locking required and callable from any context.
- */
-static inline void drm_atomic_state_put(struct drm_atomic_state *state)
-{
-	kref_put(&state->ref, __drm_atomic_state_free);
-}
+struct drm_atomic_state *drm_atomic_state_get(struct drm_atomic_state *state);
+void drm_atomic_state_put(struct drm_atomic_state *state);
 
 int  __must_check
 drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state);
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index dd1e3e99dcff..b6c7f6aec9df 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -202,6 +202,7 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
 void drm_framebuffer_remove(struct drm_framebuffer *fb);
 void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
 void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);
+uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb);
 
 /**
  * drm_framebuffer_reference - incr the fb refcnt
@@ -226,17 +227,6 @@ static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb)
 }
 
 /**
- * drm_framebuffer_read_refcount - read the framebuffer reference count.
- * @fb: framebuffer
- *
- * This functions returns the framebuffer's reference count.
- */
-static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb)
-{
-	return kref_read(&fb->base.refcount);
-}
-
-/**
  * drm_framebuffer_assign - store a reference to the fb
  * @p: location to store framebuffer
  * @fb: new framebuffer (maybe NULL)
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index 449a41b56ffc..e66bd3110044 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -186,40 +186,8 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
 		     struct vm_area_struct *vma);
 int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
 
-/**
- * drm_gem_object_reference - acquire a GEM BO 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.
- */
-static inline void
-drm_gem_object_reference(struct drm_gem_object *obj)
-{
-	kref_get(&obj->refcount);
-}
-
-/**
- * __drm_gem_object_unreference - raw function to release a GEM BO 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().
- *
- * 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
- * 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)
-{
-	kref_put(&obj->refcount, drm_gem_object_free);
-}
+void drm_gem_object_reference(struct drm_gem_object *obj);
+void __drm_gem_object_unreference(struct drm_gem_object *obj);
 
 void drm_gem_object_unreference_unlocked(struct drm_gem_object *obj);
 void drm_gem_object_unreference(struct drm_gem_object *obj);
-- 
2.1.0



More information about the dri-devel mailing list