Skip to content

Commit 760039c

Browse files
vsyrjalarodrigovivi
authored andcommitted
drm/i915/frontbuffer: Move bo refcounting intel_frontbuffer_{get,release}()
Currently xe's intel_frontbuffer implementation forgets to hold a reference on the bo. This makes the entire thing extremely fragile as the cleanup order now depends on bo references held by other things (namely intel_fb_bo_framebuffer_fini()). Move the bo refcounting to intel_frontbuffer_{get,release}() so that both i915 and xe do this the same way. I first tried to fix this by having xe do the refcounting from its intel_bo_set_frontbuffer() implementation (which is what i915 does currently), but turns out xe's drm_gem_object_free() can sleep and thus drm_gem_object_put() isn't safe to call while we hold fb_tracking.lock. Fixes: 10690b8 ("drm/i915/display: Add intel_fb_bo_framebuffer_fini") Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Jani Nikula <[email protected]> (cherry picked from commit eb4d490) Signed-off-by: Rodrigo Vivi <[email protected]>
1 parent 1696b0c commit 760039c

2 files changed

Lines changed: 9 additions & 3 deletions

File tree

drivers/gpu/drm/i915/display/intel_frontbuffer.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ static void frontbuffer_release(struct kref *ref)
270270
spin_unlock(&display->fb_tracking.lock);
271271

272272
i915_active_fini(&front->write);
273+
274+
drm_gem_object_put(obj);
273275
kfree_rcu(front, rcu);
274276
}
275277

@@ -287,6 +289,8 @@ intel_frontbuffer_get(struct drm_gem_object *obj)
287289
if (!front)
288290
return NULL;
289291

292+
drm_gem_object_get(obj);
293+
290294
front->obj = obj;
291295
kref_init(&front->ref);
292296
atomic_set(&front->bits, 0);
@@ -299,8 +303,12 @@ intel_frontbuffer_get(struct drm_gem_object *obj)
299303
spin_lock(&display->fb_tracking.lock);
300304
cur = intel_bo_set_frontbuffer(obj, front);
301305
spin_unlock(&display->fb_tracking.lock);
302-
if (cur != front)
306+
307+
if (cur != front) {
308+
drm_gem_object_put(obj);
303309
kfree(front);
310+
}
311+
304312
return cur;
305313
}
306314

drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,10 @@ i915_gem_object_set_frontbuffer(struct drm_i915_gem_object *obj,
8989

9090
if (!front) {
9191
RCU_INIT_POINTER(obj->frontbuffer, NULL);
92-
drm_gem_object_put(intel_bo_to_drm_bo(obj));
9392
} else if (rcu_access_pointer(obj->frontbuffer)) {
9493
cur = rcu_dereference_protected(obj->frontbuffer, true);
9594
kref_get(&cur->ref);
9695
} else {
97-
drm_gem_object_get(intel_bo_to_drm_bo(obj));
9896
rcu_assign_pointer(obj->frontbuffer, front);
9997
}
10098

0 commit comments

Comments
 (0)