diff options
author | Dave Airlie <airlied@redhat.com> | 2018-03-22 16:19:27 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2018-03-22 16:19:27 -0400 |
commit | b4eec0fa537165efc3265cdbb4bac06e6bdaf596 (patch) | |
tree | 1ab3efa433a3e3fd82ce24e958bf4984a3aa3b16 /drivers | |
parent | 2a2553cc45c889f15a1df0355891a809f17ca43d (diff) | |
parent | 8c5cb3c1c5701df8b8bcefb151547148378841e5 (diff) |
Merge tag 'drm-intel-next-fixes-2018-03-22' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
GVT regression fix that caused guest VM GPU hang.
Fix for race conditions in declaring GPU wedged (hit in CI).
* tag 'drm-intel-next-fixes-2018-03-22' of git://anongit.freedesktop.org/drm/drm-intel:
drm/i915/gvt: force to set all context control bits from guest
drm/i915/gvt: Update PDPs after a vGPU mm object is pinned.
drm/i915/gvt: Invalidate vGPU PPGTT mm objects during a vGPU reset.
drm/i915/kvmgt: Handle kzalloc failure
drm/i915/gvt: fix spelling mistake: "destoried" -> "destroyed"
drm/i915/gvt: Remove reduntant printing of untracked mmio
drm/i915/pmu: Work around compiler warnings on some kernel configs
drm/i915: Only call tasklet_kill() on the first prepare_reset
drm/i915: Wrap engine->schedule in RCU locks for set-wedge protection
drm/i915/icl: do not save DDI A/E sharing bit for ICL
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/gvt/gtt.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gvt/gtt.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gvt/handlers.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gvt/kvmgt.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gvt/scheduler.c | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gvt/vgpu.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_pmu.c | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_request.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 9 |
10 files changed, 119 insertions, 41 deletions
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 0a100a288e6d..d29281231507 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c | |||
@@ -2046,7 +2046,7 @@ static void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu) | |||
2046 | } | 2046 | } |
2047 | 2047 | ||
2048 | if (GEM_WARN_ON(!list_empty(&vgpu->gtt.ppgtt_mm_list_head))) | 2048 | if (GEM_WARN_ON(!list_empty(&vgpu->gtt.ppgtt_mm_list_head))) |
2049 | gvt_err("vgpu ppgtt mm is not fully destoried\n"); | 2049 | gvt_err("vgpu ppgtt mm is not fully destroyed\n"); |
2050 | 2050 | ||
2051 | if (GEM_WARN_ON(!radix_tree_empty(&vgpu->gtt.spt_tree))) { | 2051 | if (GEM_WARN_ON(!radix_tree_empty(&vgpu->gtt.spt_tree))) { |
2052 | gvt_err("Why we still has spt not freed?\n"); | 2052 | gvt_err("Why we still has spt not freed?\n"); |
@@ -2291,6 +2291,28 @@ void intel_gvt_clean_gtt(struct intel_gvt *gvt) | |||
2291 | } | 2291 | } |
2292 | 2292 | ||
2293 | /** | 2293 | /** |
2294 | * intel_vgpu_invalidate_ppgtt - invalidate PPGTT instances | ||
2295 | * @vgpu: a vGPU | ||
2296 | * | ||
2297 | * This function is called when invalidate all PPGTT instances of a vGPU. | ||
2298 | * | ||
2299 | */ | ||
2300 | void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu) | ||
2301 | { | ||
2302 | struct list_head *pos, *n; | ||
2303 | struct intel_vgpu_mm *mm; | ||
2304 | |||
2305 | list_for_each_safe(pos, n, &vgpu->gtt.ppgtt_mm_list_head) { | ||
2306 | mm = container_of(pos, struct intel_vgpu_mm, ppgtt_mm.list); | ||
2307 | if (mm->type == INTEL_GVT_MM_PPGTT) { | ||
2308 | list_del_init(&mm->ppgtt_mm.lru_list); | ||
2309 | if (mm->ppgtt_mm.shadowed) | ||
2310 | invalidate_ppgtt_mm(mm); | ||
2311 | } | ||
2312 | } | ||
2313 | } | ||
2314 | |||
2315 | /** | ||
2294 | * intel_vgpu_reset_ggtt - reset the GGTT entry | 2316 | * intel_vgpu_reset_ggtt - reset the GGTT entry |
2295 | * @vgpu: a vGPU | 2317 | * @vgpu: a vGPU |
2296 | * | 2318 | * |
diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h index e831507e17c3..a8b369cd352b 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.h +++ b/drivers/gpu/drm/i915/gvt/gtt.h | |||
@@ -194,6 +194,7 @@ struct intel_vgpu_gtt { | |||
194 | extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu); | 194 | extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu); |
195 | extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu); | 195 | extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu); |
196 | void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu); | 196 | void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu); |
197 | void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu); | ||
197 | 198 | ||
198 | extern int intel_gvt_init_gtt(struct intel_gvt *gvt); | 199 | extern int intel_gvt_init_gtt(struct intel_gvt *gvt); |
199 | void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu); | 200 | void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu); |
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 112f2ec7c25f..8c5d5d005854 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c | |||
@@ -1767,6 +1767,10 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) | |||
1767 | MMIO_D(CURBASE(PIPE_B), D_ALL); | 1767 | MMIO_D(CURBASE(PIPE_B), D_ALL); |
1768 | MMIO_D(CURBASE(PIPE_C), D_ALL); | 1768 | MMIO_D(CURBASE(PIPE_C), D_ALL); |
1769 | 1769 | ||
1770 | MMIO_D(CUR_FBC_CTL(PIPE_A), D_ALL); | ||
1771 | MMIO_D(CUR_FBC_CTL(PIPE_B), D_ALL); | ||
1772 | MMIO_D(CUR_FBC_CTL(PIPE_C), D_ALL); | ||
1773 | |||
1770 | MMIO_D(_MMIO(0x700ac), D_ALL); | 1774 | MMIO_D(_MMIO(0x700ac), D_ALL); |
1771 | MMIO_D(_MMIO(0x710ac), D_ALL); | 1775 | MMIO_D(_MMIO(0x710ac), D_ALL); |
1772 | MMIO_D(_MMIO(0x720ac), D_ALL); | 1776 | MMIO_D(_MMIO(0x720ac), D_ALL); |
@@ -2228,6 +2232,7 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) | |||
2228 | 2232 | ||
2229 | MMIO_D(HSW_AUD_CFG(PIPE_A), D_ALL); | 2233 | MMIO_D(HSW_AUD_CFG(PIPE_A), D_ALL); |
2230 | MMIO_D(HSW_AUD_PIN_ELD_CP_VLD, D_ALL); | 2234 | MMIO_D(HSW_AUD_PIN_ELD_CP_VLD, D_ALL); |
2235 | MMIO_D(HSW_AUD_MISC_CTRL(PIPE_A), D_ALL); | ||
2231 | 2236 | ||
2232 | MMIO_DH(_MMIO(_TRANS_DDI_FUNC_CTL_A), D_ALL, NULL, NULL); | 2237 | MMIO_DH(_MMIO(_TRANS_DDI_FUNC_CTL_A), D_ALL, NULL, NULL); |
2233 | MMIO_DH(_MMIO(_TRANS_DDI_FUNC_CTL_B), D_ALL, NULL, NULL); | 2238 | MMIO_DH(_MMIO(_TRANS_DDI_FUNC_CTL_B), D_ALL, NULL, NULL); |
@@ -2559,6 +2564,7 @@ static int init_broadwell_mmio_info(struct intel_gvt *gvt) | |||
2559 | MMIO_D(WM_MISC, D_BDW); | 2564 | MMIO_D(WM_MISC, D_BDW); |
2560 | MMIO_D(_MMIO(BDW_EDP_PSR_BASE), D_BDW); | 2565 | MMIO_D(_MMIO(BDW_EDP_PSR_BASE), D_BDW); |
2561 | 2566 | ||
2567 | MMIO_D(_MMIO(0x6671c), D_BDW_PLUS); | ||
2562 | MMIO_D(_MMIO(0x66c00), D_BDW_PLUS); | 2568 | MMIO_D(_MMIO(0x66c00), D_BDW_PLUS); |
2563 | MMIO_D(_MMIO(0x66c04), D_BDW_PLUS); | 2569 | MMIO_D(_MMIO(0x66c04), D_BDW_PLUS); |
2564 | 2570 | ||
@@ -2787,6 +2793,7 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) | |||
2787 | MMIO_D(_MMIO(0x70380), D_SKL_PLUS); | 2793 | MMIO_D(_MMIO(0x70380), D_SKL_PLUS); |
2788 | MMIO_D(_MMIO(0x71380), D_SKL_PLUS); | 2794 | MMIO_D(_MMIO(0x71380), D_SKL_PLUS); |
2789 | MMIO_D(_MMIO(0x72380), D_SKL_PLUS); | 2795 | MMIO_D(_MMIO(0x72380), D_SKL_PLUS); |
2796 | MMIO_D(_MMIO(0x7239c), D_SKL_PLUS); | ||
2790 | MMIO_D(_MMIO(0x7039c), D_SKL_PLUS); | 2797 | MMIO_D(_MMIO(0x7039c), D_SKL_PLUS); |
2791 | 2798 | ||
2792 | MMIO_D(_MMIO(0x8f074), D_SKL | D_KBL); | 2799 | MMIO_D(_MMIO(0x8f074), D_SKL | D_KBL); |
@@ -2801,7 +2808,9 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) | |||
2801 | MMIO_F(_MMIO(0xc800), 0x7f8, F_CMD_ACCESS, 0, 0, D_SKL | D_KBL, NULL, NULL); | 2808 | MMIO_F(_MMIO(0xc800), 0x7f8, F_CMD_ACCESS, 0, 0, D_SKL | D_KBL, NULL, NULL); |
2802 | MMIO_F(_MMIO(0xb020), 0x80, F_CMD_ACCESS, 0, 0, D_SKL | D_KBL, NULL, NULL); | 2809 | MMIO_F(_MMIO(0xb020), 0x80, F_CMD_ACCESS, 0, 0, D_SKL | D_KBL, NULL, NULL); |
2803 | 2810 | ||
2811 | MMIO_D(RPM_CONFIG0, D_SKL_PLUS); | ||
2804 | MMIO_D(_MMIO(0xd08), D_SKL_PLUS); | 2812 | MMIO_D(_MMIO(0xd08), D_SKL_PLUS); |
2813 | MMIO_D(RC6_LOCATION, D_SKL_PLUS); | ||
2805 | MMIO_DFH(_MMIO(0x20e0), D_SKL_PLUS, F_MODE_MASK, NULL, NULL); | 2814 | MMIO_DFH(_MMIO(0x20e0), D_SKL_PLUS, F_MODE_MASK, NULL, NULL); |
2806 | MMIO_DFH(_MMIO(0x20ec), D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); | 2815 | MMIO_DFH(_MMIO(0x20ec), D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); |
2807 | 2816 | ||
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 8a428678e4b5..520fe3d0a882 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c | |||
@@ -184,7 +184,7 @@ static struct gvt_dma *__gvt_cache_find_gfn(struct intel_vgpu *vgpu, gfn_t gfn) | |||
184 | return NULL; | 184 | return NULL; |
185 | } | 185 | } |
186 | 186 | ||
187 | static void __gvt_cache_add(struct intel_vgpu *vgpu, gfn_t gfn, | 187 | static int __gvt_cache_add(struct intel_vgpu *vgpu, gfn_t gfn, |
188 | dma_addr_t dma_addr) | 188 | dma_addr_t dma_addr) |
189 | { | 189 | { |
190 | struct gvt_dma *new, *itr; | 190 | struct gvt_dma *new, *itr; |
@@ -192,7 +192,7 @@ static void __gvt_cache_add(struct intel_vgpu *vgpu, gfn_t gfn, | |||
192 | 192 | ||
193 | new = kzalloc(sizeof(struct gvt_dma), GFP_KERNEL); | 193 | new = kzalloc(sizeof(struct gvt_dma), GFP_KERNEL); |
194 | if (!new) | 194 | if (!new) |
195 | return; | 195 | return -ENOMEM; |
196 | 196 | ||
197 | new->vgpu = vgpu; | 197 | new->vgpu = vgpu; |
198 | new->gfn = gfn; | 198 | new->gfn = gfn; |
@@ -229,6 +229,7 @@ static void __gvt_cache_add(struct intel_vgpu *vgpu, gfn_t gfn, | |||
229 | rb_insert_color(&new->dma_addr_node, &vgpu->vdev.dma_addr_cache); | 229 | rb_insert_color(&new->dma_addr_node, &vgpu->vdev.dma_addr_cache); |
230 | 230 | ||
231 | vgpu->vdev.nr_cache_entries++; | 231 | vgpu->vdev.nr_cache_entries++; |
232 | return 0; | ||
232 | } | 233 | } |
233 | 234 | ||
234 | static void __gvt_cache_remove_entry(struct intel_vgpu *vgpu, | 235 | static void __gvt_cache_remove_entry(struct intel_vgpu *vgpu, |
@@ -1586,11 +1587,12 @@ int kvmgt_dma_map_guest_page(unsigned long handle, unsigned long gfn, | |||
1586 | entry = __gvt_cache_find_gfn(info->vgpu, gfn); | 1587 | entry = __gvt_cache_find_gfn(info->vgpu, gfn); |
1587 | if (!entry) { | 1588 | if (!entry) { |
1588 | ret = gvt_dma_map_page(vgpu, gfn, dma_addr); | 1589 | ret = gvt_dma_map_page(vgpu, gfn, dma_addr); |
1589 | if (ret) { | 1590 | if (ret) |
1590 | mutex_unlock(&info->vgpu->vdev.cache_lock); | 1591 | goto err_unlock; |
1591 | return ret; | 1592 | |
1592 | } | 1593 | ret = __gvt_cache_add(info->vgpu, gfn, *dma_addr); |
1593 | __gvt_cache_add(info->vgpu, gfn, *dma_addr); | 1594 | if (ret) |
1595 | goto err_unmap; | ||
1594 | } else { | 1596 | } else { |
1595 | kref_get(&entry->ref); | 1597 | kref_get(&entry->ref); |
1596 | *dma_addr = entry->dma_addr; | 1598 | *dma_addr = entry->dma_addr; |
@@ -1598,6 +1600,12 @@ int kvmgt_dma_map_guest_page(unsigned long handle, unsigned long gfn, | |||
1598 | 1600 | ||
1599 | mutex_unlock(&info->vgpu->vdev.cache_lock); | 1601 | mutex_unlock(&info->vgpu->vdev.cache_lock); |
1600 | return 0; | 1602 | return 0; |
1603 | |||
1604 | err_unmap: | ||
1605 | gvt_dma_unmap_page(vgpu, gfn, *dma_addr); | ||
1606 | err_unlock: | ||
1607 | mutex_unlock(&info->vgpu->vdev.cache_lock); | ||
1608 | return ret; | ||
1601 | } | 1609 | } |
1602 | 1610 | ||
1603 | static void __gvt_dma_release(struct kref *ref) | 1611 | static void __gvt_dma_release(struct kref *ref) |
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 9b92b4e25a20..a55b4975c154 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c | |||
@@ -52,6 +52,29 @@ static void set_context_pdp_root_pointer( | |||
52 | pdp_pair[i].val = pdp[7 - i]; | 52 | pdp_pair[i].val = pdp[7 - i]; |
53 | } | 53 | } |
54 | 54 | ||
55 | static void update_shadow_pdps(struct intel_vgpu_workload *workload) | ||
56 | { | ||
57 | struct intel_vgpu *vgpu = workload->vgpu; | ||
58 | int ring_id = workload->ring_id; | ||
59 | struct i915_gem_context *shadow_ctx = vgpu->submission.shadow_ctx; | ||
60 | struct drm_i915_gem_object *ctx_obj = | ||
61 | shadow_ctx->engine[ring_id].state->obj; | ||
62 | struct execlist_ring_context *shadow_ring_context; | ||
63 | struct page *page; | ||
64 | |||
65 | if (WARN_ON(!workload->shadow_mm)) | ||
66 | return; | ||
67 | |||
68 | if (WARN_ON(!atomic_read(&workload->shadow_mm->pincount))) | ||
69 | return; | ||
70 | |||
71 | page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN); | ||
72 | shadow_ring_context = kmap(page); | ||
73 | set_context_pdp_root_pointer(shadow_ring_context, | ||
74 | (void *)workload->shadow_mm->ppgtt_mm.shadow_pdps); | ||
75 | kunmap(page); | ||
76 | } | ||
77 | |||
55 | static int populate_shadow_context(struct intel_vgpu_workload *workload) | 78 | static int populate_shadow_context(struct intel_vgpu_workload *workload) |
56 | { | 79 | { |
57 | struct intel_vgpu *vgpu = workload->vgpu; | 80 | struct intel_vgpu *vgpu = workload->vgpu; |
@@ -101,8 +124,14 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload) | |||
101 | #define COPY_REG(name) \ | 124 | #define COPY_REG(name) \ |
102 | intel_gvt_hypervisor_read_gpa(vgpu, workload->ring_context_gpa \ | 125 | intel_gvt_hypervisor_read_gpa(vgpu, workload->ring_context_gpa \ |
103 | + RING_CTX_OFF(name.val), &shadow_ring_context->name.val, 4) | 126 | + RING_CTX_OFF(name.val), &shadow_ring_context->name.val, 4) |
127 | #define COPY_REG_MASKED(name) {\ | ||
128 | intel_gvt_hypervisor_read_gpa(vgpu, workload->ring_context_gpa \ | ||
129 | + RING_CTX_OFF(name.val),\ | ||
130 | &shadow_ring_context->name.val, 4);\ | ||
131 | shadow_ring_context->name.val |= 0xffff << 16;\ | ||
132 | } | ||
104 | 133 | ||
105 | COPY_REG(ctx_ctrl); | 134 | COPY_REG_MASKED(ctx_ctrl); |
106 | COPY_REG(ctx_timestamp); | 135 | COPY_REG(ctx_timestamp); |
107 | 136 | ||
108 | if (ring_id == RCS) { | 137 | if (ring_id == RCS) { |
@@ -111,9 +140,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload) | |||
111 | COPY_REG(rcs_indirect_ctx_offset); | 140 | COPY_REG(rcs_indirect_ctx_offset); |
112 | } | 141 | } |
113 | #undef COPY_REG | 142 | #undef COPY_REG |
114 | 143 | #undef COPY_REG_MASKED | |
115 | set_context_pdp_root_pointer(shadow_ring_context, | ||
116 | (void *)workload->shadow_mm->ppgtt_mm.shadow_pdps); | ||
117 | 144 | ||
118 | intel_gvt_hypervisor_read_gpa(vgpu, | 145 | intel_gvt_hypervisor_read_gpa(vgpu, |
119 | workload->ring_context_gpa + | 146 | workload->ring_context_gpa + |
@@ -509,6 +536,8 @@ static int prepare_workload(struct intel_vgpu_workload *workload) | |||
509 | return ret; | 536 | return ret; |
510 | } | 537 | } |
511 | 538 | ||
539 | update_shadow_pdps(workload); | ||
540 | |||
512 | ret = intel_vgpu_sync_oos_pages(workload->vgpu); | 541 | ret = intel_vgpu_sync_oos_pages(workload->vgpu); |
513 | if (ret) { | 542 | if (ret) { |
514 | gvt_vgpu_err("fail to vgpu sync oos pages\n"); | 543 | gvt_vgpu_err("fail to vgpu sync oos pages\n"); |
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c index 41f76e86aa1f..2e0a02a80fe4 100644 --- a/drivers/gpu/drm/i915/gvt/vgpu.c +++ b/drivers/gpu/drm/i915/gvt/vgpu.c | |||
@@ -522,6 +522,7 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr, | |||
522 | /* full GPU reset or device model level reset */ | 522 | /* full GPU reset or device model level reset */ |
523 | if (engine_mask == ALL_ENGINES || dmlr) { | 523 | if (engine_mask == ALL_ENGINES || dmlr) { |
524 | intel_vgpu_select_submission_ops(vgpu, ALL_ENGINES, 0); | 524 | intel_vgpu_select_submission_ops(vgpu, ALL_ENGINES, 0); |
525 | intel_vgpu_invalidate_ppgtt(vgpu); | ||
525 | /*fence will not be reset during virtual reset */ | 526 | /*fence will not be reset during virtual reset */ |
526 | if (dmlr) { | 527 | if (dmlr) { |
527 | intel_vgpu_reset_gtt(vgpu); | 528 | intel_vgpu_reset_gtt(vgpu); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a5bd07338b46..0359d6f870b4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -471,10 +471,11 @@ static void __fence_set_priority(struct dma_fence *fence, int prio) | |||
471 | 471 | ||
472 | rq = to_request(fence); | 472 | rq = to_request(fence); |
473 | engine = rq->engine; | 473 | engine = rq->engine; |
474 | if (!engine->schedule) | ||
475 | return; | ||
476 | 474 | ||
477 | engine->schedule(rq, prio); | 475 | rcu_read_lock(); |
476 | if (engine->schedule) | ||
477 | engine->schedule(rq, prio); | ||
478 | rcu_read_unlock(); | ||
478 | } | 479 | } |
479 | 480 | ||
480 | static void fence_set_priority(struct dma_fence *fence, int prio) | 481 | static void fence_set_priority(struct dma_fence *fence, int prio) |
@@ -2939,8 +2940,16 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) | |||
2939 | * calling engine->init_hw() and also writing the ELSP. | 2940 | * calling engine->init_hw() and also writing the ELSP. |
2940 | * Turning off the execlists->tasklet until the reset is over | 2941 | * Turning off the execlists->tasklet until the reset is over |
2941 | * prevents the race. | 2942 | * prevents the race. |
2943 | * | ||
2944 | * Note that this needs to be a single atomic operation on the | ||
2945 | * tasklet (flush existing tasks, prevent new tasks) to prevent | ||
2946 | * a race between reset and set-wedged. It is not, so we do the best | ||
2947 | * we can atm and make sure we don't lock the machine up in the more | ||
2948 | * common case of recursively being called from set-wedged from inside | ||
2949 | * i915_reset. | ||
2942 | */ | 2950 | */ |
2943 | tasklet_kill(&engine->execlists.tasklet); | 2951 | if (!atomic_read(&engine->execlists.tasklet.count)) |
2952 | tasklet_kill(&engine->execlists.tasklet); | ||
2944 | tasklet_disable(&engine->execlists.tasklet); | 2953 | tasklet_disable(&engine->execlists.tasklet); |
2945 | 2954 | ||
2946 | /* | 2955 | /* |
@@ -3214,8 +3223,11 @@ void i915_gem_set_wedged(struct drm_i915_private *i915) | |||
3214 | */ | 3223 | */ |
3215 | for_each_engine(engine, i915, id) { | 3224 | for_each_engine(engine, i915, id) { |
3216 | i915_gem_reset_prepare_engine(engine); | 3225 | i915_gem_reset_prepare_engine(engine); |
3226 | |||
3217 | engine->submit_request = nop_submit_request; | 3227 | engine->submit_request = nop_submit_request; |
3228 | engine->schedule = NULL; | ||
3218 | } | 3229 | } |
3230 | i915->caps.scheduler = 0; | ||
3219 | 3231 | ||
3220 | /* | 3232 | /* |
3221 | * Make sure no one is running the old callback before we proceed with | 3233 | * Make sure no one is running the old callback before we proceed with |
@@ -3233,11 +3245,8 @@ void i915_gem_set_wedged(struct drm_i915_private *i915) | |||
3233 | * start to complete all requests. | 3245 | * start to complete all requests. |
3234 | */ | 3246 | */ |
3235 | engine->submit_request = nop_complete_submit_request; | 3247 | engine->submit_request = nop_complete_submit_request; |
3236 | engine->schedule = NULL; | ||
3237 | } | 3248 | } |
3238 | 3249 | ||
3239 | i915->caps.scheduler = 0; | ||
3240 | |||
3241 | /* | 3250 | /* |
3242 | * Make sure no request can slip through without getting completed by | 3251 | * Make sure no request can slip through without getting completed by |
3243 | * either this call here to intel_engine_init_global_seqno, or the one | 3252 | * either this call here to intel_engine_init_global_seqno, or the one |
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c index 964467b03e4d..d8feb9053e0c 100644 --- a/drivers/gpu/drm/i915/i915_pmu.c +++ b/drivers/gpu/drm/i915/i915_pmu.c | |||
@@ -433,7 +433,7 @@ static u64 __get_rc6(struct drm_i915_private *i915) | |||
433 | return val; | 433 | return val; |
434 | } | 434 | } |
435 | 435 | ||
436 | static u64 get_rc6(struct drm_i915_private *i915, bool locked) | 436 | static u64 get_rc6(struct drm_i915_private *i915) |
437 | { | 437 | { |
438 | #if IS_ENABLED(CONFIG_PM) | 438 | #if IS_ENABLED(CONFIG_PM) |
439 | unsigned long flags; | 439 | unsigned long flags; |
@@ -449,8 +449,7 @@ static u64 get_rc6(struct drm_i915_private *i915, bool locked) | |||
449 | * previously. | 449 | * previously. |
450 | */ | 450 | */ |
451 | 451 | ||
452 | if (!locked) | 452 | spin_lock_irqsave(&i915->pmu.lock, flags); |
453 | spin_lock_irqsave(&i915->pmu.lock, flags); | ||
454 | 453 | ||
455 | if (val >= i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) { | 454 | if (val >= i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) { |
456 | i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = 0; | 455 | i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = 0; |
@@ -459,12 +458,10 @@ static u64 get_rc6(struct drm_i915_private *i915, bool locked) | |||
459 | val = i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur; | 458 | val = i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur; |
460 | } | 459 | } |
461 | 460 | ||
462 | if (!locked) | 461 | spin_unlock_irqrestore(&i915->pmu.lock, flags); |
463 | spin_unlock_irqrestore(&i915->pmu.lock, flags); | ||
464 | } else { | 462 | } else { |
465 | struct pci_dev *pdev = i915->drm.pdev; | 463 | struct pci_dev *pdev = i915->drm.pdev; |
466 | struct device *kdev = &pdev->dev; | 464 | struct device *kdev = &pdev->dev; |
467 | unsigned long flags2; | ||
468 | 465 | ||
469 | /* | 466 | /* |
470 | * We are runtime suspended. | 467 | * We are runtime suspended. |
@@ -473,10 +470,8 @@ static u64 get_rc6(struct drm_i915_private *i915, bool locked) | |||
473 | * on top of the last known real value, as the approximated RC6 | 470 | * on top of the last known real value, as the approximated RC6 |
474 | * counter value. | 471 | * counter value. |
475 | */ | 472 | */ |
476 | if (!locked) | 473 | spin_lock_irqsave(&i915->pmu.lock, flags); |
477 | spin_lock_irqsave(&i915->pmu.lock, flags); | 474 | spin_lock(&kdev->power.lock); |
478 | |||
479 | spin_lock_irqsave(&kdev->power.lock, flags2); | ||
480 | 475 | ||
481 | if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) | 476 | if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) |
482 | i915->pmu.suspended_jiffies_last = | 477 | i915->pmu.suspended_jiffies_last = |
@@ -486,14 +481,13 @@ static u64 get_rc6(struct drm_i915_private *i915, bool locked) | |||
486 | i915->pmu.suspended_jiffies_last; | 481 | i915->pmu.suspended_jiffies_last; |
487 | val += jiffies - kdev->power.accounting_timestamp; | 482 | val += jiffies - kdev->power.accounting_timestamp; |
488 | 483 | ||
489 | spin_unlock_irqrestore(&kdev->power.lock, flags2); | 484 | spin_unlock(&kdev->power.lock); |
490 | 485 | ||
491 | val = jiffies_to_nsecs(val); | 486 | val = jiffies_to_nsecs(val); |
492 | val += i915->pmu.sample[__I915_SAMPLE_RC6].cur; | 487 | val += i915->pmu.sample[__I915_SAMPLE_RC6].cur; |
493 | i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val; | 488 | i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val; |
494 | 489 | ||
495 | if (!locked) | 490 | spin_unlock_irqrestore(&i915->pmu.lock, flags); |
496 | spin_unlock_irqrestore(&i915->pmu.lock, flags); | ||
497 | } | 491 | } |
498 | 492 | ||
499 | return val; | 493 | return val; |
@@ -502,7 +496,7 @@ static u64 get_rc6(struct drm_i915_private *i915, bool locked) | |||
502 | #endif | 496 | #endif |
503 | } | 497 | } |
504 | 498 | ||
505 | static u64 __i915_pmu_event_read(struct perf_event *event, bool locked) | 499 | static u64 __i915_pmu_event_read(struct perf_event *event) |
506 | { | 500 | { |
507 | struct drm_i915_private *i915 = | 501 | struct drm_i915_private *i915 = |
508 | container_of(event->pmu, typeof(*i915), pmu.base); | 502 | container_of(event->pmu, typeof(*i915), pmu.base); |
@@ -540,7 +534,7 @@ static u64 __i915_pmu_event_read(struct perf_event *event, bool locked) | |||
540 | val = count_interrupts(i915); | 534 | val = count_interrupts(i915); |
541 | break; | 535 | break; |
542 | case I915_PMU_RC6_RESIDENCY: | 536 | case I915_PMU_RC6_RESIDENCY: |
543 | val = get_rc6(i915, locked); | 537 | val = get_rc6(i915); |
544 | break; | 538 | break; |
545 | } | 539 | } |
546 | } | 540 | } |
@@ -555,7 +549,7 @@ static void i915_pmu_event_read(struct perf_event *event) | |||
555 | 549 | ||
556 | again: | 550 | again: |
557 | prev = local64_read(&hwc->prev_count); | 551 | prev = local64_read(&hwc->prev_count); |
558 | new = __i915_pmu_event_read(event, false); | 552 | new = __i915_pmu_event_read(event); |
559 | 553 | ||
560 | if (local64_cmpxchg(&hwc->prev_count, prev, new) != prev) | 554 | if (local64_cmpxchg(&hwc->prev_count, prev, new) != prev) |
561 | goto again; | 555 | goto again; |
@@ -605,14 +599,14 @@ static void i915_pmu_enable(struct perf_event *event) | |||
605 | engine->pmu.enable_count[sample]++; | 599 | engine->pmu.enable_count[sample]++; |
606 | } | 600 | } |
607 | 601 | ||
602 | spin_unlock_irqrestore(&i915->pmu.lock, flags); | ||
603 | |||
608 | /* | 604 | /* |
609 | * Store the current counter value so we can report the correct delta | 605 | * Store the current counter value so we can report the correct delta |
610 | * for all listeners. Even when the event was already enabled and has | 606 | * for all listeners. Even when the event was already enabled and has |
611 | * an existing non-zero value. | 607 | * an existing non-zero value. |
612 | */ | 608 | */ |
613 | local64_set(&event->hw.prev_count, __i915_pmu_event_read(event, true)); | 609 | local64_set(&event->hw.prev_count, __i915_pmu_event_read(event)); |
614 | |||
615 | spin_unlock_irqrestore(&i915->pmu.lock, flags); | ||
616 | } | 610 | } |
617 | 611 | ||
618 | static void i915_pmu_disable(struct perf_event *event) | 612 | static void i915_pmu_disable(struct perf_event *event) |
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index d437beac3969..282f57630cc1 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c | |||
@@ -1081,8 +1081,10 @@ void __i915_request_add(struct i915_request *request, bool flush_caches) | |||
1081 | * decide whether to preempt the entire chain so that it is ready to | 1081 | * decide whether to preempt the entire chain so that it is ready to |
1082 | * run at the earliest possible convenience. | 1082 | * run at the earliest possible convenience. |
1083 | */ | 1083 | */ |
1084 | rcu_read_lock(); | ||
1084 | if (engine->schedule) | 1085 | if (engine->schedule) |
1085 | engine->schedule(request, request->ctx->priority); | 1086 | engine->schedule(request, request->ctx->priority); |
1087 | rcu_read_unlock(); | ||
1086 | 1088 | ||
1087 | local_bh_disable(); | 1089 | local_bh_disable(); |
1088 | i915_sw_fence_commit(&request->submit); | 1090 | i915_sw_fence_commit(&request->submit); |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index ac8fc2a44ac6..dbcf1a0586f9 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -3080,9 +3080,12 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) | |||
3080 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); | 3080 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
3081 | intel_encoder->cloneable = 0; | 3081 | intel_encoder->cloneable = 0; |
3082 | 3082 | ||
3083 | intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & | 3083 | if (INTEL_GEN(dev_priv) >= 11) |
3084 | (DDI_BUF_PORT_REVERSAL | | 3084 | intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & |
3085 | DDI_A_4_LANES); | 3085 | DDI_BUF_PORT_REVERSAL; |
3086 | else | ||
3087 | intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & | ||
3088 | (DDI_BUF_PORT_REVERSAL | DDI_A_4_LANES); | ||
3086 | intel_dig_port->dp.output_reg = INVALID_MMIO_REG; | 3089 | intel_dig_port->dp.output_reg = INVALID_MMIO_REG; |
3087 | intel_dig_port->max_lanes = intel_ddi_max_lanes(intel_dig_port); | 3090 | intel_dig_port->max_lanes = intel_ddi_max_lanes(intel_dig_port); |
3088 | 3091 | ||