Commit 96593096 authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

drm/i915/frontbuffer: Fix intel_frontbuffer lifetime handling



The current attempted split between xe/i915 vs. display
for intel_frontbuffer is a mess:
- the i915 rcu leaks through the interface to the display side
- the obj->frontbuffer write-side is now protected by a display
  specific spinlock even though the actual obj->framebuffer
  pointer lives in a i915 specific structure
- the kref is getting poked directly from both sides
- i915_active is still on the display side

Clean up the mess by moving everything about the frontbuffer
lifetime management to the i915/xe side:
- the rcu usage is now completely contained in i915
- frontbuffer_lock is moved into i915
- kref is on the i915/xe side (xe needs the refcount as well
  due to intel_frontbuffer_queue_flush()->intel_frontbuffer_ref())
- the bo (and its refcounting) is no longer on the display side
- i915_active is contained in i915

I was pondering whether we could do this in some kind of smaller
steps, and perhaps we could, but it would probably have to start
with a bunch of reverts (which for sure won't go cleanly anymore).
So not convinced it's worth the hassle.

Acked-by: default avatarJani Nikula <jani.nikula@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/20251016185408.22735-10-ville.syrjala@linux.intel.com
parent 8f1ddb02
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -156,6 +156,7 @@ gem-y += \
	gem/i915_gem_lmem.o \
	gem/i915_gem_mman.o \
	gem/i915_gem_object.o \
	gem/i915_gem_object_frontbuffer.o \
	gem/i915_gem_pages.o \
	gem/i915_gem_phys.o \
	gem/i915_gem_pm.o \
+27 −7
Original line number Diff line number Diff line
@@ -39,20 +39,40 @@ int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, i
	return i915_gem_object_read_from_page(to_intel_bo(obj), offset, dst, size);
}

struct intel_frontbuffer *intel_bo_get_frontbuffer(struct drm_gem_object *obj)
struct intel_frontbuffer *intel_bo_frontbuffer_get(struct drm_gem_object *_obj)
{
	return i915_gem_object_get_frontbuffer(to_intel_bo(obj));
	struct drm_i915_gem_object *obj = to_intel_bo(_obj);
	struct i915_frontbuffer *front;

	front = i915_gem_object_frontbuffer_get(obj);
	if (!front)
		return NULL;

	return &front->base;
}

void intel_bo_frontbuffer_ref(struct intel_frontbuffer *_front)
{
	struct i915_frontbuffer *front =
		container_of(_front, typeof(*front), base);

	i915_gem_object_frontbuffer_ref(front);
}

struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj,
						   struct intel_frontbuffer *front)
void intel_bo_frontbuffer_put(struct intel_frontbuffer *_front)
{
	return i915_gem_object_set_frontbuffer(to_intel_bo(obj), front);
	struct i915_frontbuffer *front =
		container_of(_front, typeof(*front), base);

	return i915_gem_object_frontbuffer_put(front);
}

void intel_bo_frontbuffer_flush_for_display(struct intel_frontbuffer *front)
void intel_bo_frontbuffer_flush_for_display(struct intel_frontbuffer *_front)
{
	i915_gem_object_flush_if_display(to_intel_bo(front->obj));
	struct i915_frontbuffer *front =
		container_of(_front, typeof(*front), base);

	i915_gem_object_flush_if_display(front->obj);
}

void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj)
+3 −3
Original line number Diff line number Diff line
@@ -19,9 +19,9 @@ bool intel_bo_is_protected(struct drm_gem_object *obj);
int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, int size);

struct intel_frontbuffer *intel_bo_get_frontbuffer(struct drm_gem_object *obj);
struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj,
						   struct intel_frontbuffer *front);
struct intel_frontbuffer *intel_bo_frontbuffer_get(struct drm_gem_object *obj);
void intel_bo_frontbuffer_ref(struct intel_frontbuffer *front);
void intel_bo_frontbuffer_put(struct intel_frontbuffer *front);
void intel_bo_frontbuffer_flush_for_display(struct intel_frontbuffer *front);

void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj);
+0 −3
Original line number Diff line number Diff line
@@ -142,9 +142,6 @@ struct intel_dpll_global {
};

struct intel_frontbuffer_tracking {
	/* protects obj->frontbuffer (write-side) */
	spinlock_t frontbuffer_lock;

	/* protects busy_bits */
	spinlock_t lock;

+0 −1
Original line number Diff line number Diff line
@@ -186,7 +186,6 @@ void intel_display_driver_early_probe(struct intel_display *display)
	if (!HAS_DISPLAY(display))
		return;

	spin_lock_init(&display->fb_tracking.frontbuffer_lock);
	spin_lock_init(&display->fb_tracking.lock);
	mutex_init(&display->backlight.lock);
	mutex_init(&display->audio.mutex);
Loading