aboutsummaryrefslogtreecommitdiffstats
path: root/include/drm
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2016-05-02 04:40:51 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2016-05-04 06:25:47 -0400
commit9f0ba539d13aebacb05dda542df7ef80684b2c70 (patch)
treec47228be33ff2fc10275c059b74143dc2dc68115 /include/drm
parent8636d45249ce1d121a4c56e9d970087d7ab267b3 (diff)
drm/gem: support BO freeing without dev->struct_mutex
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. v3: Review from Lucas: - drop != NULL in pointer checks. - fixup copypasted kerneldoc to actually match the functions. v4: Add __drm_gem_object_unreference as a fastpath helper for drivers who abolished dev->struct_mutex, requested by Chris. v5: Fix silly mistake in drm_gem_object_unreference_unlocked caught by intel-gfx CI - I checked for gem_free_object instead of gem_free_object_unlocked ... Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Alex Deucher <alexdeucher@gmail.com> Cc: Lucas Stach <l.stach@pengutronix.de> Reviewed-by: Lucas Stach <l.stach@pengutronix.de> (v3) Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> (v4) Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1462178451-1765-1-git-send-email-daniel.vetter@ffwll.ch
Diffstat (limited to 'include/drm')
-rw-r--r--include/drm/drmP.h15
-rw-r--r--include/drm/drm_gem.h48
2 files changed, 27 insertions, 36 deletions
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 7901768bb47c..360b2a74e1ef 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -580,12 +580,21 @@ struct drm_driver {
580 void (*debugfs_cleanup)(struct drm_minor *minor); 580 void (*debugfs_cleanup)(struct drm_minor *minor);
581 581
582 /** 582 /**
583 * Driver-specific constructor for drm_gem_objects, to set up 583 * @gem_free_object: deconstructor for drm_gem_objects
584 * obj->driver_private.
585 * 584 *
586 * Returns 0 on success. 585 * This is deprecated and should not be used by new drivers. Use
586 * @gem_free_object_unlocked instead.
587 */ 587 */
588 void (*gem_free_object) (struct drm_gem_object *obj); 588 void (*gem_free_object) (struct drm_gem_object *obj);
589
590 /**
591 * @gem_free_object_unlocked: deconstructor for drm_gem_objects
592 *
593 * This is for drivers which are not encumbered with dev->struct_mutex
594 * legacy locking schemes. Use this hook instead of @gem_free_object.
595 */
596 void (*gem_free_object_unlocked) (struct drm_gem_object *obj);
597
589 int (*gem_open_object) (struct drm_gem_object *, struct drm_file *); 598 int (*gem_open_object) (struct drm_gem_object *, struct drm_file *);
590 void (*gem_close_object) (struct drm_gem_object *, struct drm_file *); 599 void (*gem_close_object) (struct drm_gem_object *, struct drm_file *);
591 600
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index 0b3e11ab8757..408d6c47d98b 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -200,47 +200,29 @@ drm_gem_object_reference(struct drm_gem_object *obj)
200} 200}
201 201
202/** 202/**
203 * drm_gem_object_unreference - release a GEM BO reference 203 * __drm_gem_object_unreference - raw function to release a GEM BO reference
204 * @obj: GEM buffer object 204 * @obj: GEM buffer object
205 * 205 *
206 * This releases a reference to @obj. Callers must hold the dev->struct_mutex 206 * This function is meant to be used by drivers which are not encumbered with
207 * lock when calling this function, even when the driver doesn't use 207 * dev->struct_mutex legacy locking and which are using the
208 * dev->struct_mutex for anything. 208 * gem_free_object_unlocked callback. It avoids all the locking checks and
209 * locking overhead of drm_gem_object_unreference() and
210 * drm_gem_object_unreference_unlocked().
209 * 211 *
210 * For drivers not encumbered with legacy locking use 212 * Drivers should never call this directly in their code. Instead they should
211 * drm_gem_object_unreference_unlocked() instead. 213 * wrap it up into a driver_gem_object_unreference(struct driver_gem_object
214 * *obj) wrapper function, and use that. Shared code should never call this, to
215 * avoid breaking drivers by accident which still depend upon dev->struct_mutex
216 * locking.
212 */ 217 */
213static inline void 218static inline void
214drm_gem_object_unreference(struct drm_gem_object *obj) 219__drm_gem_object_unreference(struct drm_gem_object *obj)
215{ 220{
216 if (obj != NULL) { 221 kref_put(&obj->refcount, drm_gem_object_free);
217 WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex));
218
219 kref_put(&obj->refcount, drm_gem_object_free);
220 }
221} 222}
222 223
223/** 224void drm_gem_object_unreference_unlocked(struct drm_gem_object *obj);
224 * drm_gem_object_unreference_unlocked - release a GEM BO reference 225void drm_gem_object_unreference(struct drm_gem_object *obj);
225 * @obj: GEM buffer object
226 *
227 * This releases a reference to @obj. Callers must not hold the
228 * dev->struct_mutex lock when calling this function.
229 */
230static inline void
231drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)
232{
233 struct drm_device *dev;
234
235 if (!obj)
236 return;
237
238 dev = obj->dev;
239 if (kref_put_mutex(&obj->refcount, drm_gem_object_free, &dev->struct_mutex))
240 mutex_unlock(&dev->struct_mutex);
241 else
242 might_lock(&dev->struct_mutex);
243}
244 226
245int drm_gem_handle_create(struct drm_file *file_priv, 227int drm_gem_handle_create(struct drm_file *file_priv,
246 struct drm_gem_object *obj, 228 struct drm_gem_object *obj,