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 "selftest_engine_heartbeat.h"
10 #include "selftests/igt_atomic.h"
11 #include "selftests/igt_flush_test.h"
12 #include "selftests/igt_spinner.h"
13 
14 static int live_engine_busy_stats(void *arg)
15 {
16 	struct intel_gt *gt = arg;
17 	struct intel_engine_cs *engine;
18 	enum intel_engine_id id;
19 	struct igt_spinner spin;
20 	int err = 0;
21 
22 	/*
23 	 * Check that if an engine supports busy-stats, they tell the truth.
24 	 */
25 
26 	if (igt_spinner_init(&spin, gt))
27 		return -ENOMEM;
28 
29 	GEM_BUG_ON(intel_gt_pm_is_awake(gt));
30 	for_each_engine(engine, gt, id) {
31 		struct i915_request *rq;
32 		ktime_t de, dt;
33 		ktime_t t[2];
34 
35 		if (!intel_engine_supports_stats(engine))
36 			continue;
37 
38 		if (!intel_engine_can_store_dword(engine))
39 			continue;
40 
41 		if (intel_gt_pm_wait_for_idle(gt)) {
42 			err = -EBUSY;
43 			break;
44 		}
45 
46 		st_engine_heartbeat_disable(engine);
47 
48 		ENGINE_TRACE(engine, "measuring idle time\n");
49 		preempt_disable();
50 		de = intel_engine_get_busy_time(engine, &t[0]);
51 		udelay(100);
52 		de = ktime_sub(intel_engine_get_busy_time(engine, &t[1]), de);
53 		preempt_enable();
54 		dt = ktime_sub(t[1], t[0]);
55 		if (de < 0 || de > 10) {
56 			pr_err("%s: reported %lldns [%d%%] busyness while sleeping [for %lldns]\n",
57 			       engine->name,
58 			       de, (int)div64_u64(100 * de, dt), dt);
59 			GEM_TRACE_DUMP();
60 			err = -EINVAL;
61 			goto end;
62 		}
63 
64 		/* 100% busy */
65 		rq = igt_spinner_create_request(&spin,
66 						engine->kernel_context,
67 						MI_NOOP);
68 		if (IS_ERR(rq)) {
69 			err = PTR_ERR(rq);
70 			goto end;
71 		}
72 		i915_request_add(rq);
73 
74 		if (!igt_wait_for_spinner(&spin, rq)) {
75 			intel_gt_set_wedged(engine->gt);
76 			err = -ETIME;
77 			goto end;
78 		}
79 
80 		ENGINE_TRACE(engine, "measuring busy time\n");
81 		preempt_disable();
82 		de = intel_engine_get_busy_time(engine, &t[0]);
83 		udelay(100);
84 		de = ktime_sub(intel_engine_get_busy_time(engine, &t[1]), de);
85 		preempt_enable();
86 		dt = ktime_sub(t[1], t[0]);
87 		if (100 * de < 95 * dt || 95 * de > 100 * dt) {
88 			pr_err("%s: reported %lldns [%d%%] busyness while spinning [for %lldns]\n",
89 			       engine->name,
90 			       de, (int)div64_u64(100 * de, dt), dt);
91 			GEM_TRACE_DUMP();
92 			err = -EINVAL;
93 			goto end;
94 		}
95 
96 end:
97 		st_engine_heartbeat_enable(engine);
98 		igt_spinner_end(&spin);
99 		if (igt_flush_test(gt->i915))
100 			err = -EIO;
101 		if (err)
102 			break;
103 	}
104 
105 	igt_spinner_fini(&spin);
106 	if (igt_flush_test(gt->i915))
107 		err = -EIO;
108 	return err;
109 }
110 
111 static int live_engine_pm(void *arg)
112 {
113 	struct intel_gt *gt = arg;
114 	struct intel_engine_cs *engine;
115 	enum intel_engine_id id;
116 
117 	/*
118 	 * Check we can call intel_engine_pm_put from any context. No
119 	 * failures are reported directly, but if we mess up lockdep should
120 	 * tell us.
121 	 */
122 	if (intel_gt_pm_wait_for_idle(gt)) {
123 		pr_err("Unable to flush GT pm before test\n");
124 		return -EBUSY;
125 	}
126 
127 	GEM_BUG_ON(intel_gt_pm_is_awake(gt));
128 	for_each_engine(engine, gt, id) {
129 		const typeof(*igt_atomic_phases) *p;
130 
131 		for (p = igt_atomic_phases; p->name; p++) {
132 			/*
133 			 * Acquisition is always synchronous, except if we
134 			 * know that the engine is already awake, in which
135 			 * case we should use intel_engine_pm_get_if_awake()
136 			 * to atomically grab the wakeref.
137 			 *
138 			 * In practice,
139 			 *    intel_engine_pm_get();
140 			 *    intel_engine_pm_put();
141 			 * occurs in one thread, while simultaneously
142 			 *    intel_engine_pm_get_if_awake();
143 			 *    intel_engine_pm_put();
144 			 * occurs from atomic context in another.
145 			 */
146 			GEM_BUG_ON(intel_engine_pm_is_awake(engine));
147 			intel_engine_pm_get(engine);
148 
149 			p->critical_section_begin();
150 			if (!intel_engine_pm_get_if_awake(engine))
151 				pr_err("intel_engine_pm_get_if_awake(%s) failed under %s\n",
152 				       engine->name, p->name);
153 			else
154 				intel_engine_pm_put_async(engine);
155 			intel_engine_pm_put_async(engine);
156 			p->critical_section_end();
157 
158 			intel_engine_pm_flush(engine);
159 
160 			if (intel_engine_pm_is_awake(engine)) {
161 				pr_err("%s is still awake after flushing pm\n",
162 				       engine->name);
163 				return -EINVAL;
164 			}
165 
166 			/* gt wakeref is async (deferred to workqueue) */
167 			if (intel_gt_pm_wait_for_idle(gt)) {
168 				pr_err("GT failed to idle\n");
169 				return -EINVAL;
170 			}
171 		}
172 	}
173 
174 	return 0;
175 }
176 
177 int live_engine_pm_selftests(struct intel_gt *gt)
178 {
179 	static const struct i915_subtest tests[] = {
180 		SUBTEST(live_engine_busy_stats),
181 		SUBTEST(live_engine_pm),
182 	};
183 
184 	return intel_gt_live_subtests(tests, gt);
185 }
186