summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/gt/selftest_rps.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2020-04-22 09:38:55 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2020-04-22 10:59:46 +0100
commitcbb6f8805a4cfcf6bd97dfd0de399f9f3f8f7cdc (patch)
tree6800e6e02ecae03b55b4460d8a5df6feab1b6aab /drivers/gpu/drm/i915/gt/selftest_rps.c
parent33883310cd8ed365a4279600b329c50992e8f528 (diff)
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: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200422083855.26842-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/gt/selftest_rps.c')
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_rps.c59
1 files changed, 55 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/gt/selftest_rps.c b/drivers/gpu/drm/i915/gt/selftest_rps.c
index 0d7ed000aff0..9d9c8e0aa2e7 100644
--- a/drivers/gpu/drm/i915/gt/selftest_rps.c
+++ b/drivers/gpu/drm/i915/gt/selftest_rps.c
@@ -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 @@ err_vma:
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 @@ err_vma:
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,