diff --git a/drivers/gpu/drm/i915/gt/selftest_rps.c b/drivers/gpu/drm/i915/gt/selftest_rps.c index 0d7ed000aff07c542b7639093da0ce7ff387f95e..9d9c8e0aa2e704b2e594bf07150854f78356f0bc 100644 --- a/drivers/gpu/drm/i915/gt/selftest_rps.c +++ b/drivers/gpu/drm/i915/gt/selftest_rps.c @@ -6,6 +6,7 @@ #include #include +#include "intel_engine_heartbeat.h" #include "intel_engine_pm.h" #include "intel_gpu_commands.h" #include "intel_gt_pm.h" @@ -18,6 +19,26 @@ /* Try to isolate the impact of cstates from determing frequency response */ #define CPU_LATENCY 0 /* -1 to disable pm_qos, 0 to disable cstates */ +static unsigned long engine_heartbeat_disable(struct intel_engine_cs *engine) +{ + unsigned long old; + + old = fetch_and_zero(&engine->props.heartbeat_interval_ms); + + intel_engine_pm_get(engine); + intel_engine_park_heartbeat(engine); + + return old; +} + +static void engine_heartbeat_enable(struct intel_engine_cs *engine, + unsigned long saved) +{ + intel_engine_pm_put(engine); + + engine->props.heartbeat_interval_ms = saved; +} + static void dummy_rps_work(struct work_struct *wrk) { } @@ -218,6 +239,7 @@ int live_rps_control(void *arg) intel_gt_pm_get(gt); for_each_engine(engine, gt, id) { + unsigned long saved_heartbeat; struct i915_request *rq; ktime_t min_dt, max_dt; int f, limit; @@ -226,6 +248,8 @@ int live_rps_control(void *arg) if (!intel_engine_can_store_dword(engine)) continue; + saved_heartbeat = engine_heartbeat_disable(engine); + rq = igt_spinner_create_request(&spin, engine->kernel_context, MI_NOOP); @@ -240,6 +264,7 @@ int live_rps_control(void *arg) pr_err("%s: RPS spinner did not start\n", engine->name); igt_spinner_end(&spin); + engine_heartbeat_enable(engine, saved_heartbeat); intel_gt_set_wedged(engine->gt); err = -EIO; break; @@ -249,6 +274,7 @@ int live_rps_control(void *arg) pr_err("%s: could not set minimum frequency [%x], only %x!\n", engine->name, rps->min_freq, read_cagf(rps)); igt_spinner_end(&spin); + engine_heartbeat_enable(engine, saved_heartbeat); show_pstate_limits(rps); err = -EINVAL; break; @@ -265,6 +291,7 @@ int live_rps_control(void *arg) pr_err("%s: could not restore minimum frequency [%x], only %x!\n", engine->name, rps->min_freq, read_cagf(rps)); igt_spinner_end(&spin); + engine_heartbeat_enable(engine, saved_heartbeat); show_pstate_limits(rps); err = -EINVAL; break; @@ -279,6 +306,7 @@ int live_rps_control(void *arg) min_dt = ktime_sub(ktime_get(), min_dt); igt_spinner_end(&spin); + engine_heartbeat_enable(engine, saved_heartbeat); pr_info("%s: range:[%x:%uMHz, %x:%uMHz] limit:[%x:%uMHz], %x:%x response %lluns:%lluns\n", engine->name, @@ -441,6 +469,7 @@ int live_rps_frequency_cs(void *arg) rps->work.func = dummy_rps_work; for_each_engine(engine, gt, id) { + unsigned long saved_heartbeat; struct i915_request *rq; struct i915_vma *vma; u32 *cancel, *cntr; @@ -449,11 +478,14 @@ int live_rps_frequency_cs(void *arg) int freq; } min, max; + saved_heartbeat = engine_heartbeat_disable(engine); + vma = create_spin_counter(engine, engine->kernel_context->vm, false, &cancel, &cntr); if (IS_ERR(vma)) { err = PTR_ERR(vma); + engine_heartbeat_enable(engine, saved_heartbeat); break; } @@ -533,6 +565,7 @@ int live_rps_frequency_cs(void *arg) i915_vma_unpin(vma); i915_vma_put(vma); + engine_heartbeat_enable(engine, saved_heartbeat); if (igt_flush_test(gt->i915)) err = -EIO; if (err) @@ -578,6 +611,7 @@ int live_rps_frequency_srm(void *arg) rps->work.func = dummy_rps_work; for_each_engine(engine, gt, id) { + unsigned long saved_heartbeat; struct i915_request *rq; struct i915_vma *vma; u32 *cancel, *cntr; @@ -586,11 +620,14 @@ int live_rps_frequency_srm(void *arg) int freq; } min, max; + saved_heartbeat = engine_heartbeat_disable(engine); + vma = create_spin_counter(engine, engine->kernel_context->vm, true, &cancel, &cntr); if (IS_ERR(vma)) { err = PTR_ERR(vma); + engine_heartbeat_enable(engine, saved_heartbeat); break; } @@ -669,6 +706,7 @@ int live_rps_frequency_srm(void *arg) i915_vma_unpin(vma); i915_vma_put(vma); + engine_heartbeat_enable(engine, saved_heartbeat); if (igt_flush_test(gt->i915)) err = -EIO; if (err) @@ -858,12 +896,16 @@ int live_rps_interrupt(void *arg) for_each_engine(engine, gt, id) { /* Keep the engine busy with a spinner; expect an UP! */ if (pm_events & GEN6_PM_RP_UP_THRESHOLD) { + unsigned long saved_heartbeat; + intel_gt_pm_wait_for_idle(engine->gt); GEM_BUG_ON(rps->active); - intel_engine_pm_get(engine); + saved_heartbeat = engine_heartbeat_disable(engine); + err = __rps_up_interrupt(rps, engine, &spin); - intel_engine_pm_put(engine); + + engine_heartbeat_enable(engine, saved_heartbeat); if (err) goto out; @@ -872,13 +914,15 @@ int live_rps_interrupt(void *arg) /* Keep the engine awake but idle and check for DOWN */ if (pm_events & GEN6_PM_RP_DOWN_THRESHOLD) { - intel_engine_pm_get(engine); + unsigned long saved_heartbeat; + + saved_heartbeat = engine_heartbeat_disable(engine); intel_rc6_disable(>->rc6); err = __rps_down_interrupt(rps, engine); intel_rc6_enable(>->rc6); - intel_engine_pm_put(engine); + engine_heartbeat_enable(engine, saved_heartbeat); if (err) goto out; } @@ -954,6 +998,7 @@ int live_rps_power(void *arg) rps->work.func = dummy_rps_work; for_each_engine(engine, gt, id) { + unsigned long saved_heartbeat; struct i915_request *rq; struct { u64 power; @@ -963,10 +1008,13 @@ int live_rps_power(void *arg) if (!intel_engine_can_store_dword(engine)) continue; + saved_heartbeat = engine_heartbeat_disable(engine); + rq = igt_spinner_create_request(&spin, engine->kernel_context, MI_NOOP); if (IS_ERR(rq)) { + engine_heartbeat_enable(engine, saved_heartbeat); err = PTR_ERR(rq); break; } @@ -976,6 +1024,8 @@ int live_rps_power(void *arg) if (!igt_wait_for_spinner(&spin, rq)) { pr_err("%s: RPS spinner did not start\n", engine->name); + igt_spinner_end(&spin); + engine_heartbeat_enable(engine, saved_heartbeat); intel_gt_set_wedged(engine->gt); err = -EIO; break; @@ -988,6 +1038,7 @@ int live_rps_power(void *arg) min.power = measure_power_at(rps, &min.freq); igt_spinner_end(&spin); + engine_heartbeat_enable(engine, saved_heartbeat); pr_info("%s: min:%llumW @ %uMHz, max:%llumW @ %uMHz\n", engine->name,