[PATCH 09/35] drm/gem: support BO freeing without dev->struct_mutex
Lucas Stach
l.stach at pengutronix.de
Wed Apr 27 09:31:00 UTC 2016
Am Dienstag, den 26.04.2016, 19:29 +0200 schrieb Daniel Vetter:
> Finally all the core gem and a lot of drivers are entirely free of
> dev->struct_mutex depencies, and we can start to have an entirely
> lockless unref path.
>
> To make sure that no one who touches the core code accidentally breaks
> existing drivers which still require dev->struct_mutex I've made the
> might_lock check unconditional.
>
> While at it de-inline the ref/unref functions, they've become a bit
> too big.
>
> v2: Make it not leak like a sieve.
>
> Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
Two mostly cosmetic comments below, otherwise looks good:
Reviewed-by: Lucas Stach <l.stach at pengutronix.de>
> ---
> drivers/gpu/drm/drm_gem.c | 64 ++++++++++++++++++++++++++++++++++++++---------
> include/drm/drmP.h | 12 ++++++++-
> include/drm/drm_gem.h | 45 ++-------------------------------
> 3 files changed, 65 insertions(+), 56 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index 25dac31eef37..8f2eff448bb5 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -788,16 +788,7 @@ drm_gem_object_release(struct drm_gem_object *obj)
> }
> EXPORT_SYMBOL(drm_gem_object_release);
>
> -/**
> - * drm_gem_object_free - free a GEM object
> - * @kref: kref of the object to free
> - *
> - * Called after the last reference to the object has been lost.
> - * Must be called holding struct_ mutex
> - *
> - * Frees the object
> - */
> -void
> +static void
> drm_gem_object_free(struct kref *kref)
> {
> struct drm_gem_object *obj =
> @@ -806,10 +797,59 @@ drm_gem_object_free(struct kref *kref)
>
> WARN_ON(!mutex_is_locked(&dev->struct_mutex));
>
> - if (dev->driver->gem_free_object != NULL)
> + if (dev->driver->gem_free_object_unlocked != NULL)
Why those explicit != NULL checks? The style mostly used in this file is
to omit those, like "if (dev->driver->gem_free_object_unlocked)". Same
comment applies to several hunks of this patch.
> + dev->driver->gem_free_object_unlocked(obj);
> + else if (dev->driver->gem_free_object != NULL)
> dev->driver->gem_free_object(obj);
> }
> -EXPORT_SYMBOL(drm_gem_object_free);
> +
> +/**
> + * drm_gem_object_unreference_unlocked - release a GEM BO reference
> + * @obj: GEM buffer object
> + *
> + * This releases a reference to @obj. Callers must not hold the
> + * dev->struct_mutex lock when calling this function.
> + */
> +void
> +drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)
> +{
> + struct drm_device *dev;
> +
> + if (!obj)
> + return;
> +
> + dev = obj->dev;
> + might_lock(&dev->struct_mutex);
> +
> + if (dev->driver->gem_free_object != NULL)
> + kref_put(&obj->refcount, drm_gem_object_free);
> + else if (kref_put_mutex(&obj->refcount, drm_gem_object_free,
> + &dev->struct_mutex))
> + mutex_unlock(&dev->struct_mutex);
> +}
> +EXPORT_SYMBOL(drm_gem_object_unreference_unlocked);
> +
> +/**
> + * drm_gem_object_unreference - release a GEM BO reference
> + * @obj: GEM buffer object
> + *
> + * This releases a reference to @obj. Callers must hold the dev->struct_mutex
> + * lock when calling this function, even when the driver doesn't use
> + * dev->struct_mutex for anything.
> + *
> + * For drivers not encumbered with legacy locking use
> + * drm_gem_object_unreference_unlocked() instead.
> + */
> +void
> +drm_gem_object_unreference(struct drm_gem_object *obj)
> +{
> + if (obj != NULL) {
> + WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex));
> +
> + kref_put(&obj->refcount, drm_gem_object_free);
> + }
> +}
> +EXPORT_SYMBOL(drm_gem_object_unreference);
>
> /**
> * drm_gem_vm_open - vma->ops->open implementation for GEM
> diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> index c81dd2250fc6..7e30b3d2b25c 100644
> --- a/include/drm/drmP.h
> +++ b/include/drm/drmP.h
> @@ -583,9 +583,19 @@ struct drm_driver {
> * Driver-specific constructor for drm_gem_objects, to set up
> * obj->driver_private.
> *
> - * Returns 0 on success.
> + * This is deprecated and should not be used by new drivers. Use
> + * @gem_free_object_unlocked instead.
> */
> void (*gem_free_object) (struct drm_gem_object *obj);
> +
> + /**
> + * Driver-specific constructor for drm_gem_objects, to set up
> + * obj->driver_private.
This part of the comment is really off. I see it's just copy&paste from
the comment above gem_free_object, but I think it should have been
placed above gem_open_object and has nothing to do with the free*
callbacks.
> This is for drivers which are not encumbered
> + * with dev->struct_mutex legacy locking schemes. Use this hook instead
> + * of @gem_free_object.
> + */
> + void (*gem_free_object_unlocked) (struct drm_gem_object *obj);
> +
> int (*gem_open_object) (struct drm_gem_object *, struct drm_file *);
> void (*gem_close_object) (struct drm_gem_object *, struct drm_file *);
>
> diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
> index 0b3e11ab8757..ae1c7f18eec0 100644
> --- a/include/drm/drm_gem.h
> +++ b/include/drm/drm_gem.h
> @@ -175,7 +175,6 @@ struct drm_gem_object {
> };
>
> void drm_gem_object_release(struct drm_gem_object *obj);
> -void drm_gem_object_free(struct kref *kref);
> int drm_gem_object_init(struct drm_device *dev,
> struct drm_gem_object *obj, size_t size);
> void drm_gem_private_object_init(struct drm_device *dev,
> @@ -199,48 +198,8 @@ drm_gem_object_reference(struct drm_gem_object *obj)
> kref_get(&obj->refcount);
> }
>
> -/**
> - * drm_gem_object_unreference - release a GEM BO reference
> - * @obj: GEM buffer object
> - *
> - * This releases a reference to @obj. Callers must hold the dev->struct_mutex
> - * lock when calling this function, even when the driver doesn't use
> - * dev->struct_mutex for anything.
> - *
> - * For drivers not encumbered with legacy locking use
> - * drm_gem_object_unreference_unlocked() instead.
> - */
> -static inline void
> -drm_gem_object_unreference(struct drm_gem_object *obj)
> -{
> - if (obj != NULL) {
> - WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex));
> -
> - kref_put(&obj->refcount, drm_gem_object_free);
> - }
> -}
> -
> -/**
> - * drm_gem_object_unreference_unlocked - release a GEM BO reference
> - * @obj: GEM buffer object
> - *
> - * This releases a reference to @obj. Callers must not hold the
> - * dev->struct_mutex lock when calling this function.
> - */
> -static inline void
> -drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)
> -{
> - struct drm_device *dev;
> -
> - if (!obj)
> - return;
> -
> - dev = obj->dev;
> - if (kref_put_mutex(&obj->refcount, drm_gem_object_free, &dev->struct_mutex))
> - mutex_unlock(&dev->struct_mutex);
> - else
> - might_lock(&dev->struct_mutex);
> -}
> +void drm_gem_object_unreference_unlocked(struct drm_gem_object *obj);
> +void drm_gem_object_unreference(struct drm_gem_object *obj);
>
> int drm_gem_handle_create(struct drm_file *file_priv,
> struct drm_gem_object *obj,
More information about the dri-devel
mailing list