Commit cbb6f880 authored by Chris Wilson's avatar Chris Wilson

drm/i915/selftests: Disable heartbeat around RPS interrupt testing

For verifying reciving the EI interrupts, we need to hold the GPU in
very precise conditions (in terms of C0 cycles during the EI). If we
preempt the busy load to handle the heartbeat, this may perturb the busy
load causing us to miss the interrupt.

The other tests, while not as time sensitive, may also be slightly
perturbed, so apply the heartbeat protection across all the
measurements.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200422083855.26842-1-chris@chris-wilson.co.uk
parent 33883310
......@@ -6,6 +6,7 @@
#include <linux/pm_qos.h>
#include <linux/sort.h>
#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(&gt->rc6);
err = __rps_down_interrupt(rps, engine);
intel_rc6_enable(&gt->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,
......
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