diff options
author | Dave Airlie <airlied@redhat.com> | 2021-01-22 10:08:57 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2021-01-22 10:08:58 +1000 |
commit | d82afcf9caaac26ce2642511115bca9dacf30f41 (patch) | |
tree | e084cc20577d3df73694ce69e8eb5f3e26bd0bf9 /drivers/gpu/drm/i915/i915_request.c | |
parent | a6b8720c2f85143561c3453e1cf928a2f8586ac0 (diff) | |
parent | 69b4b99842201bc24c98ba66b922d8879e190483 (diff) |
Merge tag 'drm-intel-gt-next-2021-01-21-1' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
Cross-subsystem Changes:
- Includes gvt-gt-next-2021-01-18 + header check fix for GVT
Driver Changes:
- Fix for #2955: Clear potentially malicious register state before
executing clear residuals security mitigation (Chris)
- Fixes that lead to marking per-engine-reset as supported on Gen7
(Chris)
- Remove per-client stats from debugfs/i915_gem_objects) (Tvrtko, Chris)
- Add arbitration check before semaphore wait (Chris)
- Apply interactive priority to explicit flip fences (Chris)
- Make GEM errors non-fatal by default to help capturing logs during
development (Chris)
- Fix object page offset within a region in error capture (CQ, Matt A)
- Close race between enable_breadcrumbs and cancel_breadcrumbs (Chris)
- Almagamate clflushes on suspend/freeze to speed up S/R (Chris)
- Protect used framebuffers from casual eviction (Chris)
- Fix the sgt.pfn sanity check (Kui, Matt A)
- Reduce locking around i915_request.lock and ctx->engines_mutex (Chris)
- Simplify tracking for engine->fw_active and stats.active (Chris)
- Constrain pool objects by mapping type (Chris, Matt A)
- Use shrinkable status for unknown swizzle quirks (Chris)
- Do not suspend bonded requests if one hangs (Chris)
- Restore "Skip over completed active execlists" optimization (Chris)
- Move stolen node into GEM object union (Chris)
. Split gem_create into own file (Matt A)
- Convert object_create into object_init in LMEM region code (Matt A)
- Reduce test_and_set_bit to set_bit in i915_request_submit() (Chris)
- Mark up protected uses of 'i915_request_completed' (Chris)
- Remove extraneous inline modifiers (Chris)
- Add function to define defaults for GuC/HuC enable (John)
- Improve code locality by moving closer to single user (Matt A, Chris)
- Compiler warning fixes (Matt A, Chris)
- Selftest / CI improvements (Chris)
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210121150747.GA58732@jlahtine-mobl.ger.corp.intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/i915_request.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_request.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 0b1a46a0d866..22e39d938f17 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -276,7 +276,7 @@ static void remove_from_engine(struct i915_request *rq) bool i915_request_retire(struct i915_request *rq) { - if (!i915_request_completed(rq)) + if (!__i915_request_is_complete(rq)) return false; RQ_TRACE(rq, "\n"); @@ -342,8 +342,7 @@ void i915_request_retire_upto(struct i915_request *rq) struct i915_request *tmp; RQ_TRACE(rq, "\n"); - - GEM_BUG_ON(!i915_request_completed(rq)); + GEM_BUG_ON(!__i915_request_is_complete(rq)); do { tmp = list_first_entry(&tl->requests, typeof(*tmp), link); @@ -552,8 +551,10 @@ bool __i915_request_submit(struct i915_request *request) * dropped upon retiring. (Otherwise if resubmit a *retired* * request, this would be a horrible use-after-free.) */ - if (i915_request_completed(request)) - goto xfer; + if (__i915_request_is_complete(request)) { + list_del_init(&request->sched.link); + goto active; + } if (unlikely(intel_context_is_banned(request->context))) i915_request_set_error_once(request, -EIO); @@ -588,11 +589,11 @@ bool __i915_request_submit(struct i915_request *request) engine->serial++; result = true; -xfer: - if (!test_and_set_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags)) { - list_move_tail(&request->sched.link, &engine->active.requests); - clear_bit(I915_FENCE_FLAG_PQUEUE, &request->fence.flags); - } + GEM_BUG_ON(test_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags)); + list_move_tail(&request->sched.link, &engine->active.requests); +active: + clear_bit(I915_FENCE_FLAG_PQUEUE, &request->fence.flags); + set_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags); /* * XXX Rollback bonded-execution on __i915_request_unsubmit()? @@ -652,7 +653,7 @@ void __i915_request_unsubmit(struct i915_request *request) i915_request_cancel_breadcrumb(request); /* We've already spun, don't charge on resubmitting. */ - if (request->sched.semaphores && i915_request_started(request)) + if (request->sched.semaphores && __i915_request_has_started(request)) request->sched.semaphores = 0; /* @@ -864,7 +865,7 @@ __i915_request_create(struct intel_context *ce, gfp_t gfp) RCU_INIT_POINTER(rq->timeline, tl); RCU_INIT_POINTER(rq->hwsp_cacheline, tl->hwsp_cacheline); rq->hwsp_seqno = tl->hwsp_seqno; - GEM_BUG_ON(i915_request_completed(rq)); + GEM_BUG_ON(__i915_request_is_complete(rq)); rq->rcustate = get_state_synchronize_rcu(); /* acts as smp_mb() */ @@ -970,15 +971,22 @@ i915_request_await_start(struct i915_request *rq, struct i915_request *signal) if (i915_request_started(signal)) return 0; + /* + * The caller holds a reference on @signal, but we do not serialise + * against it being retired and removed from the lists. + * + * We do not hold a reference to the request before @signal, and + * so must be very careful to ensure that it is not _recycled_ as + * we follow the link backwards. + */ fence = NULL; rcu_read_lock(); - spin_lock_irq(&signal->lock); do { struct list_head *pos = READ_ONCE(signal->link.prev); struct i915_request *prev; /* Confirm signal has not been retired, the link is valid */ - if (unlikely(i915_request_started(signal))) + if (unlikely(__i915_request_has_started(signal))) break; /* Is signal the earliest request on its timeline? */ @@ -1003,7 +1011,6 @@ i915_request_await_start(struct i915_request *rq, struct i915_request *signal) fence = &prev->fence; } while (0); - spin_unlock_irq(&signal->lock); rcu_read_unlock(); if (!fence) return 0; @@ -1520,7 +1527,7 @@ __i915_request_add_to_timeline(struct i915_request *rq) */ prev = to_request(__i915_active_fence_set(&timeline->last_request, &rq->fence)); - if (prev && !i915_request_completed(prev)) { + if (prev && !__i915_request_is_complete(prev)) { /* * The requests are supposed to be kept in order. However, * we need to be wary in case the timeline->last_request @@ -1897,10 +1904,10 @@ static char queue_status(const struct i915_request *rq) static const char *run_status(const struct i915_request *rq) { - if (i915_request_completed(rq)) + if (__i915_request_is_complete(rq)) return "!"; - if (i915_request_started(rq)) + if (__i915_request_has_started(rq)) return "*"; if (!i915_sw_fence_signaled(&rq->semaphore)) |