Skip to content

Commit 2cb3a34

Browse files
committed
Merge tag 'drm-intel-fixes-2017-10-18-1' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes
Fix for stable: - Fix DDI translation tables for BDW (Chris). Critical fix: - Fix GPU Hang on GVT (Changbin). Other fixes: - Fix eviction when GGTT is idle (Chris). - CNL PLL fixes (Rodrigo). - Fix pwrite into shmemfs (Chris). - Mask bits for BXT and CHV L3 Workaround WaProgramL3SqcReg1Default (Oscar). * tag 'drm-intel-fixes-2017-10-18-1' of git://anongit.freedesktop.org/drm/drm-intel: drm/i915: Use a mask when applying WaProgramL3SqcReg1Default drm/i915: Report -EFAULT before pwrite fast path into shmemfs drm/i915/cnl: Fix PLL initialization for HDMI. drm/i915/cnl: Fix PLL mapping. drm/i915: Use bdw_ddi_translations_fdi for Broadwell drm/i915: Fix eviction when the GGTT is idle but full drm/i915/gvt: Fix GPU hang after reusing vGPU instance across different guest OS
2 parents 3eea56c + dd00ed9 commit 2cb3a34

8 files changed

Lines changed: 69 additions & 47 deletions

File tree

drivers/gpu/drm/i915/gvt/sched_policy.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -308,20 +308,8 @@ static int tbs_sched_init_vgpu(struct intel_vgpu *vgpu)
308308

309309
static void tbs_sched_clean_vgpu(struct intel_vgpu *vgpu)
310310
{
311-
struct intel_gvt_workload_scheduler *scheduler = &vgpu->gvt->scheduler;
312-
int ring_id;
313-
314311
kfree(vgpu->sched_data);
315312
vgpu->sched_data = NULL;
316-
317-
spin_lock_bh(&scheduler->mmio_context_lock);
318-
for (ring_id = 0; ring_id < I915_NUM_ENGINES; ring_id++) {
319-
if (scheduler->engine_owner[ring_id] == vgpu) {
320-
intel_gvt_switch_mmio(vgpu, NULL, ring_id);
321-
scheduler->engine_owner[ring_id] = NULL;
322-
}
323-
}
324-
spin_unlock_bh(&scheduler->mmio_context_lock);
325313
}
326314

327315
static void tbs_sched_start_schedule(struct intel_vgpu *vgpu)
@@ -388,6 +376,7 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
388376
{
389377
struct intel_gvt_workload_scheduler *scheduler =
390378
&vgpu->gvt->scheduler;
379+
int ring_id;
391380

392381
gvt_dbg_core("vgpu%d: stop schedule\n", vgpu->id);
393382

@@ -401,4 +390,13 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
401390
scheduler->need_reschedule = true;
402391
scheduler->current_vgpu = NULL;
403392
}
393+
394+
spin_lock_bh(&scheduler->mmio_context_lock);
395+
for (ring_id = 0; ring_id < I915_NUM_ENGINES; ring_id++) {
396+
if (scheduler->engine_owner[ring_id] == vgpu) {
397+
intel_gvt_switch_mmio(vgpu, NULL, ring_id);
398+
scheduler->engine_owner[ring_id] = NULL;
399+
}
400+
}
401+
spin_unlock_bh(&scheduler->mmio_context_lock);
404402
}

drivers/gpu/drm/i915/i915_gem.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2657,6 +2657,9 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj,
26572657
if (READ_ONCE(obj->mm.pages))
26582658
return -ENODEV;
26592659

