diff mbox

drm: Apply kref_put_mutex() optimisations to drm_gem_object_unreference_unlocked()

Message ID 1375779586-24918-1-git-send-email-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Chris Wilson Aug. 6, 2013, 8:59 a.m. UTC
We can apply the same optimisation tricks as kref_put_mutex() in our
local equivalent function. However, we have a different locking semantic
(we unlock ourselves, in kref_put_mutex() the callee unlocks) so that we
can use the same callbacks for both locked and unlocked kref_put()s and
so can not simply convert to using kref_put_mutex() directly.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 include/drm/drmP.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Daniel Vetter Aug. 6, 2013, 9:27 p.m. UTC | #1
On Tue, Aug 06, 2013 at 09:59:46AM +0100, Chris Wilson wrote:
> We can apply the same optimisation tricks as kref_put_mutex() in our
> local equivalent function. However, we have a different locking semantic
> (we unlock ourselves, in kref_put_mutex() the callee unlocks) so that we
> can use the same callbacks for both locked and unlocked kref_put()s and
> so can not simply convert to using kref_put_mutex() directly.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

I think longterm we want to move to delayed free callbacks (similar to how
fput works) since the locking with dma-buf and all will simply get too
hairy. But for now this is a neat optimization imo, so

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  include/drm/drmP.h | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> index 4b518e0..ee2ef27 100644
> --- a/include/drm/drmP.h
> +++ b/include/drm/drmP.h
> @@ -1626,10 +1626,12 @@ drm_gem_object_unreference(struct drm_gem_object *obj)
>  static inline void
>  drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)
>  {
> -	if (obj != NULL) {
> +	if (obj && !atomic_add_unless(&obj->refcount.refcount, -1, 1)) {
>  		struct drm_device *dev = obj->dev;
> +
>  		mutex_lock(&dev->struct_mutex);
> -		kref_put(&obj->refcount, drm_gem_object_free);
> +		if (likely(atomic_dec_and_test(&obj->refcount.refcount)))
> +			drm_gem_object_free(&obj->refcount);
>  		mutex_unlock(&dev->struct_mutex);
>  	}
>  }
> -- 
> 1.8.4.rc1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
Chris Wilson Aug. 6, 2013, 10:22 p.m. UTC | #2
On Tue, Aug 06, 2013 at 11:27:50PM +0200, Daniel Vetter wrote:
> On Tue, Aug 06, 2013 at 09:59:46AM +0100, Chris Wilson wrote:
> > We can apply the same optimisation tricks as kref_put_mutex() in our
> > local equivalent function. However, we have a different locking semantic
> > (we unlock ourselves, in kref_put_mutex() the callee unlocks) so that we
> > can use the same callbacks for both locked and unlocked kref_put()s and
> > so can not simply convert to using kref_put_mutex() directly.
> > 
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> 
> I think longterm we want to move to delayed free callbacks (similar to how
> fput works) since the locking with dma-buf and all will simply get too
> hairy. But for now this is a neat optimization imo, so

I have bad memories of delayed free batching up several thousand small
bo. *shudder*
-Chris
diff mbox

Patch

diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 4b518e0..ee2ef27 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1626,10 +1626,12 @@  drm_gem_object_unreference(struct drm_gem_object *obj)
 static inline void
 drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)
 {
-	if (obj != NULL) {
+	if (obj && !atomic_add_unless(&obj->refcount.refcount, -1, 1)) {
 		struct drm_device *dev = obj->dev;
+
 		mutex_lock(&dev->struct_mutex);
-		kref_put(&obj->refcount, drm_gem_object_free);
+		if (likely(atomic_dec_and_test(&obj->refcount.refcount)))
+			drm_gem_object_free(&obj->refcount);
 		mutex_unlock(&dev->struct_mutex);
 	}
 }