]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/i915/selftests: Disable heartbeat around RPS interrupt testing
authorChris Wilson <chris@chris-wilson.co.uk>
Wed, 22 Apr 2020 08:38:55 +0000 (09:38 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Wed, 22 Apr 2020 09:59:46 +0000 (10:59 +0100)
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
drivers/gpu/drm/i915/gt/selftest_rps.c

index 0d7ed000aff07c542b7639093da0ce7ff387f95e..9d9c8e0aa2e704b2e594bf07150854f78356f0bc 100644 (file)
@@ -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"
 /* 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,