2660+
if (obj->mm.madv != I915_MADV_WILLNEED)
2661+
return -EFAULT;
2662+
26602663
/* Before the pages are instantiated the object is treated as being
26612664
* in the CPU domain. The pages will be clflushed as required before
26622665
* use, and we can freely write into the pages directly. If userspace

drivers/gpu/drm/i915/i915_gem_evict.c

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,20 @@
3333
#include "intel_drv.h"
3434
#include "i915_trace.h"
3535

36-
static bool ggtt_is_idle(struct drm_i915_private *dev_priv)
36+
static bool ggtt_is_idle(struct drm_i915_private *i915)
3737
{
38-
struct i915_ggtt *ggtt = &dev_priv->ggtt;
39-
struct intel_engine_cs *engine;
40-
enum intel_engine_id id;
38+
struct intel_engine_cs *engine;
39+
enum intel_engine_id id;
4140

42-
for_each_engine(engine, dev_priv, id) {
43-
struct intel_timeline *tl;
41+
if (i915->gt.active_requests)
42+
return false;
4443

45-
tl = &ggtt->base.timeline.engine[engine->id];
46-
if (i915_gem_active_isset(&tl->last_request))
47-
return false;
48-
}
44+
for_each_engine(engine, i915, id) {
45+
if (engine->last_retired_context != i915->kernel_context)
46+
return false;
47+
}
4948

50-
return true;
49+
return true;
5150
}
5251

5352
static int ggtt_flush(struct drm_i915_private *i915)
@@ -157,7 +156,8 @@ i915_gem_evict_something(struct i915_address_space *vm,
157156
min_size, alignment, cache_level,
158157
start, end, mode);
159158

160-
/* Retire before we search the active list. Although we have
159+
/*
160+
* Retire before we search the active list. Although we have
161161
* reasonable accuracy in our retirement lists, we may have
162162
* a stray pin (preventing eviction) that can only be resolved by
163163
* retiring.
@@ -182,27 +182,42 @@ i915_gem_evict_something(struct i915_address_space *vm,
182182
BUG_ON(ret);
183183
}
184184

185-
/* Can we unpin some objects such as idle hw contents,
185+
/*
186+
* Can we unpin some objects such as idle hw contents,
186187
* or pending flips? But since only the GGTT has global entries
187188
* such as scanouts, rinbuffers and contexts, we can skip the
188189
* purge when inspecting per-process local address spaces.
189190
*/
190191
if (!i915_is_ggtt(vm) || flags & PIN_NONBLOCK)
191192
return -ENOSPC;
192193

193-
if (ggtt_is_idle(dev_priv)) {
194-
/* If we still have pending pageflip completions, drop
195-
* back to userspace to give our workqueues time to
196-
* acquire our locks and unpin the old scanouts.
197-
*/
198-
return intel_has_pending_fb_unpin(dev_priv) ? -EAGAIN : -ENOSPC;
199-
}
194+
/*
195+
* Not everything in the GGTT is tracked via VMA using
196+
* i915_vma_move_to_active(), otherwise we could evict as required
197+
* with minimal stalling. Instead we are forced to idle the GPU and
198+
* explicitly retire outstanding requests which will then remove
199+
* the pinning for active objects such as contexts and ring,
200+
* enabling us to evict them on the next iteration.
201+
*
202+
* To ensure that all user contexts are evictable, we perform
203+
* a switch to the perma-pinned kernel context. This all also gives
204+
* us a termination condition, when the last retired context is
205+
* the kernel's there is no more we can evict.
206+
*/
207+
if (!ggtt_is_idle(dev_priv)) {
208+
ret = ggtt_flush(dev_priv);
209+
if (ret)
210+
return ret;
200211

201-
ret = ggtt_flush(dev_priv);
202-
if (ret)
203-
return ret;
212+
goto search_again;
213+
}
204214

205-
goto search_again;
215+
/*
216+
* If we still have pending pageflip completions, drop
217+
* back to userspace to give our workqueues time to
218+
* acquire our locks and unpin the old scanouts.
219+
*/
220+
return intel_has_pending_fb_unpin(dev_priv) ? -EAGAIN : -ENOSPC;
206221

207222
found:
208223
/* drm_mm doesn't allow any other other operations while

drivers/gpu/drm/i915/i915_reg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6998,6 +6998,7 @@ enum {
69986998
*/
69996999
#define L3_GENERAL_PRIO_CREDITS(x) (((x) >> 1) << 19)
70007000
#define L3_HIGH_PRIO_CREDITS(x) (((x) >> 1) << 14)
7001+
#define L3_PRIO_CREDITS_MASK ((0x1f << 19) | (0x1f << 14))
70017002

