Commit 617e87c0 authored by John Harrison's avatar John Harrison

drm/i915/selftest: Fix hangcheck self test for GuC submission

When GuC submission is enabled, the GuC controls engine resets. Rather
than explicitly triggering a reset, the driver must submit a hanging
context to GuC and wait for the reset to occur.

Conversely, one of the tests specifically sends hanging batches to the
engines but wants them to sit around until a manual reset of the full
GT (including GuC itself). That means disabling GuC based engine
resets to prevent those from killing the hanging batch too soon. So,
add support to the scheduling policy helper for disabling resets as
well as making them quicker!

In GuC submission mode, the 'is engine idle' test basically turns into
'is engine PM wakelock held'. Independently, there is a heartbeat
disable helper function that the tests use. For unexplained reasons,
this acquires the engine wakelock before disabling the heartbeat and
only releases it when re-enabling the heartbeat. As one of the tests
tries to do a wait for idle in the middle of a heartbeat disabled
section, it is therefore guaranteed to always fail. Added a 'no_pm'
variant of the heartbeat helper that allows the engine to be asleep
while also having heartbeats disabled.
Signed-off-by: default avatarJohn Harrison <John.C.Harrison@Intel.com>
Signed-off-by: default avatarMatthew Brost <matthew.brost@intel.com>
Reviewed-by: default avatarMatthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: default avatarJohn Harrison <John.C.Harrison@Intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210727002348.97202-31-matthew.brost@intel.com
parent 716c61c8
......@@ -405,3 +405,25 @@ void st_engine_heartbeat_enable(struct intel_engine_cs *engine)
engine->props.heartbeat_interval_ms =
engine->defaults.heartbeat_interval_ms;
}
void st_engine_heartbeat_disable_no_pm(struct intel_engine_cs *engine)
{
engine->props.heartbeat_interval_ms = 0;
/*
* Park the heartbeat but without holding the PM lock as that
* makes the engines appear not-idle. Note that if/when unpark
* is called due to the PM lock being acquired later the
* heartbeat still won't be enabled because of the above = 0.
*/
if (intel_engine_pm_get_if_awake(engine)) {
intel_engine_park_heartbeat(engine);
intel_engine_pm_put(engine);
}
}
void st_engine_heartbeat_enable_no_pm(struct intel_engine_cs *engine)
{
engine->props.heartbeat_interval_ms =
engine->defaults.heartbeat_interval_ms;
}
......@@ -9,6 +9,8 @@
struct intel_engine_cs;
void st_engine_heartbeat_disable(struct intel_engine_cs *engine);
void st_engine_heartbeat_disable_no_pm(struct intel_engine_cs *engine);
void st_engine_heartbeat_enable(struct intel_engine_cs *engine);
void st_engine_heartbeat_enable_no_pm(struct intel_engine_cs *engine);
#endif /* SELFTEST_ENGINE_HEARTBEAT_H */
......@@ -408,7 +408,8 @@ static int live_mocs_reset(void *arg)
struct intel_context *ce;
int err2;
err = intel_selftest_modify_policy(engine, &saved);
err = intel_selftest_modify_policy(engine, &saved,
SELFTEST_SCHEDULER_MODIFY_FAST_RESET);
if (err)
break;
......
......@@ -810,7 +810,8 @@ static int live_reset_whitelist(void *arg)
struct intel_selftest_saved_policy saved;
int err2;
err = intel_selftest_modify_policy(engine, &saved);
err = intel_selftest_modify_policy(engine, &saved,
SELFTEST_SCHEDULER_MODIFY_FAST_RESET);
if (err)
goto out;
......@@ -1278,7 +1279,8 @@ live_engine_reset_workarounds(void *arg)
int ret2;
pr_info("Verifying after %s reset...\n", engine->name);
ret = intel_selftest_modify_policy(engine, &saved);
ret = intel_selftest_modify_policy(engine, &saved,
SELFTEST_SCHEDULER_MODIFY_FAST_RESET);
if (ret)
break;
......
......@@ -15,7 +15,8 @@
#define WAIT_FOR_RESET_TIME 1000
int intel_selftest_modify_policy(struct intel_engine_cs *engine,
struct intel_selftest_saved_policy *saved)
struct intel_selftest_saved_policy *saved,
u32 modify_type)
{
int err;
......@@ -25,6 +26,8 @@ int intel_selftest_modify_policy(struct intel_engine_cs *engine,
saved->timeslice = engine->props.timeslice_duration_ms;
saved->preempt_timeout = engine->props.preempt_timeout_ms;
switch (modify_type) {
case SELFTEST_SCHEDULER_MODIFY_FAST_RESET:
/*
* Enable force pre-emption on time slice expiration
* together with engine reset on pre-emption timeout.
......@@ -37,6 +40,16 @@ int intel_selftest_modify_policy(struct intel_engine_cs *engine,
engine->flags |= I915_ENGINE_WANT_FORCED_PREEMPTION;
engine->props.timeslice_duration_ms = REDUCED_TIMESLICE;
engine->props.preempt_timeout_ms = REDUCED_PREEMPT;
break;
case SELFTEST_SCHEDULER_MODIFY_NO_HANGCHECK:
engine->props.preempt_timeout_ms = 0;
break;
default:
pr_err("Invalid scheduler policy modification type: %d!\n", modify_type);
return -EINVAL;
}
if (!intel_engine_uses_guc(engine))
return 0;
......
......@@ -18,8 +18,14 @@ struct intel_selftest_saved_policy {
u64 preempt_timeout;
};
enum selftest_scheduler_modify {
SELFTEST_SCHEDULER_MODIFY_NO_HANGCHECK = 0,
SELFTEST_SCHEDULER_MODIFY_FAST_RESET,
};
int intel_selftest_modify_policy(struct intel_engine_cs *engine,
struct intel_selftest_saved_policy *saved);
struct intel_selftest_saved_policy *saved,
enum selftest_scheduler_modify modify_type);
int intel_selftest_restore_policy(struct intel_engine_cs *engine,
struct intel_selftest_saved_policy *saved);
int intel_selftest_wait_for_rq(struct i915_request *rq);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment