Commit 40320844 authored by Jouni Högander's avatar Jouni Högander

drm/i915: Add new frontbuffer tracking interface to queue flush

We want to wait dma fences in dirtyfb ioctl. As we don't want to make
dirtyfb ioctl as blocking call we need to use
dma_fence_add_callback. Callback used for dma_fence_add_callback is
called from atomic context. Due to this we need to add a new
frontbuffer tracking interface to queue flush.

v3:
 - Check schedule work success rather than work being pending
 - Init flush work when frontbuffer struct is initialized
v2: Check if flush work is already pending
Signed-off-by: default avatarJouni Högander <jouni.hogander@intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230901093500.3463046-4-jouni.hogander@intel.com
parent 35a97f56
...@@ -203,6 +203,33 @@ void __intel_fb_flush(struct intel_frontbuffer *front, ...@@ -203,6 +203,33 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
frontbuffer_flush(i915, frontbuffer_bits, origin); frontbuffer_flush(i915, frontbuffer_bits, origin);
} }
static void intel_frontbuffer_flush_work(struct work_struct *work)
{
struct intel_frontbuffer *front =
container_of(work, struct intel_frontbuffer, flush_work);
i915_gem_object_flush_if_display(front->obj);
intel_frontbuffer_flush(front, ORIGIN_DIRTYFB);
intel_frontbuffer_put(front);
}
/**
* intel_frontbuffer_queue_flush - queue flushing frontbuffer object
* @front: GEM object to flush
*
* This function is targeted for our dirty callback for queueing flush when
* dma fence is signales
*/
void intel_frontbuffer_queue_flush(struct intel_frontbuffer *front)
{
if (!front)
return;
kref_get(&front->ref);
if (!schedule_work(&front->flush_work))
intel_frontbuffer_put(front);
}
static int frontbuffer_active(struct i915_active *ref) static int frontbuffer_active(struct i915_active *ref)
{ {
struct intel_frontbuffer *front = struct intel_frontbuffer *front =
...@@ -262,6 +289,7 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj) ...@@ -262,6 +289,7 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj)
frontbuffer_active, frontbuffer_active,
frontbuffer_retire, frontbuffer_retire,
I915_ACTIVE_RETIRE_SLEEPS); I915_ACTIVE_RETIRE_SLEEPS);
INIT_WORK(&front->flush_work, intel_frontbuffer_flush_work);
spin_lock(&i915->display.fb_tracking.lock); spin_lock(&i915->display.fb_tracking.lock);
cur = i915_gem_object_set_frontbuffer(obj, front); cur = i915_gem_object_set_frontbuffer(obj, front);
......
...@@ -46,6 +46,8 @@ struct intel_frontbuffer { ...@@ -46,6 +46,8 @@ struct intel_frontbuffer {
struct i915_active write; struct i915_active write;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
struct rcu_head rcu; struct rcu_head rcu;
struct work_struct flush_work;
}; };
/* /*
...@@ -135,6 +137,8 @@ static inline void intel_frontbuffer_flush(struct intel_frontbuffer *front, ...@@ -135,6 +137,8 @@ static inline void intel_frontbuffer_flush(struct intel_frontbuffer *front,
__intel_fb_flush(front, origin, frontbuffer_bits); __intel_fb_flush(front, origin, frontbuffer_bits);
} }
void intel_frontbuffer_queue_flush(struct intel_frontbuffer *front);
void intel_frontbuffer_track(struct intel_frontbuffer *old, void intel_frontbuffer_track(struct intel_frontbuffer *old,
struct intel_frontbuffer *new, struct intel_frontbuffer *new,
unsigned int frontbuffer_bits); unsigned int frontbuffer_bits);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment