196593096SVille Syrjälä // SPDX-License-Identifier: MIT 296593096SVille Syrjälä /* Copyright © 2025 Intel Corporation */ 396593096SVille Syrjälä 496593096SVille Syrjälä #include "i915_drv.h" 596593096SVille Syrjälä #include "i915_gem_object_frontbuffer.h" 696593096SVille Syrjälä 796593096SVille Syrjälä static int frontbuffer_active(struct i915_active *ref) 896593096SVille Syrjälä { 996593096SVille Syrjälä struct i915_frontbuffer *front = 1096593096SVille Syrjälä container_of(ref, typeof(*front), write); 1196593096SVille Syrjälä 1296593096SVille Syrjälä kref_get(&front->ref); 1396593096SVille Syrjälä return 0; 1496593096SVille Syrjälä } 1596593096SVille Syrjälä 1696593096SVille Syrjälä static void frontbuffer_retire(struct i915_active *ref) 1796593096SVille Syrjälä { 1896593096SVille Syrjälä struct i915_frontbuffer *front = 1996593096SVille Syrjälä container_of(ref, typeof(*front), write); 2096593096SVille Syrjälä 2196593096SVille Syrjälä intel_frontbuffer_flush(&front->base, ORIGIN_CS); 2296593096SVille Syrjälä i915_gem_object_frontbuffer_put(front); 2396593096SVille Syrjälä } 2496593096SVille Syrjälä 2596593096SVille Syrjälä struct i915_frontbuffer * 2696593096SVille Syrjälä i915_gem_object_frontbuffer_get(struct drm_i915_gem_object *obj) 2796593096SVille Syrjälä { 2896593096SVille Syrjälä struct drm_i915_private *i915 = to_i915(obj->base.dev); 2996593096SVille Syrjälä struct i915_frontbuffer *front, *cur; 3096593096SVille Syrjälä 31*f85cd99eSVille Syrjälä front = i915_gem_object_frontbuffer_lookup(obj); 3296593096SVille Syrjälä if (front) 3396593096SVille Syrjälä return front; 3496593096SVille Syrjälä 3596593096SVille Syrjälä front = kmalloc(sizeof(*front), GFP_KERNEL); 3696593096SVille Syrjälä if (!front) 3796593096SVille Syrjälä return NULL; 3896593096SVille Syrjälä 3996593096SVille Syrjälä intel_frontbuffer_init(&front->base, &i915->drm); 4096593096SVille Syrjälä 4196593096SVille Syrjälä kref_init(&front->ref); 4296593096SVille Syrjälä i915_gem_object_get(obj); 4396593096SVille Syrjälä front->obj = obj; 4496593096SVille Syrjälä 4596593096SVille Syrjälä i915_active_init(&front->write, 4696593096SVille Syrjälä frontbuffer_active, 4796593096SVille Syrjälä frontbuffer_retire, 4896593096SVille Syrjälä I915_ACTIVE_RETIRE_SLEEPS); 4996593096SVille Syrjälä 5096593096SVille Syrjälä spin_lock(&i915->frontbuffer_lock); 5196593096SVille Syrjälä if (rcu_access_pointer(obj->frontbuffer)) { 5296593096SVille Syrjälä cur = rcu_dereference_protected(obj->frontbuffer, true); 5396593096SVille Syrjälä kref_get(&cur->ref); 5496593096SVille Syrjälä } else { 5596593096SVille Syrjälä cur = front; 5696593096SVille Syrjälä rcu_assign_pointer(obj->frontbuffer, front); 5796593096SVille Syrjälä } 5896593096SVille Syrjälä spin_unlock(&i915->frontbuffer_lock); 5996593096SVille Syrjälä 6096593096SVille Syrjälä if (cur != front) { 6196593096SVille Syrjälä i915_gem_object_put(obj); 6296593096SVille Syrjälä intel_frontbuffer_fini(&front->base); 6396593096SVille Syrjälä kfree(front); 6496593096SVille Syrjälä } 6596593096SVille Syrjälä 6696593096SVille Syrjälä return cur; 6796593096SVille Syrjälä } 6896593096SVille Syrjälä 6996593096SVille Syrjälä void i915_gem_object_frontbuffer_ref(struct i915_frontbuffer *front) 7096593096SVille Syrjälä { 7196593096SVille Syrjälä kref_get(&front->ref); 7296593096SVille Syrjälä } 7396593096SVille Syrjälä 7496593096SVille Syrjälä static void frontbuffer_release(struct kref *ref) 7596593096SVille Syrjälä __releases(&i915->frontbuffer_lock) 7696593096SVille Syrjälä { 7796593096SVille Syrjälä struct i915_frontbuffer *front = 7896593096SVille Syrjälä container_of(ref, typeof(*front), ref); 7996593096SVille Syrjälä struct drm_i915_gem_object *obj = front->obj; 8096593096SVille Syrjälä struct drm_i915_private *i915 = to_i915(obj->base.dev); 8196593096SVille Syrjälä 8296593096SVille Syrjälä i915_ggtt_clear_scanout(obj); 8396593096SVille Syrjälä 8496593096SVille Syrjälä RCU_INIT_POINTER(obj->frontbuffer, NULL); 8596593096SVille Syrjälä 8696593096SVille Syrjälä spin_unlock(&i915->frontbuffer_lock); 8796593096SVille Syrjälä 8896593096SVille Syrjälä i915_active_fini(&front->write); 8996593096SVille Syrjälä 9096593096SVille Syrjälä i915_gem_object_put(obj); 9196593096SVille Syrjälä 9296593096SVille Syrjälä intel_frontbuffer_fini(&front->base); 9396593096SVille Syrjälä 9496593096SVille Syrjälä kfree_rcu(front, rcu); 9596593096SVille Syrjälä } 9696593096SVille Syrjälä 9796593096SVille Syrjälä void i915_gem_object_frontbuffer_put(struct i915_frontbuffer *front) 9896593096SVille Syrjälä { 9996593096SVille Syrjälä struct drm_i915_private *i915 = to_i915(front->obj->base.dev); 10096593096SVille Syrjälä 10196593096SVille Syrjälä kref_put_lock(&front->ref, frontbuffer_release, 10296593096SVille Syrjälä &i915->frontbuffer_lock); 10396593096SVille Syrjälä } 104