xref: /linux/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.h (revision 6dfafbd0299a60bfb5d5e277fdf100037c7ded07)
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 
15 struct 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 
23 void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,
24 					 enum fb_op_origin origin);
25 void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj,
26 					      enum fb_op_origin origin);
27 
28 static inline void
29 i915_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 
36 static inline void
37 i915_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 
44 struct i915_frontbuffer *i915_gem_object_frontbuffer_get(struct drm_i915_gem_object *obj);
45 void i915_gem_object_frontbuffer_ref(struct i915_frontbuffer *front);
46 void 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  */
57 static inline struct i915_frontbuffer *
58 i915_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