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

drm/i915: Suppress switch_mm emission between the same aliasing_ppgtt

When switching between contexts using the aliasing_ppgtt, the VM is
shared. We don't need to reload the PD registers unless they are dirty.

Martin Peres reported an issue that looks like corruption between
Haswell context switches, bisecting to commit f9326be5f1d3 ("drm/i915:
Rearrange switch_context to load the aliasing ppgtt on first use").
Switching between the same mm (the aliasing_ppgtt is used for all
contexts in this case) should be a nop, but appears to trigger some
side-effects in the context switch. However, as we know the switch
is redundant in this case, we can skip it and continue to ignore the
issue until somebody feels strong enough to investigate full-ppgtt on
gen7 again!

Except.. Martin was using full-ppgtt which is not supported as it
doesn't work correctly yet. So whilst the bisect did yield valuable
information about the failures, the fix should not have any user impact
under default settings, with the exception of a slightly lower
throughput on xcs as the VM would always be reloaded.

v2: Also remember to set the legacy_active_context following the switch
on xcs (commit e8a9c58fcd9a ("drm/i915: Unify active context tracking
between legacy/execlists/guc"))

Fixes: f9326be5f1d3 ("drm/i915: Rearrange switch_context to load the aliasing ppgtt on first use")
Fixes: e8a9c58fcd9a ("drm/i915: Unify active context tracking between legacy/execlists/guc")
Reported-by: Martin Peres <martin.peres@linux.intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Martin Peres <martin.peres@linux.intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170812152724.6883-1-chris@chris-wilson.co.uk
(cherry picked from commit 12124bea5b82dc1e917304aed703c27292270051)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>

authored by

Chris Wilson and committed by
Jani Nikula
430ffaf4 7eceb9d0

+8 -7
+8 -7
drivers/gpu/drm/i915/i915_gem_context.c
··· 688 688 } 689 689 690 690 static bool 691 - needs_pd_load_pre(struct i915_hw_ppgtt *ppgtt, 692 - struct intel_engine_cs *engine, 693 - struct i915_gem_context *to) 691 + needs_pd_load_pre(struct i915_hw_ppgtt *ppgtt, struct intel_engine_cs *engine) 694 692 { 693 + struct i915_gem_context *from = engine->legacy_active_context; 694 + 695 695 if (!ppgtt) 696 696 return false; 697 697 698 698 /* Always load the ppgtt on first use */ 699 - if (!engine->legacy_active_context) 699 + if (!from) 700 700 return true; 701 701 702 702 /* Same context without new entries, skip */ 703 - if (engine->legacy_active_context == to && 703 + if ((!from->ppgtt || from->ppgtt == ppgtt) && 704 704 !(intel_engine_flag(engine) & ppgtt->pd_dirty_rings)) 705 705 return false; 706 706 ··· 744 744 if (skip_rcs_switch(ppgtt, engine, to)) 745 745 return 0; 746 746 747 - if (needs_pd_load_pre(ppgtt, engine, to)) { 747 + if (needs_pd_load_pre(ppgtt, engine)) { 748 748 /* Older GENs and non render rings still want the load first, 749 749 * "PP_DCLV followed by PP_DIR_BASE register through Load 750 750 * Register Immediate commands in Ring Buffer before submitting ··· 841 841 struct i915_hw_ppgtt *ppgtt = 842 842 to->ppgtt ?: req->i915->mm.aliasing_ppgtt; 843 843 844 - if (needs_pd_load_pre(ppgtt, engine, to)) { 844 + if (needs_pd_load_pre(ppgtt, engine)) { 845 845 int ret; 846 846 847 847 trace_switch_mm(engine, to); ··· 852 852 ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine); 853 853 } 854 854 855 + engine->legacy_active_context = to; 855 856 return 0; 856 857 } 857 858