Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <airlied@redhat.com>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200327081607.GA3082710@intel.com

+110 -38
+2 -2
drivers/gpu/drm/i915/display/intel_display.c
··· 14748 14748 /* Catch I915_MODE_FLAG_INHERITED */ 14749 14749 for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, 14750 14750 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) 14753 14753 new_crtc_state->uapi.mode_changed = true; 14754 14754 } 14755 14755
+1 -1
drivers/gpu/drm/i915/gem/i915_gem_context.c
··· 574 574 int err = 0; 575 575 576 576 /* serialises with execbuf */ 577 - RCU_INIT_POINTER(ce->gem_context, NULL); 577 + set_bit(CONTEXT_CLOSED_BIT, &ce->flags); 578 578 if (!intel_context_pin_if_active(ce)) 579 579 continue; 580 580
+6 -2
drivers/gpu/drm/i915/gem/i915_gem_context.h
··· 192 192 static inline struct intel_context * 193 193 i915_gem_context_get_engine(struct i915_gem_context *ctx, unsigned int idx) 194 194 { 195 - struct intel_context *ce = ERR_PTR(-EINVAL); 195 + struct intel_context *ce; 196 196 197 197 rcu_read_lock(); { 198 198 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])) 200 202 ce = intel_context_get(e->engines[idx]); 203 + else 204 + ce = ERR_PTR(-EINVAL); 201 205 } rcu_read_unlock(); 202 206 203 207 return ce;
+1 -1
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
··· 2316 2316 prev = __i915_request_commit(rq); 2317 2317 2318 2318 /* 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))) { 2320 2320 attr = eb->gem_context->sched; 2321 2321 2322 2322 /*
+2
drivers/gpu/drm/i915/gt/intel_context.c
··· 97 97 { 98 98 int err; 99 99 100 + GEM_BUG_ON(intel_context_is_closed(ce)); 101 + 100 102 if (unlikely(!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) { 101 103 err = intel_context_alloc_state(ce); 102 104 if (err)
+5
drivers/gpu/drm/i915/gt/intel_context.h
··· 173 173 return test_bit(CONTEXT_BARRIER_BIT, &ce->flags); 174 174 } 175 175 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 + 176 181 static inline bool intel_context_use_semaphores(const struct intel_context *ce) 177 182 { 178 183 return test_bit(CONTEXT_USE_SEMAPHORES, &ce->flags);
+5 -4
drivers/gpu/drm/i915/gt/intel_context_types.h
··· 62 62 #define CONTEXT_BARRIER_BIT 0 63 63 #define CONTEXT_ALLOC_BIT 1 64 64 #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 69 70 70 71 u32 *lrc_reg_state; 71 72 u64 lrc_desc;
+15 -5
drivers/gpu/drm/i915/gt/intel_lrc.c
··· 1663 1663 } 1664 1664 1665 1665 static void virtual_xfer_breadcrumbs(struct virtual_engine *ve, 1666 - struct intel_engine_cs *engine) 1666 + struct i915_request *rq) 1667 1667 { 1668 1668 struct intel_engine_cs *old = ve->siblings[0]; 1669 1669 ··· 1671 1671 1672 1672 spin_lock(&old->breadcrumbs.irq_lock); 1673 1673 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); 1677 1687 } 1678 1688 spin_unlock(&old->breadcrumbs.irq_lock); 1679 1689 } ··· 2055 2045 engine); 2056 2046 2057 2047 if (!list_empty(&ve->context.signals)) 2058 - virtual_xfer_breadcrumbs(ve, engine); 2048 + virtual_xfer_breadcrumbs(ve, rq); 2059 2049 2060 2050 /* 2061 2051 * Move the bound engine to the top of the list
+9 -1
drivers/gpu/drm/i915/gt/intel_rc6.c
··· 603 603 void intel_rc6_park(struct intel_rc6 *rc6) 604 604 { 605 605 struct intel_uncore *uncore = rc6_to_uncore(rc6); 606 + unsigned int target; 606 607 607 608 if (!rc6->enabled) 608 609 return; ··· 618 617 619 618 /* Turn off the HW timers and go directly to rc6 */ 620 619 set(uncore, GEN6_RC_CONTROL, GEN6_RC_CTL_RC6_ENABLE); 621 - set(uncore, GEN6_RC_STATE, 0x4 << RC_SW_TARGET_STATE_SHIFT); 620 + 621 + if (HAS_RC6pp(rc6_to_i915(rc6))) 622 + target = 0x6; /* deepest rc6 */ 623 + else if (HAS_RC6p(rc6_to_i915(rc6))) 624 + target = 0x5; /* deep rc6 */ 625 + else 626 + target = 0x4; /* normal rc6 */ 627 + set(uncore, GEN6_RC_STATE, target << RC_SW_TARGET_STATE_SHIFT); 622 628 } 623 629 624 630 void intel_rc6_disable(struct intel_rc6 *rc6)
+5
drivers/gpu/drm/i915/gt/intel_reset.c
··· 88 88 bool banned; 89 89 int i; 90 90 91 + if (intel_context_is_closed(rq->context)) { 92 + intel_context_set_banned(rq->context); 93 + return true; 94 + } 95 + 91 96 rcu_read_lock(); 92 97 ctx = rcu_dereference(rq->context->gem_context); 93 98 if (ctx && !kref_get_unless_zero(&ctx->ref))
+1 -1
drivers/gpu/drm/i915/gt/intel_ring_submission.c
··· 2088 2088 2089 2089 GEM_BUG_ON(timeline->hwsp_ggtt != engine->status_page.vma); 2090 2090 2091 - if (IS_GEN(engine->i915, 7) && engine->class == RENDER_CLASS) { 2091 + if (IS_HASWELL(engine->i915) && engine->class == RENDER_CLASS) { 2092 2092 err = gen7_ctx_switch_bb_init(engine); 2093 2093 if (err) 2094 2094 goto err_ring_unpin;
+13
drivers/gpu/drm/i915/gt/intel_rps.c
··· 770 770 intel_uncore_forcewake_get(rps_to_uncore(rps), FORCEWAKE_MEDIA); 771 771 rps_set(rps, rps->idle_freq, false); 772 772 intel_uncore_forcewake_put(rps_to_uncore(rps), FORCEWAKE_MEDIA); 773 + 774 + /* 775 + * Since we will try and restart from the previously requested 776 + * frequency on unparking, treat this idle point as a downclock 777 + * interrupt and reduce the frequency for resume. If we park/unpark 778 + * more frequently than the rps worker can run, we will not respond 779 + * to any EI and never see a change in frequency. 780 + * 781 + * (Note we accommodate Cherryview's limitation of only using an 782 + * even bin by applying it to all.) 783 + */ 784 + rps->cur_freq = 785 + max_t(int, round_down(rps->cur_freq - 1, 2), rps->min_freq); 773 786 } 774 787 775 788 void intel_rps_boost(struct i915_request *rq)
+19 -4
drivers/gpu/drm/i915/gt/selftest_rc6.c
··· 12 12 13 13 #include "selftests/i915_random.h" 14 14 15 + static u64 rc6_residency(struct intel_rc6 *rc6) 16 + { 17 + u64 result; 18 + 19 + /* XXX VLV_GT_MEDIA_RC6? */ 20 + 21 + result = intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6); 22 + if (HAS_RC6p(rc6_to_i915(rc6))) 23 + result += intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6p); 24 + if (HAS_RC6pp(rc6_to_i915(rc6))) 25 + result += intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6pp); 26 + 27 + return result; 28 + } 29 + 15 30 int live_rc6_manual(void *arg) 16 31 { 17 32 struct intel_gt *gt = arg; ··· 53 38 __intel_rc6_disable(rc6); 54 39 msleep(1); /* wakeup is not immediate, takes about 100us on icl */ 55 40 56 - res[0] = intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6); 41 + res[0] = rc6_residency(rc6); 57 42 msleep(250); 58 - res[1] = intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6); 43 + res[1] = rc6_residency(rc6); 59 44 if ((res[1] - res[0]) >> 10) { 60 45 pr_err("RC6 residency increased by %lldus while disabled for 250ms!\n", 61 46 (res[1] - res[0]) >> 10); ··· 66 51 /* Manually enter RC6 */ 67 52 intel_rc6_park(rc6); 68 53 69 - res[0] = intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6); 54 + res[0] = rc6_residency(rc6); 70 55 msleep(100); 71 - res[1] = intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6); 56 + res[1] = rc6_residency(rc6); 72 57 73 58 if (res[1] == res[0]) { 74 59 pr_err("Did not enter RC6! RC6_STATE=%08x, RC6_CONTROL=%08x, residency=%lld\n",
+8
drivers/gpu/drm/i915/i915_perf.c
··· 2700 2700 50)) 2701 2701 drm_err(&stream->perf->i915->drm, 2702 2702 "wait for OA to be disabled timed out\n"); 2703 + 2704 + intel_uncore_write(uncore, GEN12_OA_TLB_INV_CR, 1); 2705 + if (intel_wait_for_register(uncore, 2706 + GEN12_OA_TLB_INV_CR, 2707 + 1, 0, 2708 + 50)) 2709 + drm_err(&stream->perf->i915->drm, 2710 + "wait for OA tlb invalidate timed out\n"); 2703 2711 } 2704 2712 2705 2713 /**
+2
drivers/gpu/drm/i915/i915_reg.h
··· 693 693 #define OABUFFER_SIZE_8M (6 << 3) 694 694 #define OABUFFER_SIZE_16M (7 << 3) 695 695 696 + #define GEN12_OA_TLB_INV_CR _MMIO(0xceec) 697 + 696 698 /* Gen12 OAR unit */ 697 699 #define GEN12_OAR_OACONTROL _MMIO(0x2960) 698 700 #define GEN12_OAR_OACONTROL_COUNTER_FORMAT_SHIFT 1
+16 -17
drivers/gpu/drm/i915/i915_vma.c
··· 1097 1097 void i915_vma_parked(struct intel_gt *gt) 1098 1098 { 1099 1099 struct i915_vma *vma, *next; 1100 + LIST_HEAD(closed); 1100 1101 1101 1102 spin_lock_irq(&gt->closed_lock); 1102 1103 list_for_each_entry_safe(vma, next, &gt->closed_vma, closed_link) { ··· 1109 1108 if (!kref_get_unless_zero(&obj->base.refcount)) 1110 1109 continue; 1111 1110 1112 - if (i915_vm_tryopen(vm)) { 1113 - list_del_init(&vma->closed_link); 1114 - } else { 1111 + if (!i915_vm_tryopen(vm)) { 1115 1112 i915_gem_object_put(obj); 1116 - obj = NULL; 1113 + continue; 1117 1114 } 1118 1115 1119 - spin_unlock_irq(&gt->closed_lock); 1120 - 1121 - if (obj) { 1122 - __i915_vma_put(vma); 1123 - i915_gem_object_put(obj); 1124 - } 1125 - 1126 - i915_vm_close(vm); 1127 - 1128 - /* Restart after dropping lock */ 1129 - spin_lock_irq(&gt->closed_lock); 1130 - next = list_first_entry(&gt->closed_vma, 1131 - typeof(*next), closed_link); 1116 + list_move(&vma->closed_link, &closed); 1132 1117 } 1133 1118 spin_unlock_irq(&gt->closed_lock); 1119 + 1120 + /* As the GT is held idle, no vma can be reopened as we destroy them */ 1121 + list_for_each_entry_safe(vma, next, &closed, closed_link) { 1122 + struct drm_i915_gem_object *obj = vma->obj; 1123 + struct i915_address_space *vm = vma->vm; 1124 + 1125 + INIT_LIST_HEAD(&vma->closed_link); 1126 + __i915_vma_put(vma); 1127 + 1128 + i915_gem_object_put(obj); 1129 + i915_vm_close(vm); 1130 + } 1134 1131 } 1135 1132 1136 1133 static void __i915_vma_iounmap(struct i915_vma *vma)