Commit 29e6ecf3 authored by Chris Wilson's avatar Chris Wilson

drm/i915: Extend i915_request_await_active to use all timelines

Extend i915_request_await_active() to be able to asynchronously wait on
all the tracked timelines simultaneously.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200311092044.16353-1-chris@chris-wilson.co.uk
parent 61f874d6
...@@ -518,25 +518,81 @@ int i915_active_wait(struct i915_active *ref) ...@@ -518,25 +518,81 @@ int i915_active_wait(struct i915_active *ref)
return 0; return 0;
} }
int i915_request_await_active(struct i915_request *rq, struct i915_active *ref) static int __await_active(struct i915_active_fence *active,
int (*fn)(void *arg, struct dma_fence *fence),
void *arg)
{
struct dma_fence *fence;
if (is_barrier(active)) /* XXX flush the barrier? */
return 0;
fence = i915_active_fence_get(active);
if (fence) {
int err;
err = fn(arg, fence);
dma_fence_put(fence);
if (err < 0)
return err;
}
return 0;
}
static int await_active(struct i915_active *ref,
unsigned int flags,
int (*fn)(void *arg, struct dma_fence *fence),
void *arg)
{ {
int err = 0; int err = 0;
/* We must always wait for the exclusive fence! */
if (rcu_access_pointer(ref->excl.fence)) { if (rcu_access_pointer(ref->excl.fence)) {
struct dma_fence *fence; err = __await_active(&ref->excl, fn, arg);
if (err)
rcu_read_lock(); return err;
fence = dma_fence_get_rcu_safe(&ref->excl.fence); }
rcu_read_unlock();
if (fence) { if (flags & I915_ACTIVE_AWAIT_ALL && i915_active_acquire_if_busy(ref)) {
err = i915_request_await_dma_fence(rq, fence); struct active_node *it, *n;
dma_fence_put(fence);
rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
err = __await_active(&it->base, fn, arg);
if (err)
break;
} }
i915_active_release(ref);
if (err)
return err;
} }
/* In the future we may choose to await on all fences */ return 0;
}
return err; static int rq_await_fence(void *arg, struct dma_fence *fence)
{
return i915_request_await_dma_fence(arg, fence);
}
int i915_request_await_active(struct i915_request *rq,
struct i915_active *ref,
unsigned int flags)
{
return await_active(ref, flags, rq_await_fence, rq);
}
static int sw_await_fence(void *arg, struct dma_fence *fence)
{
return i915_sw_fence_await_dma_fence(arg, fence, 0,
GFP_NOWAIT | __GFP_NOWARN);
}
int i915_sw_fence_await_active(struct i915_sw_fence *fence,
struct i915_active *ref,
unsigned int flags)
{
return await_active(ref, flags, sw_await_fence, fence);
} }
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
......
...@@ -183,7 +183,13 @@ static inline bool i915_active_has_exclusive(struct i915_active *ref) ...@@ -183,7 +183,13 @@ static inline bool i915_active_has_exclusive(struct i915_active *ref)
int i915_active_wait(struct i915_active *ref); int i915_active_wait(struct i915_active *ref);
int i915_request_await_active(struct i915_request *rq, struct i915_active *ref); int i915_sw_fence_await_active(struct i915_sw_fence *fence,
struct i915_active *ref,
unsigned int flags);
int i915_request_await_active(struct i915_request *rq,
struct i915_active *ref,
unsigned int flags);
#define I915_ACTIVE_AWAIT_ALL BIT(0)
int i915_active_acquire(struct i915_active *ref); int i915_active_acquire(struct i915_active *ref);
bool i915_active_acquire_if_busy(struct i915_active *ref); bool i915_active_acquire_if_busy(struct i915_active *ref);
......
...@@ -1173,7 +1173,7 @@ int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *rq) ...@@ -1173,7 +1173,7 @@ int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *rq)
GEM_BUG_ON(!i915_vma_is_pinned(vma)); GEM_BUG_ON(!i915_vma_is_pinned(vma));
/* Wait for the vma to be bound before we start! */ /* Wait for the vma to be bound before we start! */
err = i915_request_await_active(rq, &vma->active); err = i915_request_await_active(rq, &vma->active, 0);
if (err) if (err)
return err; return err;
......
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