#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"
/* 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)
{
}
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;
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);
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;
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;
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;
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,
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;
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;
}
i915_vma_unpin(vma);
i915_vma_put(vma);
+ engine_heartbeat_enable(engine, saved_heartbeat);
if (igt_flush_test(gt->i915))
err = -EIO;
if (err)
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;
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;
}
i915_vma_unpin(vma);
i915_vma_put(vma);
+ engine_heartbeat_enable(engine, saved_heartbeat);
if (igt_flush_test(gt->i915))
err = -EIO;
if (err)
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;
/* 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;
}
rps->work.func = dummy_rps_work;
for_each_engine(engine, gt, id) {
+ unsigned long saved_heartbeat;
struct i915_request *rq;
struct {
u64 power;
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;
}
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;
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,