Restore workarounds after engine reset and unify their handling
Subsystems (2)
cover Restore workarounds after engine reset and unify their handling
From: Tvrtko Ursulin <[email protected]>
First two patches in this series fix losing of workarounds after engine reset
(https://bugzilla.freedesktop.org/show_bug.cgi?id=107945) which started happening after 59b449d5c82a ("drm/i915: Split out functions for different kinds of workarounds").
But since it was discovered to be unsafe to simply re-apply all of them, against a possibly active GPU, and potentially from IRQ context, the approach taken was to split GT workarounds and per-engine workarounds. Latter so far contain the ones living in the 0x2xxx and 0xbxxx range, which were empirically shown to be lost after RCS reset.
This way only a smaller set of affected workarounds can be applied after engine resetm, which is done with irq safe read-modify-write cycle.
The series is structured like this so first two patches are as standalone as possible so it is easy (easier) to backport them. The rest of the series cleans up the whole workaround handling by moving all four classes of them to a common framework.
Tvrtko Ursulin (8):
drm/i915: Record GT workarounds in a list
drm/i915: Introduce per-engine workarounds
drm/i915: Verify GT workaround state at runtime drm/i915: Verify engine workaround state at runtime drm/i915/selftests: Add tests for GT and engine workaround
verification
drm/i915: Move register white-listing to the common workaround
framework
drm/i915: Fuse per-context workaround handling with the common
framework
drm/i915: Trim unused workaround list entries
drivers/gpu/drm/i915/i915_debugfs.c | 11 +- drivers/gpu/drm/i915/i915_drv.c | 8 + drivers/gpu/drm/i915/i915_drv.h | 18 +- drivers/gpu/drm/i915/i915_gem.c | 6 + drivers/gpu/drm/i915/i915_gem_context.c | 6 +- drivers/gpu/drm/i915/intel_engine_cs.c | 3 + drivers/gpu/drm/i915/intel_lrc.c | 5 + drivers/gpu/drm/i915/intel_ringbuffer.h | 3 + drivers/gpu/drm/i915/intel_workarounds.c | 896 +++++++++++------- drivers/gpu/drm/i915/intel_workarounds.h | 33 +- .../drm/i915/selftests/intel_workarounds.c | 130 ++- 11 files changed, 726 insertions(+), 393 deletions(-)
Signature · 6 lines
2.19.1 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 1/8 drm/i915: Record GT workarounds in a list
From: Tvrtko Ursulin <[email protected]>
To enable later verification of GT workaround state at various stages of driver lifetime, we record the list of applicable ones per platforms to a list, from which they are also applied.
The added data structure is a simple array of register, mask and value items, which is allocated on demand as workarounds are added to the list.
This is a temporary implementation which later in the series gets fused with the existing per context workaround list handling. It is separated at this stage since the following patch fixes a bug which needs to be as easy to backport as possible.
Also, since in the following patch we will be adding a new class of workarounds (per engine) which can be applied from interrupt context, we straight away make the provision for safe read-modify-write cycle.
--- drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 2 + drivers/gpu/drm/i915/intel_workarounds.c | 443 +++++++++++++++-------- drivers/gpu/drm/i915/intel_workarounds.h | 22 ++ 5 files changed, 327 insertions(+), 143 deletions(-)
drivers/gpu/drm/i915/i915_drv.c +1 -0
@@ -1453,6 +1453,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)intel_uncore_sanitize (dev_priv); +intel_gt_workarounds_init (dev_priv);i915_gem_load_init_fences (dev_priv);/* On the 945G/GM, the chipset reports the MSI capability on the
drivers/gpu/drm/i915/i915_drv.h +2 -0
@@ -69,6 +69,7 @@#include "intel_ringbuffer.h" #include "intel_uncore.h" #include "intel_wopcm.h" +#include "intel_workarounds.h" #include "intel_uc.h" #include "i915_gem.h"
@@ -1652,6 +1653,7 @@ struct drm_i915_private {int dpio_phy_iosf_port[I915_NUM_PHYS_VLV ];struct i915_workarounds workarounds; +struct i915_wa_list gt_wa_list;struct i915_frontbuffer_tracking fb_tracking;
drivers/gpu/drm/i915/i915_gem.c +2 -0
@@ -5706,6 +5706,8 @@ void i915_gem_fini(struct drm_i915_private *dev_priv)i915_gem_contexts_fini (dev_priv);mutex_unlock (&dev_priv->drm.struct_mutex); +intel_wa_list_free (&dev_priv->gt_wa_list); +intel_cleanup_gt_powersave (dev_priv);intel_uc_fini_misc (dev_priv);
drivers/gpu/drm/i915/intel_workarounds.c +300 -143
625 lines not on this page · raw message
drivers/gpu/drm/i915/intel_workarounds.h +22 -0
@@ -7,9 +7,31 @@#ifndef _I915_WORKAROUNDS_H_#define _I915_WORKAROUNDS_H_ +#include <linux/slab.h> + +struct i915_wa { +i915_reg_t reg; +u32 mask; +u32 val; +}; + +struct i915_wa_list { +const char *name; +unsigned int count; +struct i915_wa *list; +unsigned int __size; +}; + +static inline void intel_wa_list_free (struct i915_wa_list *wal) +{ +kfree (wal->list); +memset (wal,0 ,sizeof (*wal)); +} +int intel_ctx_workarounds_init (struct drm_i915_private *dev_priv);int intel_ctx_workarounds_emit (struct i915_request *rq); +void intel_gt_workarounds_init (struct drm_i915_private *dev_priv);void intel_gt_workarounds_apply (struct drm_i915_private *dev_priv);void intel_whitelist_workarounds_apply (struct intel_engine_cs *engine);
Signature · 6 lines
2.19.1 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 2/8 drm/i915: Introduce per-engine workarounds
In reply to Tvrtko UrsulinFrom: Tvrtko Ursulin <[email protected]>
We stopped re-applying the GT workarounds after engine reset since commit 59b449d5c82a ("drm/i915: Split out functions for different kinds of workarounds").
Issue with this is that some of the GT workarounds live in the MMIO space which gets lost during engine resets. So far the registers in 0x2xxx and 0xbxxx address range have been identified to be affected.
This losing of applied workarounds has obvious negative effects and can even lead to hard system hangs (see the linked Bugzilla).
Rather than just restoring this re-application, because we have also observed that it is not safe to just re-write all GT workarounds after engine resets (GPU might be live and weird hardware states can happen), we introduce a new class of per-engine workarounds and move only the affected GT workarounds over.
Using the framework introduced in the previous patch, we therefore after engine reset, re-apply only the workarounds living in the affected MMIO address ranges.
Bugzilla: https://bugzilla.freedesktop.org/show_bug.cgi?id=107945
--- drivers/gpu/drm/i915/intel_engine_cs.c | 2 + drivers/gpu/drm/i915/intel_lrc.c | 4 + drivers/gpu/drm/i915/intel_ringbuffer.h | 2 + drivers/gpu/drm/i915/intel_workarounds.c | 249 +++++++++++++---------- drivers/gpu/drm/i915/intel_workarounds.h | 3 + 5 files changed, 148 insertions(+), 112 deletions(-)
drivers/gpu/drm/i915/intel_engine_cs.c +2 -0
@@ -723,6 +723,8 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)__intel_context_unpin (i915->kernel_context, engine);i915_timeline_fini (&engine->timeline); + +intel_wa_list_free (&engine->wa_list); }u64 intel_engine_get_active_head (const struct intel_engine_cs *engine)
drivers/gpu/drm/i915/intel_lrc.c +4 -0
@@ -1617,6 +1617,8 @@ static bool unexpected_starting_state(struct intel_engine_cs *engine)static int gen8_init_common_ring (struct intel_engine_cs *engine) { +intel_engine_workarounds_apply (engine); +intel_mocs_init_engine (engine);intel_engine_reset_breadcrumbs (engine);
@@ -2314,6 +2316,8 @@ int logical_render_ring_init(struct intel_engine_cs *engine) ret); } +intel_engine_workarounds_init (engine); +return 0 ; err_cleanup_common:
drivers/gpu/drm/i915/intel_ringbuffer.h +2 -0
@@ -15,6 +15,7 @@#include "i915_selftest.h" #include "i915_timeline.h" #include "intel_gpu_commands.h" +#include "intel_workarounds.h" struct drm_printer ;struct i915_sched_attr ;
@@ -451,6 +452,7 @@ struct intel_engine_cs {struct intel_hw_status_page status_page;struct i915_ctx_workarounds wa_ctx; +struct i915_wa_list wa_list;struct i915_vma *scratch;u32 irq_keep_mask;/* always keep these interrupts */
drivers/gpu/drm/i915/intel_workarounds.c +137 -112
326 lines not on this page · raw message
drivers/gpu/drm/i915/intel_workarounds.h +3 -0
@@ -36,4 +36,7 @@ void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv);void intel_whitelist_workarounds_apply (struct intel_engine_cs *engine); +void intel_engine_workarounds_init (struct intel_engine_cs *engine); +void intel_engine_workarounds_apply (struct intel_engine_cs *engine); +#endif
Signature · 6 lines
2.19.1 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 3/8 drm/i915: Verify GT workaround state at runtime
In reply to Tvrtko UrsulinFrom: Tvrtko Ursulin <[email protected]>
Since we now have all the GT workarounds in a table, by adding a simple shared helper function we can now verify that their values are still applied after some interesting events in the lifetime of the driver.
At this stage these are the driver initialization and engine reset.
--- drivers/gpu/drm/i915/i915_drv.c | 4 +++ drivers/gpu/drm/i915/i915_gem.c | 3 ++ drivers/gpu/drm/i915/intel_workarounds.c | 46 ++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_workarounds.h | 2 ++ 4 files changed, 55 insertions(+)
drivers/gpu/drm/i915/i915_drv.c +4 -0
@@ -53,6 +53,7 @@#include "i915_vgpu.h" #include "intel_drv.h" #include "intel_uc.h" +#include "intel_workarounds.h" static struct drm_driver driver;
@@ -2362,6 +2363,9 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg) goto out; } +/* Catch GT workarounds affected by engine reset. */ +intel_gt_workarounds_verify (engine->i915, engine->name); +/* * The request that caused the hang is stuck on elsp, we know the * active request and can drop it, adjust head to skip the offending
drivers/gpu/drm/i915/i915_gem.c +3 -0
@@ -5334,7 +5334,10 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)I915_WRITE (MI_PREDICATE_RESULT_2 ,IS_HSW_GT3 (dev_priv) ?LOWER_SLICE_ENABLED :LOWER_SLICE_DISABLED ); +/* Apply the GT workarounds... */ intel_gt_workarounds_apply (dev_priv); +/* ...and determine whether they are sticking. */ +intel_gt_workarounds_verify (dev_priv,"init" );i915_gem_init_swizzling (dev_priv);
drivers/gpu/drm/i915/intel_workarounds.c +46 -0
52 lines not on this page · raw message
drivers/gpu/drm/i915/intel_workarounds.h +2 -0
@@ -33,6 +33,8 @@ int intel_ctx_workarounds_emit(struct i915_request *rq);void intel_gt_workarounds_init (struct drm_i915_private *dev_priv);void intel_gt_workarounds_apply (struct drm_i915_private *dev_priv); +void intel_gt_workarounds_verify (struct drm_i915_private *dev_priv, +const char *from);void intel_whitelist_workarounds_apply (struct intel_engine_cs *engine);
Signature · 6 lines
2.19.1 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 3/8] drm/i915: Verify GT workaround state at runtime
Quoting Tvrtko Ursulin (2018-11-30 11:31:56)
Quoted 29 lines
From: Tvrtko Ursulin <[email protected]>
Since we now have all the GT workarounds in a table, by adding a simple shared helper function we can now verify that their values are still applied after some interesting events in the lifetime of the driver.
At this stage these are the driver initialization and engine reset.
Signed-off-by Tvrtko Ursulin <[email protected]>--- drivers/gpu/drm/i915/i915_drv.c | 4 +++ drivers/gpu/drm/i915/i915_gem.c | 3 ++ drivers/gpu/drm/i915/intel_workarounds.c | 46 ++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_workarounds.h | 2 ++ 4 files changed, 55 insertions(+)drivers/gpu/drm/i915/i915_drv.c +1
-0@@ -53,6 +53,7 @@#include "i915_vgpu.h" #include "intel_drv.h" #include "intel_uc.h" +#include "intel_workarounds.h" static struct drm_driver driver;
drivers/gpu/drm/i915/i915_drv.c int i915_reset_engine(struct intel_engine_cs *engine, const char *msg) · line 2367
Quoted 5 lines
drivers/gpu/drm/i915/i915_drv.c +2
-0@@ -2362,6 +2363,9 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg) goto out; } +/* Catch GT workarounds affected by engine reset. */ +intel_gt_workarounds_verify (engine->i915, engine->name);
I'd rather, quite strongly, not have this inside i915_reset_engine() itself. i915_reset_engine() is [designed to be] called from atomic context. Adding I915_READ() here is questionable. My preference is to have all this inside selftests/intel_workarounds where we can cross check the gt/all-engines after device reset and other engine reset. -Chris
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 3/8] drm/i915: Verify GT workaround state at runtime
Quoted 33 lines · Chris Wilson
Quoting Tvrtko Ursulin (2018-11-30 11:31:56)
Quoted 32 lines
From: Tvrtko Ursulin <[email protected]>
Since we now have all the GT workarounds in a table, by adding a simple shared helper function we can now verify that their values are still applied after some interesting events in the lifetime of the driver.
At this stage these are the driver initialization and engine reset.
Signed-off-by Tvrtko Ursulin <[email protected]>--- drivers/gpu/drm/i915/i915_drv.c | 4 +++ drivers/gpu/drm/i915/i915_gem.c | 3 ++ drivers/gpu/drm/i915/intel_workarounds.c | 46 ++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_workarounds.h | 2 ++ 4 files changed, 55 insertions(+)drivers/gpu/drm/i915/i915_drv.c +1
-0@@ -53,6 +53,7 @@#include "i915_vgpu.h" #include "intel_drv.h" #include "intel_uc.h" +#include "intel_workarounds.h" static struct drm_driver driver;@@ -2362,6 +2363,9 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg) goto out; }
Quoted 8 lines
drivers/gpu/drm/i915/i915_drv.c int i915_reset_engine(struct intel_engine_cs *engine, const char *msg) · line 2367
Quoted 2 lines
drivers/gpu/drm/i915/i915_drv.c +2
-0+/* Catch GT workarounds affected by engine reset. */ +intel_gt_workarounds_verify (engine->i915, engine->name);I'd rather, quite strongly, not have this inside
i915_reset_engine()itself.i915_reset_engine()is [designed to be] called from atomic context. AddingI915_READ()here is questionable. My preference is to have all this inside selftests/intel_workarounds where we can cross check the gt/all-engines after device reset and other engine reset.
I wasn't sure myself how much value checking it here adds, but regarding I915_READs, they are happening during engine->init_hw anyway. So I don't think a few more would harm. But yes, as said, since I was unsure myself I am happy to drop this hunk.
Regards,
Tvrtko
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 3/8] drm/i915: Verify GT workaround state at runtime
Quoting Tvrtko Ursulin (2018-11-30 12:02:56)
Quoted 44 lines · Chris Wilson
Quoted 33 lines
Quoting Tvrtko Ursulin (2018-11-30 11:31:56)
Quoted 32 lines
From: Tvrtko Ursulin <[email protected]>
Since we now have all the GT workarounds in a table, by adding a simple shared helper function we can now verify that their values are still applied after some interesting events in the lifetime of the driver.
At this stage these are the driver initialization and engine reset.
Signed-off-by Tvrtko Ursulin <[email protected]>--- drivers/gpu/drm/i915/i915_drv.c | 4 +++ drivers/gpu/drm/i915/i915_gem.c | 3 ++ drivers/gpu/drm/i915/intel_workarounds.c | 46 ++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_workarounds.h | 2 ++ 4 files changed, 55 insertions(+)drivers/gpu/drm/i915/i915_drv.c +1
-0@@ -53,6 +53,7 @@#include "i915_vgpu.h" #include "intel_drv.h" #include "intel_uc.h" +#include "intel_workarounds.h" static struct drm_driver driver;@@ -2362,6 +2363,9 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg) goto out; }Quoted 8 lines
drivers/gpu/drm/i915/i915_drv.c int i915_reset_engine(struct intel_engine_cs *engine, const char *msg) · line 2367
Quoted 2 lines
drivers/gpu/drm/i915/i915_drv.c +2
-0+/* Catch GT workarounds affected by engine reset. */ +intel_gt_workarounds_verify (engine->i915, engine->name);I'd rather, quite strongly, not have this inside
i915_reset_engine()itself.i915_reset_engine()is [designed to be] called from atomic context. AddingI915_READ()here is questionable. My preference is to have all this inside selftests/intel_workarounds where we can cross check the gt/all-engines after device reset and other engine reset.
Quoted 4 lines
I wasn't sure myself how much value checking it here adds, but regarding
I915_READs, they are happening duringengine->init_hwanyway. So I don't think a few more would harm. But yes, as said, since I was unsure myself I am happy to drop this hunk.
Adding the I915_READ isn't the end-of-the-world, I am more wary of the slipperly slope and suddenly finding ourselves with a per-engine reset that is no longer suitable for fast resets, possibly from hardirq context. (Although that's more likely to be softirq really.)
In this case, I think we can satisfy ourselves with a comprehensive yet fast test suite. And there's no harm in having the checks on idle for runtime consistency checking (we can even inject SRM before idling for completeness).
-Chris
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 3/8] drm/i915: Verify GT workaround state at runtime
In reply to Tvrtko UrsulinQuoting Tvrtko Ursulin (2018-11-30 11:31:56)
Quoted 67 lines
From: Tvrtko Ursulin <[email protected]>
Since we now have all the GT workarounds in a table, by adding a simple shared helper function we can now verify that their values are still applied after some interesting events in the lifetime of the driver.
At this stage these are the driver initialization and engine reset.
Signed-off-by Tvrtko Ursulin <[email protected]>--- drivers/gpu/drm/i915/i915_drv.c | 4 +++ drivers/gpu/drm/i915/i915_gem.c | 3 ++ drivers/gpu/drm/i915/intel_workarounds.c | 46 ++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_workarounds.h | 2 ++ 4 files changed, 55 insertions(+)drivers/gpu/drm/i915/i915_drv.c +4
-0@@ -53,6 +53,7 @@#include "i915_vgpu.h" #include "intel_drv.h" #include "intel_uc.h" +#include "intel_workarounds.h" static struct drm_driver driver;@@ -2362,6 +2363,9 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg) goto out; } +/* Catch GT workarounds affected by engine reset. */ +intel_gt_workarounds_verify (engine->i915, engine->name); +/* * The request that caused the hang is stuck on elsp, we know the * active request and can drop it, adjust head to skip the offending drivers/gpu/drm/i915/i915_gem.c +3
-0@@ -5334,7 +5334,10 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)I915_WRITE (MI_PREDICATE_RESULT_2 ,IS_HSW_GT3 (dev_priv) ?LOWER_SLICE_ENABLED :LOWER_SLICE_DISABLED ); +/* Apply the GT workarounds... */ intel_gt_workarounds_apply (dev_priv); +/* ...and determine whether they are sticking. */ +intel_gt_workarounds_verify (dev_priv,"init" );i915_gem_init_swizzling (dev_priv);drivers/gpu/drm/i915/intel_workarounds.c +6
-0@@ -981,6 +981,52 @@ void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv)wa_list_apply (dev_priv, &dev_priv->gt_wa_list); } +static void +wa_fail (const struct i915_wa *wa,u32 cur,const char *name,const char *from) +{ + DRM_ERROR("%s workaround lost on %s! (%x=%x/%x, expected %x, mask=%x)\n", + name, from, + i915_mmio_reg_offset(wa->reg),
drivers/gpu/drm/i915/intel_workarounds.c void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv) · line 999
Quoted 10 lines
drivers/gpu/drm/i915/intel_workarounds.c +10
-0+ cur, cur & wa->mask, wa->val, wa->mask); +} + +static void +wa_verify_bits (const struct i915_wa *wa,u32 cur,const char *name, +const char *from) +{ +u32 bits = wa->mask; +u32 cur_ = cur; +u32 val_ = wa->val;
Make sure wa->mask is set to ~0u for whole registers, which it must be for the wa_fail.
if ((cur ^ wa->val) & wa->mask) {
wa_fail(wa, cur, name, whom);
return false; /* make it bool now to save churn later? */
}-Chris
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 3/8] drm/i915: Verify GT workaround state at runtime
Quoted 73 lines · Chris Wilson
Quoting Tvrtko Ursulin (2018-11-30 11:31:56)
Quoted 72 lines
From: Tvrtko Ursulin <[email protected]>
Since we now have all the GT workarounds in a table, by adding a simple shared helper function we can now verify that their values are still applied after some interesting events in the lifetime of the driver.
At this stage these are the driver initialization and engine reset.
Signed-off-by Tvrtko Ursulin <[email protected]>--- drivers/gpu/drm/i915/i915_drv.c | 4 +++ drivers/gpu/drm/i915/i915_gem.c | 3 ++ drivers/gpu/drm/i915/intel_workarounds.c | 46 ++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_workarounds.h | 2 ++ 4 files changed, 55 insertions(+)drivers/gpu/drm/i915/i915_drv.c +4
-0@@ -53,6 +53,7 @@#include "i915_vgpu.h" #include "intel_drv.h" #include "intel_uc.h" +#include "intel_workarounds.h" static struct drm_driver driver;@@ -2362,6 +2363,9 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg) goto out; } +/* Catch GT workarounds affected by engine reset. */ +intel_gt_workarounds_verify (engine->i915, engine->name); +/* * The request that caused the hang is stuck on elsp, we know the * active request and can drop it, adjust head to skip the offending drivers/gpu/drm/i915/i915_gem.c +3
-0@@ -5334,7 +5334,10 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)I915_WRITE (MI_PREDICATE_RESULT_2 ,IS_HSW_GT3 (dev_priv) ?LOWER_SLICE_ENABLED :LOWER_SLICE_DISABLED ); +/* Apply the GT workarounds... */ intel_gt_workarounds_apply (dev_priv); +/* ...and determine whether they are sticking. */ +intel_gt_workarounds_verify (dev_priv,"init" );i915_gem_init_swizzling (dev_priv);drivers/gpu/drm/i915/intel_workarounds.c +11
-0@@ -981,6 +981,52 @@ void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv)wa_list_apply (dev_priv, &dev_priv->gt_wa_list); } +static void +wa_fail (const struct i915_wa *wa,u32 cur,const char *name,const char *from) +{ +DRM_ERROR ("%s workaround lost on %s! (%x=%x/%x, expected %x, mask=%x)\n" , + name, from, +i915_mmio_reg_offset (wa->reg), + cur, cur & wa->mask, wa->val, wa->mask); +} + +static void +wa_verify_bits(const struct i915_wa *wa, u32 cur, const char *name,
Quoted 8 lines
drivers/gpu/drm/i915/intel_workarounds.c void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv) · line 999
Quoted 5 lines
drivers/gpu/drm/i915/intel_workarounds.c +5
-0+ const char *from) +{ +u32 bits = wa->mask; +u32 cur_ = cur; +u32 val_ = wa->val;Make sure
wa->maskis set to ~0u for whole registers, which it must be for thewa_fail.
It is (wa_write), unless you spotted a miss?
Quoted 2 lines
if ((cur ^ wa->val) & wa->mask) {
wa_fail(wa, cur, name, whom);Not sure if I feel like laughing or crying at my implementation. :) I was cleaning up the lot when I realized it all reduces to simplicity, but obviously missed this one..
Quoted 2 lines
return false; /* make it bool now to save churn later? */
}
Okay.
Regards,
Tvrtko
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 4/8 drm/i915: Verify engine workaround state at runtime
In reply to Tvrtko UrsulinFrom: Tvrtko Ursulin <[email protected]>
Analogue to the previous patch we add at runtime verification that after engine reset all respective workarounds have been correctly applied.
--- drivers/gpu/drm/i915/i915_drv.c | 3 +++ drivers/gpu/drm/i915/intel_workarounds.c | 6 ++++++ drivers/gpu/drm/i915/intel_workarounds.h | 2 ++ 3 files changed, 11 insertions(+)
drivers/gpu/drm/i915/i915_drv.c +3 -0
@@ -2382,6 +2382,9 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg)if (ret) goto out; +/* Catch engine workarounds not restored by engine re-init. */ +intel_engine_workarounds_verify (engine, engine->name); + out:intel_engine_cancel_stop_cs (engine);i915_gem_reset_finish_engine (engine);
drivers/gpu/drm/i915/intel_workarounds.c +6 -0
@@ -1313,6 +1313,12 @@ void intel_engine_workarounds_apply(struct intel_engine_cs *engine)wa_list_apply (engine->i915, &engine->wa_list); } +void intel_engine_workarounds_verify (struct intel_engine_cs *engine, +const char *from) +{ +wa_list_verify (engine->i915, &engine->wa_list, from); +} +#if IS_ENABLED (CONFIG_DRM_I915_SELFTEST )#include "selftests/intel_workarounds.c" #endif
drivers/gpu/drm/i915/intel_workarounds.h +2 -0
@@ -40,5 +40,7 @@ void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine);void intel_engine_workarounds_init (struct intel_engine_cs *engine);void intel_engine_workarounds_apply (struct intel_engine_cs *engine); +void intel_engine_workarounds_verify (struct intel_engine_cs *engine, +const char *from);#endif
Signature · 6 lines
2.19.1 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 5/8 drm/i915/selftests: Add tests for GT and engine workaround verification
In reply to Tvrtko UrsulinFrom: Tvrtko Ursulin <[email protected]>
Two simple selftests which test that both GT and engine workarounds are not lost after either a full GPU reset, or after the per-engine ones.
(Including checks that one engine reset is not affecting workarounds not belonging to itself.)
--- drivers/gpu/drm/i915/intel_workarounds.c | 21 +++-- drivers/gpu/drm/i915/intel_workarounds.h | 4 +- .../drm/i915/selftests/intel_workarounds.c | 90 +++++++++++++++++++ 3 files changed, 105 insertions(+), 10 deletions(-)
drivers/gpu/drm/i915/intel_workarounds.c +13 -8
@@ -990,7 +990,7 @@ wa_fail(const struct i915_wa *wa, u32 cur, const char *name, const char *from) cur, cur & wa->mask, wa->val, wa->mask); } -static void +static bool wa_verify_bits (const struct i915_wa *wa,u32 cur,const char *name,const char *from) {
@@ -1001,30 +1001,35 @@ wa_verify_bits(const struct i915_wa *wa, u32 cur, const char *name,while (bits) {if ((bits &1 ) && ((cur_ &1 ) != (val_ &1 ))) {wa_fail (wa, cur, name, from); -break ; +return false; } bits >>=1 ; cur_ >>=1 ; val_ >>=1 ; } + +return true; } -static void wa_list_verify (struct drm_i915_private *dev_priv, +static bool wa_list_verify (struct drm_i915_private *dev_priv,const struct i915_wa_list *wal,const char *from) {struct i915_wa *wa;unsigned int i; +bool res = true;for (i =0 , wa = wal->list; i < wal->count; i++, wa++) -wa_verify_bits (wa,I915_READ (wa->reg), wal->name, from); + res &=wa_verify_bits (wa,I915_READ (wa->reg), wal->name, from); + +return res; } -void intel_gt_workarounds_verify (struct drm_i915_private *dev_priv, +bool intel_gt_workarounds_verify (struct drm_i915_private *dev_priv,const char *from) { -wa_list_verify (dev_priv, &dev_priv->gt_wa_list, from); +return wa_list_verify (dev_priv, &dev_priv->gt_wa_list, from); }struct whitelist {
@@ -1313,10 +1318,10 @@ void intel_engine_workarounds_apply(struct intel_engine_cs *engine)wa_list_apply (engine->i915, &engine->wa_list); } -void intel_engine_workarounds_verify (struct intel_engine_cs *engine, +bool intel_engine_workarounds_verify (struct intel_engine_cs *engine,const char *from) { -wa_list_verify (engine->i915, &engine->wa_list, from); +return wa_list_verify (engine->i915, &engine->wa_list, from); }#if IS_ENABLED (CONFIG_DRM_I915_SELFTEST )
drivers/gpu/drm/i915/intel_workarounds.h +2 -2
@@ -33,14 +33,14 @@ int intel_ctx_workarounds_emit(struct i915_request *rq);void intel_gt_workarounds_init (struct drm_i915_private *dev_priv);void intel_gt_workarounds_apply (struct drm_i915_private *dev_priv); -void intel_gt_workarounds_verify (struct drm_i915_private *dev_priv, +bool intel_gt_workarounds_verify (struct drm_i915_private *dev_priv,const char *from);void intel_whitelist_workarounds_apply (struct intel_engine_cs *engine);void intel_engine_workarounds_init (struct intel_engine_cs *engine);void intel_engine_workarounds_apply (struct intel_engine_cs *engine); -void intel_engine_workarounds_verify (struct intel_engine_cs *engine, +bool intel_engine_workarounds_verify (struct intel_engine_cs *engine,const char *from);#endif
drivers/gpu/drm/i915/selftests/intel_workarounds.c +90 -0
100 lines not on this page · raw message
Signature · 6 lines
2.19.1 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 5/8] drm/i915/selftests: Add tests for GT and engine workaround verification
Quoting Tvrtko Ursulin (2018-11-30 11:31:58)
Quoted 111 lines
From: Tvrtko Ursulin <[email protected]>
Two simple selftests which test that both GT and engine workarounds are not lost after either a full GPU reset, or after the per-engine ones.
(Including checks that one engine reset is not affecting workarounds not belonging to itself.)
Signed-off-by Tvrtko Ursulin <[email protected]>--- drivers/gpu/drm/i915/intel_workarounds.c | 21 +++-- drivers/gpu/drm/i915/intel_workarounds.h | 4 +- .../drm/i915/selftests/intel_workarounds.c | 90 +++++++++++++++++++ 3 files changed, 105 insertions(+), 10 deletions(-)drivers/gpu/drm/i915/intel_workarounds.c +13
-8@@ -990,7 +990,7 @@ wa_fail(const struct i915_wa *wa, u32 cur, const char *name, const char *from) cur, cur & wa->mask, wa->val, wa->mask); } -static void +static bool wa_verify_bits (const struct i915_wa *wa,u32 cur,const char *name,const char *from) {@@ -1001,30 +1001,35 @@ wa_verify_bits(const struct i915_wa *wa, u32 cur, const char *name,while (bits) {if ((bits &1 ) && ((cur_ &1 ) != (val_ &1 ))) {wa_fail (wa, cur, name, from); -break ; +return false; } bits >>=1 ; cur_ >>=1 ; val_ >>=1 ; } + +return true; } -static void wa_list_verify (struct drm_i915_private *dev_priv, +static bool wa_list_verify (struct drm_i915_private *dev_priv,const struct i915_wa_list *wal,const char *from) {struct i915_wa *wa;unsigned int i; +bool res = true;for (i =0 , wa = wal->list; i < wal->count; i++, wa++) -wa_verify_bits (wa,I915_READ (wa->reg), wal->name, from); + res &=wa_verify_bits (wa,I915_READ (wa->reg), wal->name, from); + +return res; } -void intel_gt_workarounds_verify (struct drm_i915_private *dev_priv, +bool intel_gt_workarounds_verify (struct drm_i915_private *dev_priv,const char *from) { -wa_list_verify (dev_priv, &dev_priv->gt_wa_list, from); +return wa_list_verify (dev_priv, &dev_priv->gt_wa_list, from); }struct whitelist {@@ -1313,10 +1318,10 @@ void intel_engine_workarounds_apply(struct intel_engine_cs *engine)wa_list_apply (engine->i915, &engine->wa_list); } -void intel_engine_workarounds_verify (struct intel_engine_cs *engine, +bool intel_engine_workarounds_verify (struct intel_engine_cs *engine,const char *from) { -wa_list_verify (engine->i915, &engine->wa_list, from); +return wa_list_verify (engine->i915, &engine->wa_list, from); }#if IS_ENABLED (CONFIG_DRM_I915_SELFTEST )drivers/gpu/drm/i915/intel_workarounds.h +2
-2@@ -33,14 +33,14 @@ int intel_ctx_workarounds_emit(struct i915_request *rq);void intel_gt_workarounds_init (struct drm_i915_private *dev_priv);void intel_gt_workarounds_apply (struct drm_i915_private *dev_priv); -void intel_gt_workarounds_verify (struct drm_i915_private *dev_priv, +bool intel_gt_workarounds_verify (struct drm_i915_private *dev_priv,const char *from);void intel_whitelist_workarounds_apply (struct intel_engine_cs *engine);void intel_engine_workarounds_init (struct intel_engine_cs *engine);void intel_engine_workarounds_apply (struct intel_engine_cs *engine); -void intel_engine_workarounds_verify (struct intel_engine_cs *engine, +bool intel_engine_workarounds_verify (struct intel_engine_cs *engine,const char *from);#endif drivers/gpu/drm/i915/selftests/intel_workarounds.c +0
-0@@ -327,10 +327,100 @@ static int live_reset_whitelist(void *arg)return err; }
drivers/gpu/drm/i915/selftests/intel_workarounds.c static int live_reset_whitelist(void *arg) · line 339
Quoted 10 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +10
-0+static bool verify_gt_engine_wa (struct drm_i915_private *i915,const char *str) +{ +struct intel_engine_cs *engine; +enum intel_engine_id id; +bool ok = true; + + ok &=intel_gt_workarounds_verify (i915, str); + +for_each_engine (engine, i915, id) + ok &=intel_engine_workarounds_verify (engine, str);
Ok, ok.
Quoted 14 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +14
-0+ +return ok; +} + +static int +live_gpu_reset_gt_engine_workarounds (void *arg) +{ +struct drm_i915_private *i915 = arg; +struct i915_gpu_error *error = &i915->gpu_error; +bool ok; + +if (!intel_has_gpu_reset (i915)) +return 0 ; +
drivers/gpu/drm/i915/selftests/intel_workarounds.c static int live_reset_whitelist(void *arg) · line 363
Quoted 10 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +10
-0+pr_info ("Verifying after GPU reset...\n" ); + +set_bit (I915_RESET_BACKOFF , &error->flags); +set_bit (I915_RESET_HANDOFF , &error->flags); + + ok =verify_gt_engine_wa (i915,"before reset" ); +if (!ok) + goto out; + +intel_runtime_pm_get (i915);
Move RESET_HANDOFF here to avoid any repetition of earlier problems we had with the reset being applied too early.
Quoted 12 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +12
-0+i915_reset (i915, ~0 ,"live_workarounds" ); +intel_runtime_pm_put (i915); + + ok =verify_gt_engine_wa (i915,"after reset" ); + +out: +clear_bit (I915_RESET_BACKOFF , &error->flags); + +return ok ?0 : -ESRCH ; +} + +static int
drivers/gpu/drm/i915/selftests/intel_workarounds.c static int live_reset_whitelist(void *arg) · line 385
Quoted 10 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +10
-0+live_engine_reset_gt_engine_workarounds(void *arg) +{ +struct drm_i915_private *i915 = arg; +struct i915_gpu_error *error = &i915->gpu_error; +struct intel_engine_cs *engine; +enum intel_engine_id id; +bool ok; + +if (!intel_has_reset_engine (i915)) +return 0 ;
May be easier to take global_reset_lock/unlock from selftests/intel_hanghceck.
Quoted 4 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +4
-0+ +for_each_engine (engine, i915, id) { +pr_info ("Verifying after %s reset...\n" , engine->name); +
drivers/gpu/drm/i915/selftests/intel_workarounds.c static int live_reset_whitelist(void *arg) · line 399
Quoted 10 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +10
-0+set_bit (I915_RESET_BACKOFF , &error->flags); +set_bit (I915_RESET_ENGINE + engine->id, &error->flags); + + ok =verify_gt_engine_wa (i915,"before reset" ); +if (!ok) + goto out; + +intel_runtime_pm_get (i915); +i915_reset_engine (engine,"live_workarounds" ); +intel_runtime_pm_put (i915);
Once idle, and once with a spinner?
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 5/8] drm/i915/selftests: Add tests for GT and engine workaround verification
Quoted 144 lines · Chris Wilson
Quoting Tvrtko Ursulin (2018-11-30 11:31:58)
Quoted 111 lines
From: Tvrtko Ursulin <[email protected]>
Two simple selftests which test that both GT and engine workarounds are not lost after either a full GPU reset, or after the per-engine ones.
(Including checks that one engine reset is not affecting workarounds not belonging to itself.)
Signed-off-by Tvrtko Ursulin <[email protected]>--- drivers/gpu/drm/i915/intel_workarounds.c | 21 +++-- drivers/gpu/drm/i915/intel_workarounds.h | 4 +- .../drm/i915/selftests/intel_workarounds.c | 90 +++++++++++++++++++ 3 files changed, 105 insertions(+), 10 deletions(-)drivers/gpu/drm/i915/intel_workarounds.c +13
-8@@ -990,7 +990,7 @@ wa_fail(const struct i915_wa *wa, u32 cur, const char *name, const char *from) cur, cur & wa->mask, wa->val, wa->mask); } -static void +static bool wa_verify_bits (const struct i915_wa *wa,u32 cur,const char *name,const char *from) {@@ -1001,30 +1001,35 @@ wa_verify_bits(const struct i915_wa *wa, u32 cur, const char *name,while (bits) {if ((bits &1 ) && ((cur_ &1 ) != (val_ &1 ))) {wa_fail (wa, cur, name, from); -break ; +return false; } bits >>=1 ; cur_ >>=1 ; val_ >>=1 ; } + +return true; } -static void wa_list_verify (struct drm_i915_private *dev_priv, +static bool wa_list_verify (struct drm_i915_private *dev_priv,const struct i915_wa_list *wal,const char *from) {struct i915_wa *wa;unsigned int i; +bool res = true;for (i =0 , wa = wal->list; i < wal->count; i++, wa++) -wa_verify_bits (wa,I915_READ (wa->reg), wal->name, from); + res &=wa_verify_bits (wa,I915_READ (wa->reg), wal->name, from); + +return res; } -void intel_gt_workarounds_verify (struct drm_i915_private *dev_priv, +bool intel_gt_workarounds_verify (struct drm_i915_private *dev_priv,const char *from) { -wa_list_verify (dev_priv, &dev_priv->gt_wa_list, from); +return wa_list_verify (dev_priv, &dev_priv->gt_wa_list, from); }struct whitelist {@@ -1313,10 +1318,10 @@ void intel_engine_workarounds_apply(struct intel_engine_cs *engine)wa_list_apply (engine->i915, &engine->wa_list); } -void intel_engine_workarounds_verify (struct intel_engine_cs *engine, +bool intel_engine_workarounds_verify (struct intel_engine_cs *engine,const char *from) { -wa_list_verify (engine->i915, &engine->wa_list, from); +return wa_list_verify (engine->i915, &engine->wa_list, from); }#if IS_ENABLED (CONFIG_DRM_I915_SELFTEST )drivers/gpu/drm/i915/intel_workarounds.h +2
-2@@ -33,14 +33,14 @@ int intel_ctx_workarounds_emit(struct i915_request *rq);void intel_gt_workarounds_init (struct drm_i915_private *dev_priv);void intel_gt_workarounds_apply (struct drm_i915_private *dev_priv); -void intel_gt_workarounds_verify (struct drm_i915_private *dev_priv, +bool intel_gt_workarounds_verify (struct drm_i915_private *dev_priv,const char *from);void intel_whitelist_workarounds_apply (struct intel_engine_cs *engine);void intel_engine_workarounds_init (struct intel_engine_cs *engine);void intel_engine_workarounds_apply (struct intel_engine_cs *engine); -void intel_engine_workarounds_verify (struct intel_engine_cs *engine, +bool intel_engine_workarounds_verify (struct intel_engine_cs *engine,const char *from);#endif drivers/gpu/drm/i915/selftests/intel_workarounds.c +0
-0@@ -327,10 +327,100 @@ static int live_reset_whitelist(void *arg)return err; }drivers/gpu/drm/i915/selftests/intel_workarounds.c static int live_reset_whitelist(void *arg) · line 339
Quoted 10 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +10
-0+static bool verify_gt_engine_wa (struct drm_i915_private *i915,const char *str) +{ +struct intel_engine_cs *engine; +enum intel_engine_id id; +bool ok = true; + + ok &=intel_gt_workarounds_verify (i915, str); + +for_each_engine (engine, i915, id) + ok &=intel_engine_workarounds_verify (engine, str);Ok, ok.
Quoted 19 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +19
-0+ +return ok; +} + +static int +live_gpu_reset_gt_engine_workarounds (void *arg) +{ +struct drm_i915_private *i915 = arg; +struct i915_gpu_error *error = &i915->gpu_error; +bool ok; + +if (!intel_has_gpu_reset (i915)) +return 0 ; + +pr_info ("Verifying after GPU reset...\n" ); + +set_bit (I915_RESET_BACKOFF , &error->flags); +set_bit (I915_RESET_HANDOFF , &error->flags); +
Quoted 8 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c static int live_reset_whitelist(void *arg) · line 363
Quoted 5 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +5
-0+ ok =verify_gt_engine_wa (i915,"before reset" ); +if (!ok) + goto out; + +intel_runtime_pm_get (i915);Move
RESET_HANDOFFhere to avoid any repetition of earlier problems we had with the reset being applied too early.
There are not requests in this test but OK, I guess it makes it more future proof if one day something gets added.
Quoted 18 lines
Quoted 18 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +17
-0+i915_reset (i915, ~0 ,"live_workarounds" ); +intel_runtime_pm_put (i915); + + ok =verify_gt_engine_wa (i915,"after reset" ); + +out: +clear_bit (I915_RESET_BACKOFF , &error->flags); + +return ok ?0 : -ESRCH ; +} + +static int +live_engine_reset_gt_engine_workarounds (void *arg) +{ +struct drm_i915_private *i915 = arg; +struct i915_gpu_error *error = &i915->gpu_error; +struct intel_engine_cs *engine;
Quoted 8 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c static int live_reset_whitelist(void *arg) · line 385
Quoted 5 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +5
-0+enum intel_engine_id id; +bool ok; + +if (!intel_has_reset_engine (i915)) +return 0 ;May be easier to take global_reset_lock/unlock from selftests/intel_hanghceck.
I looked inside and did not find anything with this name so I don't know what you mean?
Quoted 8 lines
Quoted 8 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +8
-0+ +for_each_engine (engine, i915, id) { +pr_info ("Verifying after %s reset...\n" , engine->name); + +set_bit (I915_RESET_BACKOFF , &error->flags); +set_bit (I915_RESET_ENGINE + engine->id, &error->flags); + + ok =verify_gt_engine_wa (i915,"before reset" );
Quoted 8 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c static int live_reset_whitelist(void *arg) · line 399
Quoted 6 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +6
-0+if (!ok) + goto out; + +intel_runtime_pm_get (i915); +i915_reset_engine (engine,"live_workarounds" ); +intel_runtime_pm_put (i915);Once idle, and once with a spinner?
If idle then engine reset does nothing, so maybe I am again not following you.
Regards,
Tvrtko
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 5/8] drm/i915/selftests: Add tests for GT and engine workaround verification
Quoting Tvrtko Ursulin (2018-11-30 15:15:28)
Quoted 28 lines · Chris Wilson
Quoted 9 lines
Quoting Tvrtko Ursulin (2018-11-30 11:31:58)
Quoted 8 lines
From: Tvrtko Ursulin <[email protected]>
Two simple selftests which test that both GT and engine workarounds are not lost after either a full GPU reset, or after the per-engine ones.
(Including checks that one engine reset is not affecting workarounds not belonging to itself.)
Quoted 16 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c static int live_reset_whitelist(void *arg) · line 385
Quoted 13 lines
Signed-off-by Tvrtko Ursulin <[email protected]>---
drivers/gpu/drm/i915/selftests/intel_workarounds.c +11
-0+static int +live_engine_reset_gt_engine_workarounds (void *arg) +{ +struct drm_i915_private *i915 = arg; +struct i915_gpu_error *error = &i915->gpu_error; +struct intel_engine_cs *engine; +enum intel_engine_id id; +bool ok; + +if (!intel_has_reset_engine (i915)) +return 0 ;May be easier to take global_reset_lock/unlock from selftests/intel_hanghceck.
Quoted 2 lines
I looked inside and did not find anything with this name so I don't know what you mean?
This function
static void global_reset_lock(struct drm_i915_private *i915)
{
struct intel_engine_cs *engine;
enum intel_engine_id id;
pr_debug("%s: current gpu_error=%08lx\n",
__func__, i915->gpu_error.flags);
while (test_and_set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags))
wait_event(i915->gpu_error.reset_queue,
!test_bit(I915_RESET_BACKOFF,
&i915->gpu_error.flags));
for_each_engine(engine, i915, id) {
while (test_and_set_bit(I915_RESET_ENGINE + id,
&i915->gpu_error.flags))
wait_on_bit(&i915->gpu_error.flags,
I915_RESET_ENGINE + id,
TASK_UNINTERRUPTIBLE);
}
}in selftests/intel_hangcheck.c
Quoted 17 lines
Quoted 8 lines
Quoted 8 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +8
-0+ +for_each_engine (engine, i915, id) { +pr_info ("Verifying after %s reset...\n" , engine->name); + +set_bit (I915_RESET_BACKOFF , &error->flags); +set_bit (I915_RESET_ENGINE + engine->id, &error->flags); + + ok =verify_gt_engine_wa (i915,"before reset" );Quoted 8 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c static int live_reset_whitelist(void *arg) · line 399
Quoted 6 lines
drivers/gpu/drm/i915/selftests/intel_workarounds.c +6
-0+if (!ok) + goto out; + +intel_runtime_pm_get (i915); +i915_reset_engine (engine,"live_workarounds" ); +intel_runtime_pm_put (i915);Once idle, and once with a spinner?
Quoted 2 lines
If idle then engine reset does nothing, so maybe I am again not following you.
The engine is idle here, so no reset, right?
Also worth verifying in case we change the implementation and there is variation in HW between resetting from different states. -Chris
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 6/8 drm/i915: Move register white-listing to the common workaround framework
In reply to Tvrtko UrsulinFrom: Tvrtko Ursulin <[email protected]>
Instead of having a separate list of white-listed registers we can trivially move this to the common workarounds framework.
This brings us one step closer to the goal of driving all workaround classes using the same code.
--- drivers/gpu/drm/i915/intel_engine_cs.c | 1 + drivers/gpu/drm/i915/intel_lrc.c | 1 + drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + drivers/gpu/drm/i915/intel_workarounds.c | 83 ++++++++----------- drivers/gpu/drm/i915/intel_workarounds.h | 1 + .../drm/i915/selftests/intel_workarounds.c | 40 ++++----- 6 files changed, 57 insertions(+), 70 deletions(-)
drivers/gpu/drm/i915/intel_engine_cs.c +1 -0
@@ -725,6 +725,7 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)i915_timeline_fini (&engine->timeline);intel_wa_list_free (&engine->wa_list); +intel_wa_list_free (&engine->whitelist); }u64 intel_engine_get_active_head (const struct intel_engine_cs *engine)
drivers/gpu/drm/i915/intel_lrc.c +1 -0
@@ -2316,6 +2316,7 @@ int logical_render_ring_init(struct intel_engine_cs *engine) ret); } +intel_whitelist_workarounds_init (engine);intel_engine_workarounds_init (engine);return 0 ;
drivers/gpu/drm/i915/intel_ringbuffer.h +1 -0
@@ -453,6 +453,7 @@ struct intel_engine_cs {struct intel_hw_status_page status_page;struct i915_ctx_workarounds wa_ctx;struct i915_wa_list wa_list; +struct i915_wa_list whitelist;struct i915_vma *scratch;u32 irq_keep_mask;/* always keep these interrupts */
drivers/gpu/drm/i915/intel_workarounds.c +33 -50
165 lines not on this page · raw message
drivers/gpu/drm/i915/intel_workarounds.h +1 -0
@@ -36,6 +36,7 @@ void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv);bool intel_gt_workarounds_verify (struct drm_i915_private *dev_priv,const char *from); +void intel_whitelist_workarounds_init (struct intel_engine_cs *engine);void intel_whitelist_workarounds_apply (struct intel_engine_cs *engine);void intel_engine_workarounds_init (struct intel_engine_cs *engine);
drivers/gpu/drm/i915/selftests/intel_workarounds.c +20 -20
@@ -92,17 +92,23 @@ read_nonprivs(struct i915_gem_context *ctx, struct intel_engine_cs *engine)return ERR_PTR (err); } -static u32 get_whitelist_reg (const struct whitelist *w,unsigned int i) +static u32 +get_whitelist_reg (const struct intel_engine_cs *engine,unsigned int i) { -return i < w->count ?i915_mmio_reg_offset (w->reg[i]) : w->nopid; +i915_reg_t reg = i < engine->whitelist.count ? + engine->whitelist.list[i].reg : +RING_NOPID (engine->mmio_base); + +return i915_mmio_reg_offset (reg); } -static void print_results (const struct whitelist *w,const u32 *results) +static void +print_results (const struct intel_engine_cs *engine,const u32 *results) {unsigned int i;for (i =0 ; i <RING_MAX_NONPRIV_SLOTS ; i++) { -u32 expected =get_whitelist_reg (w, i); +u32 expected =get_whitelist_reg (engine, i);u32 actual = results[i]; pr_info("RING_NONPRIV[%d]: expected 0x%08x, found 0x%08x\n",
@@ -110,8 +116,7 @@ static void print_results(const struct whitelist *w, const u32 *results) } } -static int check_whitelist (const struct whitelist *w, -struct i915_gem_context *ctx, +static int check_whitelist (struct i915_gem_context *ctx,struct intel_engine_cs *engine) {struct drm_i915_gem_object *results;
@@ -139,11 +144,11 @@ static int check_whitelist(const struct whitelist *w, }for (i =0 ; i <RING_MAX_NONPRIV_SLOTS ; i++) { -u32 expected =get_whitelist_reg (w, i); +u32 expected =get_whitelist_reg (engine, i);u32 actual = vaddr[i];if (expected != actual) { -print_results (w, vaddr); +print_results (engine, vaddr);pr_err ("Invalid RING_NONPRIV[%d], expected 0x%08x, found 0x%08x\n" , i, expected, actual);
@@ -215,7 +220,6 @@ switch_to_scratch_context(struct intel_engine_cs *engine,static int check_whitelist_across_reset (struct intel_engine_cs *engine,int (*reset)(struct intel_engine_cs *), -const struct whitelist *w,const char *name) {struct drm_i915_private *i915 = engine->i915;
@@ -225,7 +229,7 @@ static int check_whitelist_across_reset(struct intel_engine_cs *engine,int err;pr_info ("Checking %d whitelisted registers (RING_NONPRIV) [%s]\n" , - w->count, name); + engine->whitelist.count, name);if (want_spin) { err =igt_spinner_init (&spin, i915);
@@ -237,7 +241,7 @@ static int check_whitelist_across_reset(struct intel_engine_cs *engine,if (IS_ERR (ctx))return PTR_ERR (ctx); - err =check_whitelist (w, ctx, engine); + err =check_whitelist (ctx, engine);if (err) {pr_err ("Invalid whitelist *before* %s reset!\n" , name); goto out;
@@ -261,7 +265,7 @@ static int check_whitelist_across_reset(struct intel_engine_cs *engine, goto out; } - err =check_whitelist (w, ctx, engine); + err =check_whitelist (ctx, engine);if (err) {pr_err ("Whitelist not preserved in context across %s reset!\n" , name);
@@ -274,7 +278,7 @@ static int check_whitelist_across_reset(struct intel_engine_cs *engine,if (IS_ERR (ctx))return PTR_ERR (ctx); - err =check_whitelist (w, ctx, engine); + err =check_whitelist (ctx, engine);if (err) {pr_err ("Invalid whitelist *after* %s reset in fresh context!\n" , name);
@@ -291,15 +295,11 @@ static int live_reset_whitelist(void *arg)struct drm_i915_private *i915 = arg;struct intel_engine_cs *engine = i915->engine[RCS ];struct i915_gpu_error *error = &i915->gpu_error; -struct whitelist w;int err =0 ;/* If we reset the gpu, we should not lose the RING_NONPRIV */ -if (!engine) -return 0 ; - -if (!whitelist_build (engine, &w)) +if (!engine || engine->whitelist.count ==0 )return 0 ;set_bit (I915_RESET_BACKOFF , &error->flags);
@@ -307,7 +307,7 @@ static int live_reset_whitelist(void *arg)if (intel_has_reset_engine (i915)) { err =check_whitelist_across_reset (engine, - do_engine_reset, &w, + do_engine_reset,"engine" );if (err) goto out;
@@ -315,7 +315,7 @@ static int live_reset_whitelist(void *arg)if (intel_has_gpu_reset (i915)) { err =check_whitelist_across_reset (engine, - do_device_reset, &w, + do_device_reset,"device" );if (err) goto out;
Signature · 6 lines
2.19.1 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 6/8] drm/i915: Move register white-listing to the common workaround framework
Quoting Tvrtko Ursulin (2018-11-30 11:31:59)
Quoted 7 lines
drivers/gpu/drm/i915/intel_workarounds.c +2
-4-static void whitelist_reg (struct whitelist *w,i915_reg_t reg) +static void +whitelist_reg (struct i915_wa_list *wal,i915_reg_t reg) { -if (GEM_DEBUG_WARN_ON (w->count >=RING_MAX_NONPRIV_SLOTS )) -return ; -
drivers/gpu/drm/i915/intel_workarounds.c bool intel_gt_workarounds_verify(struct drm_i915_private *dev_priv, · line 1042
Quoted 10 lines
drivers/gpu/drm/i915/intel_workarounds.c +4
-5- w->reg[w->count++] = reg; -} +struct i915_wa wa = { + .reg = reg + }; -static void bdw_whitelist_build (struct whitelist *w) -{ -} +if (GEM_WARN_ON (wal->count >=RING_MAX_NONPRIV_SLOTS ))
We only need this code for pre-merge testing of patches as the build list is static.
-Chris
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 6/8] drm/i915: Move register white-listing to the common workaround framework
Quoted 14 lines · Chris Wilson
Quoting Tvrtko Ursulin (2018-11-30 11:31:59)
Quoted 13 lines
drivers/gpu/drm/i915/intel_workarounds.c +5
-6-static void whitelist_reg (struct whitelist *w,i915_reg_t reg) +static void +whitelist_reg (struct i915_wa_list *wal,i915_reg_t reg) { -if (GEM_DEBUG_WARN_ON (w->count >=RING_MAX_NONPRIV_SLOTS )) -return ; - - w->reg[w->count++] = reg; -} +struct i915_wa wa = { + .reg = reg + };
Quoted 7 lines
drivers/gpu/drm/i915/intel_workarounds.c bool intel_gt_workarounds_verify(struct drm_i915_private *dev_priv, · line 1042
Quoted 4 lines
drivers/gpu/drm/i915/intel_workarounds.c +1
-3-static void bdw_whitelist_build (struct whitelist *w) -{ -} +if (GEM_WARN_ON (wal->count >=RING_MAX_NONPRIV_SLOTS ))We only need this code for pre-merge testing of patches as the build list is static.
I interpret this as change to GEM_DEBUG_WARN_ON - makes sense.
Regards,
Tvrtko
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 7/8 drm/i915: Fuse per-context workaround handling with the common framework
In reply to Tvrtko UrsulinFrom: Tvrtko Ursulin <[email protected]>
Convert the per context workaround handling code to run against the newly introduced common workaround framework and fuse the two to use the existing smarter list add helper, the one which does the sorted insert and merges registers where possible.
This completes migration of all four classes of workarounds onto the common framework.
Existing macros are kept untouched for smaller code churn.
--- drivers/gpu/drm/i915/i915_debugfs.c | 11 +- drivers/gpu/drm/i915/i915_drv.h | 16 +- drivers/gpu/drm/i915/i915_gem.c | 1 + drivers/gpu/drm/i915/i915_gem_context.c | 6 +- drivers/gpu/drm/i915/intel_workarounds.c | 267 ++++++++++------------- drivers/gpu/drm/i915/intel_workarounds.h | 3 +- 6 files changed, 128 insertions(+), 176 deletions(-)
drivers/gpu/drm/i915/i915_debugfs.c +6 -5
@@ -3375,13 +3375,14 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)static int i915_wa_registers (struct seq_file *m,void *unused) { -struct i915_workarounds *wa = &node_to_i915 (m->private)->workarounds; -int i; +const struct i915_wa_list *wal = &node_to_i915 (m->private)->wa_list; +struct i915_wa *wa; +unsigned int i; -seq_printf (m,"Workarounds applied: %d\n" , wa->count); -for (i =0 ; i < wa->count; ++i) +seq_printf (m,"Workarounds applied: %u\n" , wal->count); +for (i =0 , wa = wal->list; i < wal->count; i++, wa++)seq_printf (m,"0x%X: 0x%08X, mask: 0x%08X\n" , - wa->reg[i].addr, wa->reg[i].value, wa->reg[i].mask); +i915_mmio_reg_offset (wa->reg), wa->val, wa->mask);return 0 ; }
drivers/gpu/drm/i915/i915_drv.h +1 -15
@@ -1189,20 +1189,6 @@ struct i915_frontbuffer_tracking {unsigned flip_bits; }; -struct i915_wa_reg { -u32 addr; -u32 value; -/* bitmask representing WA bits */ -u32 mask; -}; - -#define I915_MAX_WA_REGS 16 - -struct i915_workarounds { -struct i915_wa_reg reg[I915_MAX_WA_REGS ]; -u32 count; -}; -struct i915_virtual_gpu {bool active;u32 caps;
@@ -1652,7 +1638,7 @@ struct drm_i915_private {int dpio_phy_iosf_port[I915_NUM_PHYS_VLV ]; -struct i915_workarounds workarounds; +struct i915_wa_list wa_list;struct i915_wa_list gt_wa_list;struct i915_frontbuffer_tracking fb_tracking;
drivers/gpu/drm/i915/i915_gem.c +1 -0
@@ -5709,6 +5709,7 @@ void i915_gem_fini(struct drm_i915_private *dev_priv)i915_gem_contexts_fini (dev_priv);mutex_unlock (&dev_priv->drm.struct_mutex); +intel_wa_list_free (&dev_priv->wa_list);intel_wa_list_free (&dev_priv->gt_wa_list);intel_cleanup_gt_powersave (dev_priv);
drivers/gpu/drm/i915/i915_gem_context.c +1 -5
@@ -535,16 +535,12 @@ static bool needs_preempt_context(struct drm_i915_private *i915)int i915_gem_contexts_init (struct drm_i915_private *dev_priv) {struct i915_gem_context *ctx; -int ret;/* Reassure ourselves we are only called once */ GEM_BUG_ON (dev_priv->kernel_context);GEM_BUG_ON (dev_priv->preempt_context); - ret =intel_ctx_workarounds_init (dev_priv); -if (ret) -return ret; - +intel_ctx_workarounds_init (dev_priv);init_contexts (dev_priv);/* lowest priority; idle task */
drivers/gpu/drm/i915/intel_workarounds.c +117 -150
471 lines not on this page · raw message
drivers/gpu/drm/i915/intel_workarounds.h +2 -1
@@ -18,6 +18,7 @@ struct i915_wa {struct i915_wa_list {const char *name;unsigned int count; +unsigned int wa_count;struct i915_wa *list;unsigned int __size; };
@@ -28,7 +29,7 @@ static inline void intel_wa_list_free(struct i915_wa_list *wal)memset (wal,0 ,sizeof (*wal)); } -int intel_ctx_workarounds_init (struct drm_i915_private *dev_priv); +void intel_ctx_workarounds_init (struct drm_i915_private *dev_priv);int intel_ctx_workarounds_emit (struct i915_request *rq);void intel_gt_workarounds_init (struct drm_i915_private *dev_priv);
Signature · 6 lines
2.19.1 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 7/8] drm/i915: Fuse per-context workaround handling with the common framework
Quoting Tvrtko Ursulin (2018-11-30 11:32:00)
Quoted 15 lines
From: Tvrtko Ursulin <[email protected]>
Convert the per context workaround handling code to run against the newly introduced common workaround framework and fuse the two to use the existing smarter list add helper, the one which does the sorted insert and merges registers where possible.
This completes migration of all four classes of workarounds onto the common framework.
Existing macros are kept untouched for smaller code churn.
Signed-off-by Tvrtko Ursulin <[email protected]>---
drivers/gpu/drm/i915/i915_drv.h struct drm_i915_private { · line 1642
Quoted 6 lines
drivers/gpu/drm/i915/i915_drv.h +1
-1@@ -1652,7 +1638,7 @@ struct drm_i915_private {int dpio_phy_iosf_port[I915_NUM_PHYS_VLV ]; -struct i915_workarounds workarounds; +struct i915_wa_list wa_list;struct i915_wa_list gt_wa_list;
ctx_wa_list ?
-Chris
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 7/8] drm/i915: Fuse per-context workaround handling with the common framework
Quoted 17 lines · Chris Wilson
Quoting Tvrtko Ursulin (2018-11-30 11:32:00)
Quoted 16 lines
From: Tvrtko Ursulin <[email protected]>
Convert the per context workaround handling code to run against the newly introduced common workaround framework and fuse the two to use the existing smarter list add helper, the one which does the sorted insert and merges registers where possible.
This completes migration of all four classes of workarounds onto the common framework.
Existing macros are kept untouched for smaller code churn.
Signed-off-by Tvrtko Ursulin <[email protected]>---
(quoted diff) +0
-0@@ -1652,7 +1638,7 @@ struct drm_i915_private {
Quoted 7 lines
drivers/gpu/drm/i915/i915_drv.h struct drm_i915_private { · line 1642
Quoted 5 lines
drivers/gpu/drm/i915/i915_drv.h +1
-1int dpio_phy_iosf_port[I915_NUM_PHYS_VLV ]; -struct i915_workarounds workarounds; +struct i915_wa_list wa_list;struct i915_wa_list gt_wa_list;
ctx_wa_list?
Can do, will do.
Regards,
Tvrtko
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 8/8 drm/i915: Trim unused workaround list entries
In reply to Tvrtko UrsulinFrom: Tvrtko Ursulin <[email protected]>
The new workaround list allocator grows the list in chunks so will end up with some unused space. Trim it when the initialization phase is done to free up a tiny bit of slab.
--- drivers/gpu/drm/i915/intel_workarounds.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/gpu/drm/i915/intel_workarounds.c +13 -0
@@ -55,6 +55,19 @@ static void wa_init_start(struct i915_wa_list *wal, const char *name)static void wa_init_finish (struct i915_wa_list *wal) { +/* Trim unused entries. */ +if (wal->count < wal->__size) { +struct i915_wa *wa = +kcalloc (wal->count,sizeof (*wa),GFP_KERNEL ); + +if (wa) { +memcpy (wa, wal->list,sizeof (*wa) * wal->count); +kfree (wal->list); + wal->list = wa; + wal->__size = wal->count; + } + } +if (wal->count)DRM_DEBUG_DRIVER ("Initialized %u %s workarounds\n" , wal->wa_count, wal->name);
Signature · 6 lines
2.19.1 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 8/8] drm/i915: Trim unused workaround list entries
Quoting Tvrtko Ursulin (2018-11-30 11:32:01)
Quoted 16 lines
From: Tvrtko Ursulin <[email protected]>
The new workaround list allocator grows the list in chunks so will end up with some unused space. Trim it when the initialization phase is done to free up a tiny bit of slab.
Signed-off-by Tvrtko Ursulin <[email protected]>--- drivers/gpu/drm/i915/intel_workarounds.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)drivers/gpu/drm/i915/intel_workarounds.c +0
-0
drivers/gpu/drm/i915/intel_workarounds.c static void wa_init_start(struct i915_wa_list *wal, const char *name) · line 61
Quoted 7 lines
drivers/gpu/drm/i915/intel_workarounds.c +4
-0@@ -55,6 +55,19 @@ static void wa_init_start(struct i915_wa_list *wal, const char *name)static void wa_init_finish (struct i915_wa_list *wal) { +/* Trim unused entries. */ +if (wal->count < wal->__size) { +struct i915_wa *wa = +kcalloc (wal->count,sizeof (*wa),GFP_KERNEL );
kcalloc followed by memcpy, what have you done with Tvrtko? kmemdup ?
-Chris
_______________________________________________
Intel-gfx mailing list [email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 8/8] drm/i915: Trim unused workaround list entries
Quoted 18 lines · Chris Wilson
Quoting Tvrtko Ursulin (2018-11-30 11:32:01)
Quoted 17 lines
From: Tvrtko Ursulin <[email protected]>
The new workaround list allocator grows the list in chunks so will end up with some unused space. Trim it when the initialization phase is done to free up a tiny bit of slab.
Signed-off-by Tvrtko Ursulin <[email protected]>--- drivers/gpu/drm/i915/intel_workarounds.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)drivers/gpu/drm/i915/intel_workarounds.c +0
-0@@ -55,6 +55,19 @@ static void wa_init_start(struct i915_wa_list *wal, const char *name)
Quoted 9 lines
drivers/gpu/drm/i915/intel_workarounds.c static void wa_init_start(struct i915_wa_list *wal, const char *name) · line 61
Quoted 6 lines
drivers/gpu/drm/i915/intel_workarounds.c +4
-0static void wa_init_finish (struct i915_wa_list *wal) { +/* Trim unused entries. */ +if (wal->count < wal->__size) { +struct i915_wa *wa = +kcalloc (wal->count,sizeof (*wa),GFP_KERNEL );kcalloc followed by memcpy, what have you done with Tvrtko? kmemdup ?
Oh well, the richer the API the easier to forget. :)
Regards,
Tvrtko
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Patchwork
CI✗ Fi.CI.BAT: failure for Restore workarounds after engine reset and unify their handling
In reply to Tvrtko Ursulin== Series Details ==
== Series Details ==
Series: Restore workarounds after engine reset and unify their handling
URL : https://patchwork.freedesktop.org/series/53313/
State : failure
== Summary ==
Applying: drm/i915: Record GT workarounds in a list
Applying: drm/i915: Introduce per-engine workarounds
Applying: drm/i915: Verify GT workaround state at runtime
Applying: drm/i915: Verify engine workaround state at runtime
Applying: drm/i915/selftests: Add tests for GT and engine workaround verification
Applying: drm/i915: Move register white-listing to the common workaround framework
error: sha1 information is lacking or useless (drivers/gpu/drm/i915/selftests/intel_workarounds.c).
error: could not build fake ancestor
Patch failed at 0006 drm/i915: Move register white-listing to the common workaround framework Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx