Skip to content

Commit b0647a5

Browse files
icklerodrigovivi
authored andcommitted
drm/i915: Avoid live-lock with i915_vma_parked()
Abuse^W Take advantage that we know we are inside the GT wakeref and that prevents any client execbuf from reopening the i915_vma in order to claim all the vma to close without having to drop the spinlock to free each one individually. By keeping the spinlock, we do not have to restart if we run concurrently with i915_gem_free_objects -- which causes them both to restart continually and make very very slow progress. Closes: https://gitlab.freedesktop.org/drm/intel/issues/1361 Fixes: 7785318 ("drm/i915: Claim vma while under closed_lock in i915_vma_parked()") Signed-off-by: Chris Wilson <[email protected]> Cc: Tvrtko Ursulin <[email protected]> Reviewed-by: Tvrtko Ursulin <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] (cherry picked from commit 3447c4c) Signed-off-by: Rodrigo Vivi <[email protected]>
1 parent 98479ad commit b0647a5

File tree

1 file changed

+14
-15
lines changed

1 file changed

+14
-15
lines changed

drivers/gpu/drm/i915/i915_vma.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,7 @@ void i915_vma_release(struct kref *ref)
10971097
void i915_vma_parked(struct intel_gt *gt)
10981098
{
10991099
struct i915_vma *vma, *next;
1100+
LIST_HEAD(closed);
11001101

11011102
spin_lock_irq(&gt->closed_lock);
11021103
list_for_each_entry_safe(vma, next, &gt->closed_vma, closed_link) {
@@ -1108,28 +1109,26 @@ void i915_vma_parked(struct intel_gt *gt)
11081109
if (!kref_get_unless_zero(&obj->base.refcount))
11091110
continue;
11101111

1111-
if (i915_vm_tryopen(vm)) {
1112-
list_del_init(&vma->closed_link);
1113-
} else {
1112+
if (!i915_vm_tryopen(vm)) {
11141113
i915_gem_object_put(obj);
1115-
obj = NULL;
1114+
continue;
11161115
}
11171116

1118-
spin_unlock_irq(&gt->closed_lock);
1117+
list_move(&vma->closed_link, &closed);
1118+
}
1119+
spin_unlock_irq(&gt->closed_lock);
11191120

1120-
if (obj) {
1121-
__i915_vma_put(vma);
1122-
i915_gem_object_put(obj);
1123-
}
1121+
/* As the GT is held idle, no vma can be reopened as we destroy them */
1122+
list_for_each_entry_safe(vma, next, &closed, closed_link) {
1123+
struct drm_i915_gem_object *obj = vma->obj;
1124+
struct i915_address_space *vm = vma->vm;
11241125

1125-
i915_vm_close(vm);
1126+
INIT_LIST_HEAD(&vma->closed_link);
1127+
__i915_vma_put(vma);
11261128

1127-
/* Restart after dropping lock */
1128-
spin_lock_irq(&gt->closed_lock);
1129-
next = list_first_entry(&gt->closed_vma,
1130-
typeof(*next), closed_link);
1129+
i915_gem_object_put(obj);
1130+
i915_vm_close(vm);
11311131
}
1132-
spin_unlock_irq(&gt->closed_lock);
11331132
}
11341133

11351134
static void __i915_vma_iounmap(struct i915_vma *vma)

0 commit comments

Comments
 (0)