summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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,