]> Git Repo - linux.git/blob - drivers/gpu/drm/i915/gt/selftest_engine_pm.c
Merge remote-tracking branch 'asoc/for-5.8' into asoc-linus
[linux.git] / drivers / gpu / drm / i915 / gt / selftest_engine_pm.c
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, 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_async(engine);
55                         intel_engine_pm_put_async(engine);
56                         p->critical_section_end();
57
58                         intel_engine_pm_flush(engine);
59
60                         if (intel_engine_pm_is_awake(engine)) {
61                                 pr_err("%s is still awake after flushing pm\n",
62                                        engine->name);
63                                 return -EINVAL;
64                         }
65
66                         /* gt wakeref is async (deferred to workqueue) */
67                         if (intel_gt_pm_wait_for_idle(gt)) {
68                                 pr_err("GT failed to idle\n");
69                                 return -EINVAL;
70                         }
71                 }
72         }
73
74         return 0;
75 }
76
77 int live_engine_pm_selftests(struct intel_gt *gt)
78 {
79         static const struct i915_subtest tests[] = {
80                 SUBTEST(live_engine_pm),
81         };
82
83         return intel_gt_live_subtests(tests, gt);
84 }
This page took 0.038506 seconds and 4 git commands to generate.