105 lines · c
1/* SPDX-License-Identifier: MIT */2/*3 * Copyright © 2023 Intel Corporation4 */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 15void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,16 enum fb_op_origin origin);17void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj,18 enum fb_op_origin origin);19 20static inline void21i915_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 28static inline void29i915_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 frontbuffer38 * @obj: The object whose frontbuffer to get.39 *40 * Get pointer to object's frontbuffer if such exists. Please note that RCU41 * mechanism is used to handle e.g. ongoing removal of frontbuffer pointer.42 *43 * Return: pointer to object's frontbuffer is such exists or NULL44 */45static inline struct intel_frontbuffer *46i915_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 frontbuffer74 * @obj: The object whose frontbuffer to set.75 * @front: The frontbuffer to set76 *77 * Set object's frontbuffer pointer. If frontbuffer is already set for the78 * object keep it and return it's pointer to the caller. Please note that RCU79 * mechanism is used to handle e.g. ongoing removal of frontbuffer pointer. This80 * function is protected by i915->display.fb_tracking.lock81 *82 * Return: pointer to frontbuffer which was set.83 */84static inline struct intel_frontbuffer *85i915_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#endif105