Skip to content

Commit 2826d44

Browse files
icklerodrigovivi
authored andcommitted
drm/i915/gem: Remove shared locking on freeing objects
The obj->base.resv may be shared across many objects, some of which may still be live and locked, preventing objects from being freed indefintely. We could individualise the lock during the free, or rely on a freed object having no contention and being able to immediately free the pages it owns. References: https://gitlab.freedesktop.org/drm/intel/-/issues/6469 Fixes: be7612f ("drm/i915: Require object lock when freeing pages during destruction") Fixes: 6cb12fb ("drm/i915: Use trylock instead of blocking lock for __i915_gem_free_objects.") Cc: <[email protected]> # v5.17+ Signed-off-by: Chris Wilson <[email protected]> Tested-by: Nirmoy Das <[email protected]> Acked-by: Nirmoy Das <[email protected]> Signed-off-by: Nirmoy Das <[email protected]> Reviewed-by: Matthew Auld <[email protected]> Signed-off-by: Matthew Auld <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] (cherry picked from commit 7dd5c56) Signed-off-by: Rodrigo Vivi <[email protected]>
1 parent 59eda6c commit 2826d44

File tree

2 files changed

+6
-14
lines changed

2 files changed

+6
-14
lines changed

drivers/gpu/drm/i915/gem/i915_gem_object.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ static void __i915_gem_object_free_mmaps(struct drm_i915_gem_object *obj)
268268
*/
269269
void __i915_gem_object_pages_fini(struct drm_i915_gem_object *obj)
270270
{
271-
assert_object_held(obj);
271+
assert_object_held_shared(obj);
272272

273273
if (!list_empty(&obj->vma.list)) {
274274
struct i915_vma *vma;
@@ -331,15 +331,7 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
331331
continue;
332332
}
333333

334-
if (!i915_gem_object_trylock(obj, NULL)) {
335-
/* busy, toss it back to the pile */
336-
if (llist_add(&obj->freed, &i915->mm.free_list))
337-
queue_delayed_work(i915->wq, &i915->mm.free_work, msecs_to_jiffies(10));
338-
continue;
339-
}
340-
341334
__i915_gem_object_pages_fini(obj);
342-
i915_gem_object_unlock(obj);
343335
__i915_gem_free_object(obj);
344336

345337
/* But keep the pointer alive for RCU-protected lookups */
@@ -359,7 +351,7 @@ void i915_gem_flush_free_objects(struct drm_i915_private *i915)
359351
static void __i915_gem_free_work(struct work_struct *work)
360352
{
361353
struct drm_i915_private *i915 =
362-
container_of(work, struct drm_i915_private, mm.free_work.work);
354+
container_of(work, struct drm_i915_private, mm.free_work);
363355

364356
i915_gem_flush_free_objects(i915);
365357
}
@@ -391,7 +383,7 @@ static void i915_gem_free_object(struct drm_gem_object *gem_obj)
391383
*/
392384

393385
if (llist_add(&obj->freed, &i915->mm.free_list))
394-
queue_delayed_work(i915->wq, &i915->mm.free_work, 0);
386+
queue_work(i915->wq, &i915->mm.free_work);
395387
}
396388

397389
void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,
@@ -745,7 +737,7 @@ bool i915_gem_object_needs_ccs_pages(struct drm_i915_gem_object *obj)
745737

746738
void i915_gem_init__objects(struct drm_i915_private *i915)
747739
{
748-
INIT_DELAYED_WORK(&i915->mm.free_work, __i915_gem_free_work);
740+
INIT_WORK(&i915->mm.free_work, __i915_gem_free_work);
749741
}
750742

751743
void i915_objects_module_exit(void)

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ struct i915_gem_mm {
247247
* List of objects which are pending destruction.
248248
*/
249249
struct llist_head free_list;
250-
struct delayed_work free_work;
250+
struct work_struct free_work;
251251
/**
252252
* Count of objects pending destructions. Used to skip needlessly
253253
* waiting on an RCU barrier if no objects are waiting to be freed.
@@ -1378,7 +1378,7 @@ static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
13781378
* armed the work again.
13791379
*/
13801380
while (atomic_read(&i915->mm.free_count)) {
1381-
flush_delayed_work(&i915->mm.free_work);
1381+
flush_work(&i915->mm.free_work);
13821382
flush_delayed_work(&i915->bdev.wq);
13831383
rcu_barrier();
13841384
}

0 commit comments

Comments
 (0)