]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/frontbuffer: Split fb_tracking.lock into two
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 16 Oct 2025 18:54:04 +0000 (21:54 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 7 Nov 2025 15:38:02 +0000 (17:38 +0200)
Our fb_tracking.lock is serving a double duty:
- protects fb_tracking.busy_bits
- provides the write-side protection for obj->frontbuffer

Split obj->frontbuffer role into a separate lock so that
we can clean up the current mess with the frontbuffer lifetime
management.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/20251016185408.22735-7-ville.syrjala@linux.intel.com
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/display/intel_display_core.h
drivers/gpu/drm/i915/display/intel_display_driver.c
drivers/gpu/drm/i915/display/intel_frontbuffer.c
drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.h

index 2eb742ab5222e0c2ce20eb2062d9be611096e7ff..9e53ae599cf01802c26e4b6d1c95119b5568960c 100644 (file)
@@ -142,6 +142,10 @@ struct intel_dpll_global {
 };
 
 struct intel_frontbuffer_tracking {
+       /* protects obj->frontbuffer (write-side) */
+       spinlock_t frontbuffer_lock;
+
+       /* protects busy_bits */
        spinlock_t lock;
 
        /*
index eb0727b9a0f697cd3c9cca084ba838c356ded4b6..c7a74b0df25f0f9c439c5d5496647017aff074d5 100644 (file)
@@ -186,6 +186,7 @@ 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);
index bdf8bfa7deb991c33eb51d754ac28b4da201b77b..02b06dfb9fee7126f9380efd5423a6aa1d20eed2 100644 (file)
@@ -210,7 +210,7 @@ static void frontbuffer_retire(struct i915_active *ref)
 }
 
 static void frontbuffer_release(struct kref *ref)
-       __releases(&to_intel_display(front->obj->dev)->fb_tracking.lock)
+       __releases(&to_intel_display(front->obj->dev)->fb_tracking.frontbuffer_lock)
 {
        struct intel_frontbuffer *ret, *front =
                container_of(ref, typeof(*front), ref);
@@ -223,7 +223,7 @@ static void frontbuffer_release(struct kref *ref)
 
        ret = intel_bo_set_frontbuffer(obj, NULL);
        drm_WARN_ON(display->drm, ret);
-       spin_unlock(&display->fb_tracking.lock);
+       spin_unlock(&display->fb_tracking.frontbuffer_lock);
 
        i915_active_fini(&front->write);
 
@@ -256,9 +256,9 @@ intel_frontbuffer_get(struct drm_gem_object *obj)
                         I915_ACTIVE_RETIRE_SLEEPS);
        INIT_WORK(&front->flush_work, intel_frontbuffer_flush_work);
 
-       spin_lock(&display->fb_tracking.lock);
+       spin_lock(&display->fb_tracking.frontbuffer_lock);
        cur = intel_bo_set_frontbuffer(obj, front);
-       spin_unlock(&display->fb_tracking.lock);
+       spin_unlock(&display->fb_tracking.frontbuffer_lock);
 
        if (cur != front) {
                drm_gem_object_put(obj);
@@ -272,7 +272,7 @@ void intel_frontbuffer_put(struct intel_frontbuffer *front)
 {
        kref_put_lock(&front->ref,
                      frontbuffer_release,
-                     &to_intel_display(front->obj->dev)->fb_tracking.lock);
+                     &to_intel_display(front->obj->dev)->fb_tracking.frontbuffer_lock);
 }
 
 /**
index b682969e3a293c2b40b14b4a229cdd9e45fc3d21..1ec382c43aee09537baba1ef23a98519410e26b1 100644 (file)
@@ -77,7 +77,7 @@ i915_gem_object_get_frontbuffer(const struct drm_i915_gem_object *obj)
  * Set object's frontbuffer pointer. If frontbuffer is already set for the
  * object keep it and return it's pointer to the caller. Please note that RCU
  * mechanism is used to handle e.g. ongoing removal of frontbuffer pointer. This
- * function is protected by i915->display->fb_tracking.lock
+ * function is protected by i915->display->fb_tracking.frontbuffer_lock
  *
  * Return: pointer to frontbuffer which was set.
  */