70027003
#define GEN7_L3CNTLREG1 _MMIO(0xB01C)
70037004
#define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C47FF8C

drivers/gpu/drm/i915/intel_ddi.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -664,8 +664,8 @@ intel_ddi_get_buf_trans_fdi(struct drm_i915_private *dev_priv,
664664
int *n_entries)
665665
{
666666
if (IS_BROADWELL(dev_priv)) {
667-
*n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi);
668-
return hsw_ddi_translations_fdi;
667+
*n_entries = ARRAY_SIZE(bdw_ddi_translations_fdi);
668+
return bdw_ddi_translations_fdi;
669669
} else if (IS_HASWELL(dev_priv)) {
670670
*n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi);
671671
return hsw_ddi_translations_fdi;
@@ -2102,8 +2102,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
21022102
* register writes.
21032103
*/
21042104
val = I915_READ(DPCLKA_CFGCR0);
2105-
val &= ~(DPCLKA_CFGCR0_DDI_CLK_OFF(port) |
2106-
DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port));
2105+
val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port);
21072106
I915_WRITE(DPCLKA_CFGCR0, val);
21082107
} else if (IS_GEN9_BC(dev_priv)) {
21092108
/* DDI -> PLL mapping */

drivers/gpu/drm/i915/intel_dpll_mgr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1996,7 +1996,7 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv,
19961996

19971997
/* 3. Configure DPLL_CFGCR0 */
19981998
/* Avoid touch CFGCR1 if HDMI mode is not enabled */
1999-
if (pll->state.hw_state.cfgcr0 & DPLL_CTRL1_HDMI_MODE(pll->id)) {
1999+
if (pll->state.hw_state.cfgcr0 & DPLL_CFGCR0_HDMI_MODE) {
20002000
val = pll->state.hw_state.cfgcr1;
20012001
I915_WRITE(CNL_DPLL_CFGCR1(pll->id), val);
20022002
/* 4. Reab back to ensure writes completed */

drivers/gpu/drm/i915/intel_engine_cs.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,9 +1048,12 @@ static int bxt_init_workarounds(struct intel_engine_cs *engine)
10481048
}
10491049

10501050
/* WaProgramL3SqcReg1DefaultForPerf:bxt */
1051-
if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER))
1052-
I915_WRITE(GEN8_L3SQCREG1, L3_GENERAL_PRIO_CREDITS(62) |
1053-
L3_HIGH_PRIO_CREDITS(2));
1051+
if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) {
1052+
u32 val = I915_READ(GEN8_L3SQCREG1);
1053+
val &= ~L3_PRIO_CREDITS_MASK;
1054+
val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2);
1055+
I915_WRITE(GEN8_L3SQCREG1, val);
1056+
}
10541057

10551058
/* WaToEnableHwFixForPushConstHWBug:bxt */
10561059
if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))

drivers/gpu/drm/i915/intel_pm.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8245,14 +8245,17 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv,
82458245
int high_prio_credits)
82468246
{
82478247
u32 misccpctl;
8248+
u32 val;
82488249

82498250
/* WaTempDisableDOPClkGating:bdw */
82508251
misccpctl = I915_READ(GEN7_MISCCPCTL);
82518252
I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
82528253

8253-
I915_WRITE(GEN8_L3SQCREG1,
8254-
L3_GENERAL_PRIO_CREDITS(general_prio_credits) |
8255-
L3_HIGH_PRIO_CREDITS(high_prio_credits));
8254+
val = I915_READ(GEN8_L3SQCREG1);
8255+
val &= ~L3_PRIO_CREDITS_MASK;
8256+
val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits);
8257+
val |= L3_HIGH_PRIO_CREDITS(high_prio_credits);
8258+
I915_WRITE(GEN8_L3SQCREG1, val);
82568259

82578260
/*
82588261
* Wait at least 100 clocks before re-enabling clock gating.

0 commit comments

Comments
 (0)