Skip to content

Commit 700d6ab

Browse files
committed
Merge tag 'drm-intel-next-fixes-2020-03-27' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
Fixes for instability on Baytrail and Haswell; Ice Lake RPS; Sandy Bridge RC6; and few others around GT hangchec/reset; livelock; and a null dereference. Signed-off-by: Dave Airlie <[email protected]> From: Rodrigo Vivi <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents c0ca543 + 2bdd4c2 commit 700d6ab

16 files changed

+108
-36
lines changed

drivers/gpu/drm/i915/display/intel_display.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14748,8 +14748,8 @@ static int intel_atomic_check(struct drm_device *dev,
1474814748
/* Catch I915_MODE_FLAG_INHERITED */
1474914749
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
1475014750
new_crtc_state, i) {
14751-
if (new_crtc_state->hw.mode.private_flags !=
14752-
old_crtc_state->hw.mode.private_flags)
14751+
if (new_crtc_state->uapi.mode.private_flags !=
14752+
old_crtc_state->uapi.mode.private_flags)
1475314753
new_crtc_state->uapi.mode_changed = true;
1475414754
}
1475514755

drivers/gpu/drm/i915/gem/i915_gem_context.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ static void engines_idle_release(struct i915_gem_context *ctx,
574574
int err = 0;
575575

576576
/* serialises with execbuf */
577-
RCU_INIT_POINTER(ce->gem_context, NULL);
577+
set_bit(CONTEXT_CLOSED_BIT, &ce->flags);
578578
if (!intel_context_pin_if_active(ce))
579579
continue;
580580

drivers/gpu/drm/i915/gem/i915_gem_context.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,16 @@ i915_gem_context_unlock_engines(struct i915_gem_context *ctx)
192192
static inline struct intel_context *
193193
i915_gem_context_get_engine(struct i915_gem_context *ctx, unsigned int idx)
194194
{
195-
struct intel_context *ce = ERR_PTR(-EINVAL);
195+
struct intel_context *ce;
196196

197197
rcu_read_lock(); {
198198
struct i915_gem_engines *e = rcu_dereference(ctx->engines);
199-
if (likely(idx < e->num_engines && e->engines[idx]))
199+
if (unlikely(!e)) /* context was closed! */
200+
ce = ERR_PTR(-ENOENT);
201+
else if (likely(idx < e->num_engines && e->engines[idx]))
200202
ce = intel_context_get(e->engines[idx]);
203+
else
204+
ce = ERR_PTR(-EINVAL);
201205
} rcu_read_unlock();
202206

203207
return ce;

drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2316,7 +2316,7 @@ static void eb_request_add(struct i915_execbuffer *eb)
23162316
prev = __i915_request_commit(rq);
23172317

23182318
/* Check that the context wasn't destroyed before submission */
2319-
if (likely(rcu_access_pointer(eb->context->gem_context))) {
2319+
if (likely(!intel_context_is_closed(eb->context))) {
23202320
attr = eb->gem_context->sched;
23212321

23222322
/*

drivers/gpu/drm/i915/gt/intel_context.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ int __intel_context_do_pin(struct intel_context *ce)
9797
{
9898
int err;
9999

100+
GEM_BUG_ON(intel_context_is_closed(ce));
101+
100102
if (unlikely(!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) {
101103
err = intel_context_alloc_state(ce);
102104
if (err)

drivers/gpu/drm/i915/gt/intel_context.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,11 @@ static inline bool intel_context_is_barrier(const struct intel_context *ce)
173173
return test_bit(CONTEXT_BARRIER_BIT, &ce->flags);
174174
}
175175

176+
static inline bool intel_context_is_closed(const struct intel_context *ce)
177+
{
178+
return test_bit(CONTEXT_CLOSED_BIT, &ce->flags);
179+
}
180+
176181
static inline bool intel_context_use_semaphores(const struct intel_context *ce)
177182
{
178183
return test_bit(CONTEXT_USE_SEMAPHORES, &ce->flags);

drivers/gpu/drm/i915/gt/intel_context_types.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,11 @@ struct intel_context {
6262
#define CONTEXT_BARRIER_BIT 0
6363
#define CONTEXT_ALLOC_BIT 1
6464
#define CONTEXT_VALID_BIT 2
65-
#define CONTEXT_USE_SEMAPHORES 3
66-
#define CONTEXT_BANNED 4
67-
#define CONTEXT_FORCE_SINGLE_SUBMISSION 5
68-
#define CONTEXT_NOPREEMPT 6
65+
#define CONTEXT_CLOSED_BIT 3
66+
#define CONTEXT_USE_SEMAPHORES 4
67+
#define CONTEXT_BANNED 5
68+
#define CONTEXT_FORCE_SINGLE_SUBMISSION 6
69+
#define CONTEXT_NOPREEMPT 7
6970

7071
u32 *lrc_reg_state;
7172
u64 lrc_desc;

drivers/gpu/drm/i915/gt/intel_lrc.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,17 +1663,27 @@ static bool virtual_matches(const struct virtual_engine *ve,
16631663
}
16641664

16651665
static void virtual_xfer_breadcrumbs(struct virtual_engine *ve,
1666-
struct intel_engine_cs *engine)
1666+
struct i915_request *rq)
16671667
{
16681668
struct intel_engine_cs *old = ve->siblings[0];
16691669

16701670
/* All unattached (rq->engine == old) must already be completed */
16711671

16721672
spin_lock(&old->breadcrumbs.irq_lock);
16731673
if (!list_empty(&ve->context.signal_link)) {
1674-
list_move_tail(&ve->context.signal_link,
1675-
&engine->breadcrumbs.signalers);
1676-
intel_engine_signal_breadcrumbs(engine);
1674+
list_del_init(&ve->context.signal_link);
1675+
1676+
/*
1677+
* We cannot acquire the new engine->breadcrumbs.irq_lock
1678+
* (as we are holding a breadcrumbs.irq_lock already),
1679+
* so attach this request to the signaler on submission.
1680+
* The queued irq_work will occur when we finally drop
1681+
* the engine->active.lock after dequeue.
1682+
*/
1683+
set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &rq->fence.flags);
1684+
1685+
/* Also transfer the pending irq_work for the old breadcrumb. */
1686+
intel_engine_signal_breadcrumbs(rq->engine);
16771687
}
16781688
spin_unlock(&old->breadcrumbs.irq_lock);
16791689
}
@@ -2045,7 +2055,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
20452055
engine);
20462056

20472057
if (!list_empty(&ve->context.signals))
2048-
virtual_xfer_breadcrumbs(ve, engine);
2058+
virtual_xfer_breadcrumbs(ve, rq);
20492059

20502060
/*
20512061
* Move the bound engine to the top of the list

drivers/gpu/drm/i915/gt/intel_rc6.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ void intel_rc6_unpark(struct intel_rc6 *rc6)
603603
void intel_rc6_park(struct intel_rc6 *rc6)
604604
{
605605
struct intel_uncore *uncore = rc6_to_uncore(rc6);
606+
unsigned int target;
606607

607608
if (!rc6->enabled)
608609
return;
@@ -617,7 +618,14 @@ void intel_rc6_park(struct intel_rc6 *rc6)
617618

618619
/* Turn off the HW timers and go directly to rc6 */
619620
set(uncore, GEN6_RC_CONTROL, GEN6_RC_CTL_RC6_ENABLE);
620-
set(uncore, GEN6_RC_STATE, 0x4 << RC_SW_TARGET_STATE_SHIFT);
621+
622+
if (HAS_RC6pp(rc6_to_i915(rc6)))
623+
target = 0x6; /* deepest rc6 */
624+
else if (HAS_RC6p(rc6_to_i915(rc6)))
625+
target = 0x5; /* deep rc6 */
626+
else
627+
target = 0x4; /* normal rc6 */
628+
set(uncore, GEN6_RC_STATE, target << RC_SW_TARGET_STATE_SHIFT);
621629
}
622630

623631
void intel_rc6_disable(struct intel_rc6 *rc6)

drivers/gpu/drm/i915/gt/intel_reset.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ static bool mark_guilty(struct i915_request *rq)
8888
bool banned;
8989
int i;
9090

91+
if (intel_context_is_closed(rq->context)) {
92+
intel_context_set_banned(rq->context);
93+
return true;
94+
}
95+
9196
rcu_read_lock();
9297
ctx = rcu_dereference(rq->context->gem_context);
9398
if (ctx && !kref_get_unless_zero(&ctx->ref))

0 commit comments

Comments
 (0)