1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright © 2023 Intel Corporation
4 */
5
6#ifndef __I915_GEM_OBJECT_FRONTBUFFER_H__
7#define __I915_GEM_OBJECT_FRONTBUFFER_H__
8
9#include <linux/kref.h>
10#include <linux/rcupdate.h>
11
12#include "display/intel_frontbuffer.h"
13#include "i915_gem_object_types.h"
14
15struct i915_frontbuffer {
16 struct intel_frontbuffer base;
17 struct drm_i915_gem_object *obj;
18 struct i915_active write;
19 struct rcu_head rcu;
20 struct kref ref;
21};
22
23void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,
24 enum fb_op_origin origin);
25void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj,
26 enum fb_op_origin origin);
27
28static inline void
29i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,
30 enum fb_op_origin origin)
31{
32 if (unlikely(rcu_access_pointer(obj->frontbuffer)))
33 __i915_gem_object_flush_frontbuffer(obj, origin);
34}
35
36static inline void
37i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj,
38 enum fb_op_origin origin)
39{
40 if (unlikely(rcu_access_pointer(obj->frontbuffer)))
41 __i915_gem_object_invalidate_frontbuffer(obj, origin);
42}
43
44struct i915_frontbuffer *i915_gem_object_frontbuffer_get(struct drm_i915_gem_object *obj);
45void i915_gem_object_frontbuffer_ref(struct i915_frontbuffer *front);
46void i915_gem_object_frontbuffer_put(struct i915_frontbuffer *front);
47
48/**
49 * i915_gem_object_frontbuffer_lookup - Look up the object's frontbuffer
50 * @obj: The object whose frontbuffer to look up.
51 *
52 * Get pointer to object's frontbuffer if such exists. Please note that RCU
53 * mechanism is used to handle e.g. ongoing removal of frontbuffer pointer.
54 *
55 * Return: pointer to object's frontbuffer is such exists or NULL
56 */
57static inline struct i915_frontbuffer *
58i915_gem_object_frontbuffer_lookup(const struct drm_i915_gem_object *obj)
59{
60 struct i915_frontbuffer *front;
61
62 if (likely(!rcu_access_pointer(obj->frontbuffer)))
63 return NULL;
64
65 rcu_read_lock();
66 do {
67 front = rcu_dereference(obj->frontbuffer);
68 if (!front)
69 break;
70
71 if (unlikely(!kref_get_unless_zero(&front->ref)))
72 continue;
73
74 if (likely(front == rcu_access_pointer(obj->frontbuffer)))
75 break;
76
77 i915_gem_object_frontbuffer_put(front);
78 } while (1);
79 rcu_read_unlock();
80
81 return front;
82}
83
84#endif
85

source code of linux/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.h