File Index
Files and directories
Sign in
FILE

i915_gem_object_frontbuffer.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.c C
  1// SPDX-License-Identifier: MIT
  2/* Copyright © 2025 Intel Corporation */
  3
  4#include "i915_drv.h"
  5#include "i915_gem_object_frontbuffer.h"
  6
  7static int frontbuffer_active(struct i915_active *ref)
  8{
  9	struct i915_frontbuffer *front =
 10		container_of(ref, typeof(*front), write);
 11
 12	kref_get(&front->ref);
 13	return 0;
 14}
 15
 16static void frontbuffer_retire(struct i915_active *ref)
 17{
 18	struct i915_frontbuffer *front =
 19		container_of(ref, typeof(*front), write);
 20
 21	intel_frontbuffer_flush(&front->base, ORIGIN_CS);
 22	i915_gem_object_frontbuffer_put(front);
 23}
 24
 25struct i915_frontbuffer *
 26i915_gem_object_frontbuffer_get(struct drm_i915_gem_object *obj)
 27{
 28	struct drm_i915_private *i915 = to_i915(obj->base.dev);
 29	struct i915_frontbuffer *front, *cur;
 30
 31	front = i915_gem_object_frontbuffer_lookup(obj);
 32	if (front)
 33		return front;
 34
 35	front = kmalloc(sizeof(*front), GFP_KERNEL);
 36	if (!front)
 37		return NULL;
 38
 39	intel_frontbuffer_init(&front->base, &i915->drm);
 40
 41	kref_init(&front->ref);
 42	i915_gem_object_get(obj);
 43	front->obj = obj;
 44
 45	i915_active_init(&front->write,
 46			 frontbuffer_active,
 47			 frontbuffer_retire,
 48			 I915_ACTIVE_RETIRE_SLEEPS);
 49
 50	spin_lock(&i915->frontbuffer_lock);
 51	if (rcu_access_pointer(obj->frontbuffer)) {
 52		cur = rcu_dereference_protected(obj->frontbuffer, true);
 53		kref_get(&cur->ref);
 54	} else {
 55		cur = front;
 56		rcu_assign_pointer(obj->frontbuffer, front);
 57	}
 58	spin_unlock(&i915->frontbuffer_lock);
 59
 60	if (cur != front) {
 61		i915_gem_object_put(obj);
 62		intel_frontbuffer_fini(&front->base);
 63		kfree(front);
 64	}
 65
 66	return cur;
 67}
 68
 69void i915_gem_object_frontbuffer_ref(struct i915_frontbuffer *front)
 70{
 71	kref_get(&front->ref);
 72}
 73
 74static void frontbuffer_release(struct kref *ref)
 75	__releases(&i915->frontbuffer_lock)
 76{
 77	struct i915_frontbuffer *front =
 78		container_of(ref, typeof(*front), ref);
 79	struct drm_i915_gem_object *obj = front->obj;
 80	struct drm_i915_private *i915 = to_i915(obj->base.dev);
 81
 82	i915_ggtt_clear_scanout(obj);
 83
 84	RCU_INIT_POINTER(obj->frontbuffer, NULL);
 85
 86	spin_unlock(&i915->frontbuffer_lock);
 87
 88	i915_active_fini(&front->write);
 89
 90	i915_gem_object_put(obj);
 91
 92	intel_frontbuffer_fini(&front->base);
 93
 94	kfree_rcu(front, rcu);
 95}
 96
 97void i915_gem_object_frontbuffer_put(struct i915_frontbuffer *front)
 98{
 99	struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
100
101	kref_put_lock(&front->ref, frontbuffer_release,
102		      &i915->frontbuffer_lock);
103}
~/ Read-only file preview.