root/drivers/gpu/drm/i915/gt/selftest_engine_pm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. live_engine_pm
  2. live_engine_pm_selftests

   1 /*
   2  * SPDX-License-Identifier: GPL-2.0
   3  *
   4  * Copyright © 2018 Intel Corporation
   5  */
   6 
   7 #include "i915_selftest.h"
   8 #include "selftest_engine.h"
   9 #include "selftests/igt_atomic.h"
  10 
  11 static int live_engine_pm(void *arg)
  12 {
  13         struct intel_gt *gt = arg;
  14         struct intel_engine_cs *engine;
  15         enum intel_engine_id id;
  16 
  17         /*
  18          * Check we can call intel_engine_pm_put from any context. No
  19          * failures are reported directly, but if we mess up lockdep should
  20          * tell us.
  21          */
  22         if (intel_gt_pm_wait_for_idle(gt)) {
  23                 pr_err("Unable to flush GT pm before test\n");
  24                 return -EBUSY;
  25         }
  26 
  27         GEM_BUG_ON(intel_gt_pm_is_awake(gt));
  28         for_each_engine(engine, gt->i915, id) {
  29                 const typeof(*igt_atomic_phases) *p;
  30 
  31                 for (p = igt_atomic_phases; p->name; p++) {
  32                         /*
  33                          * Acquisition is always synchronous, except if we
  34                          * know that the engine is already awake, in which
  35                          * case we should use intel_engine_pm_get_if_awake()
  36                          * to atomically grab the wakeref.
  37                          *
  38                          * In practice,
  39                          *    intel_engine_pm_get();
  40                          *    intel_engine_pm_put();
  41                          * occurs in one thread, while simultaneously
  42                          *    intel_engine_pm_get_if_awake();
  43                          *    intel_engine_pm_put();
  44                          * occurs from atomic context in another.
  45                          */
  46                         GEM_BUG_ON(intel_engine_pm_is_awake(engine));
  47                         intel_engine_pm_get(engine);
  48 
  49                         p->critical_section_begin();
  50                         if (!intel_engine_pm_get_if_awake(engine))
  51                                 pr_err("intel_engine_pm_get_if_awake(%s) failed under %s\n",
  52                                        engine->name, p->name);
  53                         else
  54                                 intel_engine_pm_put(engine);
  55                         intel_engine_pm_put(engine);
  56                         p->critical_section_end();
  57 
  58                         /* engine wakeref is sync (instant) */
  59                         if (intel_engine_pm_is_awake(engine)) {
  60                                 pr_err("%s is still awake after flushing pm\n",
  61                                        engine->name);
  62                                 return -EINVAL;
  63                         }
  64 
  65                         /* gt wakeref is async (deferred to workqueue) */
  66                         if (intel_gt_pm_wait_for_idle(gt)) {
  67                                 pr_err("GT failed to idle\n");
  68                                 return -EINVAL;
  69                         }
  70                 }
  71         }
  72 
  73         return 0;
  74 }
  75 
  76 int live_engine_pm_selftests(struct intel_gt *gt)
  77 {
  78         static const struct i915_subtest tests[] = {
  79                 SUBTEST(live_engine_pm),
  80         };
  81 
  82         return intel_gt_live_subtests(tests, gt);
  83 }

/* [<][>][^][v][top][bottom][index][help] */