diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_frontbuffer.h')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_frontbuffer.h | 34 | 
1 files changed, 31 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.h b/drivers/gpu/drm/i915/display/intel_frontbuffer.h index adc64d61a4a5..6d41f5394425 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.h +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.h @@ -27,10 +27,10 @@  #include <linux/atomic.h>  #include <linux/kref.h> +#include "gem/i915_gem_object_types.h"  #include "i915_active.h"  struct drm_i915_private; -struct drm_i915_gem_object;  enum fb_op_origin {  	ORIGIN_GTT, @@ -45,6 +45,7 @@ struct intel_frontbuffer {  	atomic_t bits;  	struct i915_active write;  	struct drm_i915_gem_object *obj; +	struct rcu_head rcu;  };  void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915, @@ -54,6 +55,35 @@ void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,  void intel_frontbuffer_flip(struct drm_i915_private *i915,  			    unsigned frontbuffer_bits); +void intel_frontbuffer_put(struct intel_frontbuffer *front); + +static inline struct intel_frontbuffer * +__intel_frontbuffer_get(const struct drm_i915_gem_object *obj) +{ +	struct intel_frontbuffer *front; + +	if (likely(!rcu_access_pointer(obj->frontbuffer))) +		return NULL; + +	rcu_read_lock(); +	do { +		front = rcu_dereference(obj->frontbuffer); +		if (!front) +			break; + +		if (unlikely(!kref_get_unless_zero(&front->ref))) +			continue; + +		if (likely(front == rcu_access_pointer(obj->frontbuffer))) +			break; + +		intel_frontbuffer_put(front); +	} while (1); +	rcu_read_unlock(); + +	return front; +} +  struct intel_frontbuffer *  intel_frontbuffer_get(struct drm_i915_gem_object *obj); @@ -119,6 +149,4 @@ void intel_frontbuffer_track(struct intel_frontbuffer *old,  			     struct intel_frontbuffer *new,  			     unsigned int frontbuffer_bits); -void intel_frontbuffer_put(struct intel_frontbuffer *front); -  #endif /* __INTEL_FRONTBUFFER_H__ */  |