xref: /linux/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.c (revision 24f171c7e145f43b9f187578e89b0982ce87e54c)
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