Skip to content

Commit 6cb12fb

Browse files
committed
drm/i915: Use trylock instead of blocking lock for __i915_gem_free_objects.
Convert free_work into delayed_work, similar to ttm to allow converting the blocking lock in __i915_gem_free_objects to a trylock. Unlike ttm, the object should already be idle, as it's kept alive by a reference through struct i915_vma->active, which is dropped after all vma's are idle. Because of this, we can use a no wait by default, or when the lock is contested, we use ttm's 10 ms. The trylock should only fail when the object is sharing it's resv with other objects, and typically objects are not kept locked for a long time, so we can safely retry on failure. Fixes: be7612f ("drm/i915: Require object lock when freeing pages during destruction") Testcase: igt/gem_exec_alignment/pi* Signed-off-by: Maarten Lankhorst <[email protected]> Reviewed-by: Thomas Hellström <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent c2ea703 commit 6cb12fb

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,13 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
331331
continue;
332332
}
333333

334-
i915_gem_object_lock(obj, NULL);
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+
335341
__i915_gem_object_pages_fini(obj);
336342
i915_gem_object_unlock(obj);
337343
__i915_gem_free_object(obj);
@@ -353,7 +359,7 @@ void i915_gem_flush_free_objects(struct drm_i915_private *i915)
353359
static void __i915_gem_free_work(struct work_struct *work)
354360
{
355361
struct drm_i915_private *i915 =
356-
container_of(work, struct drm_i915_private, mm.free_work);
362+
container_of(work, struct drm_i915_private, mm.free_work.work);
357363

358364
i915_gem_flush_free_objects(i915);
359365
}
@@ -385,7 +391,7 @@ static void i915_gem_free_object(struct drm_gem_object *gem_obj)
385391
*/
386392

387393
if (llist_add(&obj->freed, &i915->mm.free_list))
388-
queue_work(i915->wq, &i915->mm.free_work);
394+
queue_delayed_work(i915->wq, &i915->mm.free_work, 0);
389395
}
390396

391397
void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,
@@ -710,7 +716,7 @@ bool i915_gem_object_placement_possible(struct drm_i915_gem_object *obj,
710716

711717
void i915_gem_init__objects(struct drm_i915_private *i915)
712718
{
713-
INIT_WORK(&i915->mm.free_work, __i915_gem_free_work);
719+
INIT_DELAYED_WORK(&i915->mm.free_work, __i915_gem_free_work);
714720
}
715721

716722
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
@@ -601,7 +601,7 @@ struct i915_gem_mm {
601601
* List of objects which are pending destruction.
602602
*/
603603
struct llist_head free_list;
604-
struct work_struct free_work;
604+
struct delayed_work free_work;
605605
/**
606606
* Count of objects pending destructions. Used to skip needlessly
607607
* waiting on an RCU barrier if no objects are waiting to be freed.
@@ -1835,7 +1835,7 @@ static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
18351835
* armed the work again.
18361836
*/
18371837
while (atomic_read(&i915->mm.free_count)) {
1838-
flush_work(&i915->mm.free_work);
1838+
flush_delayed_work(&i915->mm.free_work);
18391839
flush_delayed_work(&i915->bdev.wq);
18401840
rcu_barrier();
18411841
}

0 commit comments

Comments
 (0)