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 void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj, 16 enum fb_op_origin origin); 17 void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj, 18 enum fb_op_origin origin); 19 20 static inline void 21 i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj, 22 enum fb_op_origin origin) 23 { 24 if (unlikely(rcu_access_pointer(obj->frontbuffer))) 25 __i915_gem_object_flush_frontbuffer(obj, origin); 26 } 27 28 static inline void 29 i915_gem_object_invalidate_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_invalidate_frontbuffer(obj, origin); 34 } 35 36 /** 37 * i915_gem_object_get_frontbuffer - Get the object's frontbuffer 38 * @obj: The object whose frontbuffer to get. 39 * 40 * Get pointer to object's frontbuffer if such exists. Please note that RCU 41 * mechanism is used to handle e.g. ongoing removal of frontbuffer pointer. 42 * 43 * Return: pointer to object's frontbuffer is such exists or NULL 44 */ 45 static inline struct intel_frontbuffer * 46 i915_gem_object_get_frontbuffer(const struct drm_i915_gem_object *obj) 47 { 48 struct intel_frontbuffer *front; 49 50 if (likely(!rcu_access_pointer(obj->frontbuffer))) 51 return NULL; 52 53 rcu_read_lock(); 54 do { 55 front = rcu_dereference(obj->frontbuffer); 56 if (!front) 57 break; 58 59 if (unlikely(!kref_get_unless_zero(&front->ref))) 60 continue; 61 62 if (likely(front == rcu_access_pointer(obj->frontbuffer))) 63 break; 64 65 intel_frontbuffer_put(front); 66 } while (1); 67 rcu_read_unlock(); 68 69 return front; 70 } 71 72 /** 73 * i915_gem_object_set_frontbuffer - Set the object's frontbuffer 74 * @obj: The object whose frontbuffer to set. 75 * @front: The frontbuffer to set 76 * 77 * Set object's frontbuffer pointer. If frontbuffer is already set for the 78 * object keep it and return it's pointer to the caller. Please note that RCU 79 * mechanism is used to handle e.g. ongoing removal of frontbuffer pointer. This 80 * function is protected by i915->display.fb_tracking.lock 81 * 82 * Return: pointer to frontbuffer which was set. 83 */ 84 static inline struct intel_frontbuffer * 85 i915_gem_object_set_frontbuffer(struct drm_i915_gem_object *obj, 86 struct intel_frontbuffer *front) 87 { 88 struct intel_frontbuffer *cur = front; 89 90 if (!front) { 91 RCU_INIT_POINTER(obj->frontbuffer, NULL); 92 drm_gem_object_put(intel_bo_to_drm_bo(obj)); 93 } else if (rcu_access_pointer(obj->frontbuffer)) { 94 cur = rcu_dereference_protected(obj->frontbuffer, true); 95 kref_get(&cur->ref); 96 } else { 97 drm_gem_object_get(intel_bo_to_drm_bo(obj)); 98 rcu_assign_pointer(obj->frontbuffer, front); 99 } 100 101 return cur; 102 } 103 104 #endif 105