Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
 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
11static 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
76int 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}