Re: [PATCH 1/2] drm: introduce drm_gem_object_[handle_]unreference_unlocked

2010-02-10 Thread Eric Anholt
On Tue,  9 Feb 2010 06:49:11 +0100, Luca Barbieri l...@luca-barbieri.com 
wrote:
 This patch introduces the drm_gem_object_unreference_unlocked
 and drm_gem_object_handle_unreference_unlocked functions that
 do not require holding struct_mutex.
 
 drm_gem_object_unreference_unlocked calls the new
 -gem_free_object_unlocked entry point if available, and
 otherwise just takes struct_mutex and just calls -gem_free_object

With the exception of adding a new unused API in the form of
gem_free_object_unlocked driver hook, I like this.


pgpWTX0zXEDW7.pgp
Description: PGP signature
--
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev--
___
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel


Re: [PATCH 1/2] drm: introduce drm_gem_object_[handle_]unreference_unlocked

2010-02-10 Thread Luca Barbieri
 With the exception of adding a new unused API in the form of
 gem_free_object_unlocked driver hook, I like this.

Nouveau and Radeon should be able to use it (by setting it to the same
function used for gem_free_object) with little or no modification
(they rely on TTM locking).

I didn't do it for Radeon since I'm not familiar with the code.
I'll hopefully send a Nouveau patch as part of a patchset removing all
non-init/KMS BKL/struct_mutex usage in it once it is done.

--
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
--
___
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel


Re: [PATCH 1/2] drm: introduce drm_gem_object_[handle_]unreference_unlocked

2010-02-09 Thread Daniel Vetter
On Tue, Feb 09, 2010 at 06:49:11AM +0100, Luca Barbieri wrote:
 This patch introduces the drm_gem_object_unreference_unlocked
 and drm_gem_object_handle_unreference_unlocked functions that
 do not require holding struct_mutex.
 
 drm_gem_object_unreference_unlocked calls the new
 -gem_free_object_unlocked entry point if available, and
 otherwise just takes struct_mutex and just calls -gem_free_object

Why not add a BUG_ON(!mutex_is_locked(dev-struct_mutex)) to
drm_gem_object_unreference to catch wrong api by occasional drm hackers
like me?

-Daniel
-- 
Daniel Vetter
Mail: dan...@ffwll.ch
Mobile: +41 (0)79 365 57 48

--
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
--
___
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel


[PATCH 1/2] drm: introduce drm_gem_object_[handle_]unreference_unlocked

2010-02-08 Thread Luca Barbieri
This patch introduces the drm_gem_object_unreference_unlocked
and drm_gem_object_handle_unreference_unlocked functions that
do not require holding struct_mutex.

drm_gem_object_unreference_unlocked calls the new
-gem_free_object_unlocked entry point if available, and
otherwise just takes struct_mutex and just calls -gem_free_object

Signed-off-by: Luca Barbieri l...@luca-barbieri.com
---
 drivers/gpu/drm/drm_gem.c |   49 
 include/drm/drmP.h|   28 +++--
 2 files changed, 69 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 8bf3770..4018b3b 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -411,8 +411,19 @@ drm_gem_release(struct drm_device *dev, struct drm_file 
*file_private)
mutex_unlock(dev-struct_mutex);
 }
 
+static void
+drm_gem_object_free_common(struct drm_gem_object *obj)
+{
+   struct drm_device *dev = obj-dev;
+   fput(obj-filp);
+   atomic_dec(dev-object_count);
+   atomic_sub(obj-size, dev-object_memory);
+   kfree(obj);
+}
+
 /**
  * Called after the last reference to the object has been lost.
+ * Must be called holding struct_ mutex
  *
  * Frees the object
  */
@@ -427,14 +438,40 @@ drm_gem_object_free(struct kref *kref)
if (dev-driver-gem_free_object != NULL)
dev-driver-gem_free_object(obj);
 
-   fput(obj-filp);
-   atomic_dec(dev-object_count);
-   atomic_sub(obj-size, dev-object_memory);
-   kfree(obj);
+   drm_gem_object_free_common(obj);
 }
 EXPORT_SYMBOL(drm_gem_object_free);
 
 /**
+ * Called after the last reference to the object has been lost.
+ * Must be called without holding struct_mutex
+ *
+ * Frees the object
+ */
+void
+drm_gem_object_free_unlocked(struct kref *kref)
+{
+   struct drm_gem_object *obj = (struct drm_gem_object *) kref;
+   struct drm_device *dev = obj-dev;
+
+   if (dev-driver-gem_free_object_unlocked != NULL)
+   dev-driver-gem_free_object_unlocked(obj);
+   else if (dev-driver-gem_free_object != NULL) {
+   mutex_lock(dev-struct_mutex);
+   dev-driver-gem_free_object(obj);
+   mutex_unlock(dev-struct_mutex);
+   }
+
+   drm_gem_object_free_common(obj);
+}
+EXPORT_SYMBOL(drm_gem_object_free_unlocked);
+
+static void drm_gem_object_ref_bug(struct kref *list_kref)
+{
+   BUG();
+}
+
+/**
  * Called after the last handle to the object has been closed
  *
  * Removes any name for the object. Note that this must be
@@ -458,8 +495,10 @@ drm_gem_object_handle_free(struct kref *kref)
/*
 * The object name held a reference to this object, drop
 * that now.
+   *
+   * This cannot be the last reference, since the handle holds one 
too.
 */
-   drm_gem_object_unreference(obj);
+   kref_put(obj-refcount, drm_gem_object_ref_bug);
} else
spin_unlock(dev-object_name_lock);
 
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index ffac157..4a3c4e4 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -801,6 +801,7 @@ struct drm_driver {
 */
int (*gem_init_object) (struct drm_gem_object *obj);
void (*gem_free_object) (struct drm_gem_object *obj);
+   void (*gem_free_object_unlocked) (struct drm_gem_object *obj);
 
/* vga arb irq handler */
void (*vgaarb_irq)(struct drm_device *dev, bool state);
@@ -1427,6 +1428,7 @@ extern void drm_sysfs_connector_remove(struct 
drm_connector *connector);
 int drm_gem_init(struct drm_device *dev);
 void drm_gem_destroy(struct drm_device *dev);
 void drm_gem_object_free(struct kref *kref);
+void drm_gem_object_free_unlocked(struct kref *kref);
 struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev,
size_t size);
 void drm_gem_object_handle_free(struct kref *kref);
@@ -1443,10 +1445,15 @@ drm_gem_object_reference(struct drm_gem_object *obj)
 static inline void
 drm_gem_object_unreference(struct drm_gem_object *obj)
 {
-   if (obj == NULL)
-   return;
+   if (obj != NULL)
+   kref_put(obj-refcount, drm_gem_object_free);
+}
 
-   kref_put(obj-refcount, drm_gem_object_free);
+static inline void
+drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)
+{
+   if (obj != NULL)
+   kref_put(obj-refcount, drm_gem_object_free_unlocked);
 }
 
 int drm_gem_handle_create(struct drm_file *file_priv,
@@ -1475,6 +1482,21 @@ drm_gem_object_handle_unreference(struct drm_gem_object 
*obj)
drm_gem_object_unreference(obj);
 }
 
+static inline void
+drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj)
+{
+   if (obj == NULL)
+   return;
+
+   /*
+   * Must bump handle count first as this may be the last
+   * ref, in