1 /*
2  * SPDX-License-Identifier: MIT
3  *
4  * Copyright © 2018 Intel Corporation
5  */
6 
7 #include <linux/sort.h>
8 
9 #include "i915_drv.h"
10 
11 #include "intel_gt_requests.h"
12 #include "i915_selftest.h"
13 
14 struct pulse {
15 	struct i915_active active;
16 	struct kref kref;
17 };
18 
19 static int pulse_active(struct i915_active *active)
20 {
21 	kref_get(&container_of(active, struct pulse, active)->kref);
22 	return 0;
23 }
24 
25 static void pulse_free(struct kref *kref)
26 {
27 	kfree(container_of(kref, struct pulse, kref));
28 }
29 
30 static void pulse_put(struct pulse *p)
31 {
32 	kref_put(&p->kref, pulse_free);
33 }
34 
35 static void pulse_retire(struct i915_active *active)
36 {
37 	pulse_put(container_of(active, struct pulse, active));
38 }
39 
40 static struct pulse *pulse_create(void)
41 {
42 	struct pulse *p;
43 
44 	p = kmalloc(sizeof(*p), GFP_KERNEL);
45 	if (!p)
46 		return p;
47 
48 	kref_init(&p->kref);
49 	i915_active_init(&p->active, pulse_active, pulse_retire);
50 
51 	return p;
52 }
53 
54 static void pulse_unlock_wait(struct pulse *p)
55 {
56 	mutex_lock(&p->active.mutex);
57 	mutex_unlock(&p->active.mutex);
58 	flush_work(&p->active.work);
59 }
60 
61 static int __live_idle_pulse(struct intel_engine_cs *engine,
62 			     int (*fn)(struct intel_engine_cs *cs))
63 {
64 	struct pulse *p;
65 	int err;
66 
67 	GEM_BUG_ON(!intel_engine_pm_is_awake(engine));
68 
69 	p = pulse_create();
70 	if (!p)
71 		return -ENOMEM;
72 
73 	err = i915_active_acquire(&p->active);
74 	if (err)
75 		goto out;
76 
77 	err = i915_active_acquire_preallocate_barrier(&p->active, engine);
78 	if (err) {
79 		i915_active_release(&p->active);
80 		goto out;
81 	}
82 
83 	i915_active_acquire_barrier(&p->active);
84 	i915_active_release(&p->active);
85 
86 	GEM_BUG_ON(i915_active_is_idle(&p->active));
87 	GEM_BUG_ON(llist_empty(&engine->barrier_tasks));
88 
89 	err = fn(engine);
90 	if (err)
91 		goto out;
92 
93 	GEM_BUG_ON(!llist_empty(&engine->barrier_tasks));
94 
95 	if (intel_gt_retire_requests_timeout(engine->gt, HZ / 5)) {
96 		err = -ETIME;
97 		goto out;
98 	}
99 
100 	GEM_BUG_ON(READ_ONCE(engine->serial) != engine->wakeref_serial);
101 
102 	pulse_unlock_wait(p); /* synchronize with the retirement callback */
103 
104 	if (!i915_active_is_idle(&p->active)) {
105 		struct drm_printer m = drm_err_printer("pulse");
106 
107 		pr_err("%s: heartbeat pulse did not flush idle tasks\n",
108 		       engine->name);
109 		i915_active_print(&p->active, &m);
110 
111 		err = -EINVAL;
112 		goto out;
113 	}
114 
115 out:
116 	pulse_put(p);
117 	return err;
118 }
119 
120 static int live_idle_flush(void *arg)
121 {
122 	struct intel_gt *gt = arg;
123 	struct intel_engine_cs *engine;
124 	enum intel_engine_id id;
125 	int err = 0;
126 
127 	/* Check that we can flush the idle barriers */
128 
129 	for_each_engine(engine, gt, id) {
130 		intel_engine_pm_get(engine);
131 		err = __live_idle_pulse(engine, intel_engine_flush_barriers);
132 		intel_engine_pm_put(engine);
133 		if (err)
134 			break;
135 	}
136 
137 	return err;
138 }
139 
140 static int live_idle_pulse(void *arg)
141 {
142 	struct intel_gt *gt = arg;
143 	struct intel_engine_cs *engine;
144 	enum intel_engine_id id;
145 	int err = 0;
146 
147 	/* Check that heartbeat pulses flush the idle barriers */
148 
149 	for_each_engine(engine, gt, id) {
150 		intel_engine_pm_get(engine);
151 		err = __live_idle_pulse(engine, intel_engine_pulse);
152 		intel_engine_pm_put(engine);
153 		if (err && err != -ENODEV)
154 			break;
155 
156 		err = 0;
157 	}
158 
159 	return err;
160 }
161 
162 static int cmp_u32(const void *_a, const void *_b)
163 {
164 	const u32 *a = _a, *b = _b;
165 
166 	return *a - *b;
167 }
168 
169 static int __live_heartbeat_fast(struct intel_engine_cs *engine)
170 {
171 	struct intel_context *ce;
172 	struct i915_request *rq;
173 	ktime_t t0, t1;
174 	u32 times[5];
175 	int err;
176 	int i;
177 
178 	ce = intel_context_create(engine->kernel_context->gem_context,
179 				  engine);
180 	if (IS_ERR(ce))
181 		return PTR_ERR(ce);
182 
183 	intel_engine_pm_get(engine);
184 
185 	err = intel_engine_set_heartbeat(engine, 1);
186 	if (err)
187 		goto err_pm;
188 
189 	for (i = 0; i < ARRAY_SIZE(times); i++) {
190 		/* Manufacture a tick */
191 		do {
192 			while (READ_ONCE(engine->heartbeat.systole))
193 				flush_delayed_work(&engine->heartbeat.work);
194 
195 			engine->serial++; /* quick, pretend we are not idle! */
196 			flush_delayed_work(&engine->heartbeat.work);
197 			if (!delayed_work_pending(&engine->heartbeat.work)) {
198 				pr_err("%s: heartbeat did not start\n",
199 				       engine->name);
200 				err = -EINVAL;
201 				goto err_pm;
202 			}
203 
204 			rcu_read_lock();
205 			rq = READ_ONCE(engine->heartbeat.systole);
206 			if (rq)
207 				rq = i915_request_get_rcu(rq);
208 			rcu_read_unlock();
209 		} while (!rq);
210 
211 		t0 = ktime_get();
212 		while (rq == READ_ONCE(engine->heartbeat.systole))
213 			yield(); /* work is on the local cpu! */
214 		t1 = ktime_get();
215 
216 		i915_request_put(rq);
217 		times[i] = ktime_us_delta(t1, t0);
218 	}
219 
220 	sort(times, ARRAY_SIZE(times), sizeof(times[0]), cmp_u32, NULL);
221 
222 	pr_info("%s: Heartbeat delay: %uus [%u, %u]\n",
223 		engine->name,
224 		times[ARRAY_SIZE(times) / 2],
225 		times[0],
226 		times[ARRAY_SIZE(times) - 1]);
227 
228 	/* Min work delay is 2 * 2 (worst), +1 for scheduling, +1 for slack */
229 	if (times[ARRAY_SIZE(times) / 2] > jiffies_to_usecs(6)) {
230 		pr_err("%s: Heartbeat delay was %uus, expected less than %dus\n",
231 		       engine->name,
232 		       times[ARRAY_SIZE(times) / 2],
233 		       jiffies_to_usecs(6));
234 		err = -EINVAL;
235 	}
236 
237 	intel_engine_set_heartbeat(engine, CONFIG_DRM_I915_HEARTBEAT_INTERVAL);
238 err_pm:
239 	intel_engine_pm_put(engine);
240 	intel_context_put(ce);
241 	return err;
242 }
243 
244 static int live_heartbeat_fast(void *arg)
245 {
246 	struct intel_gt *gt = arg;
247 	struct intel_engine_cs *engine;
248 	enum intel_engine_id id;
249 	int err = 0;
250 
251 	/* Check that the heartbeat ticks at the desired rate. */
252 	if (!CONFIG_DRM_I915_HEARTBEAT_INTERVAL)
253 		return 0;
254 
255 	for_each_engine(engine, gt, id) {
256 		err = __live_heartbeat_fast(engine);
257 		if (err)
258 			break;
259 	}
260 
261 	return err;
262 }
263 
264 static int __live_heartbeat_off(struct intel_engine_cs *engine)
265 {
266 	int err;
267 
268 	intel_engine_pm_get(engine);
269 
270 	engine->serial++;
271 	flush_delayed_work(&engine->heartbeat.work);
272 	if (!delayed_work_pending(&engine->heartbeat.work)) {
273 		pr_err("%s: heartbeat not running\n",
274 		       engine->name);
275 		err = -EINVAL;
276 		goto err_pm;
277 	}
278 
279 	err = intel_engine_set_heartbeat(engine, 0);
280 	if (err)
281 		goto err_pm;
282 
283 	engine->serial++;
284 	flush_delayed_work(&engine->heartbeat.work);
285 	if (delayed_work_pending(&engine->heartbeat.work)) {
286 		pr_err("%s: heartbeat still running\n",
287 		       engine->name);
288 		err = -EINVAL;
289 		goto err_beat;
290 	}
291 
292 	if (READ_ONCE(engine->heartbeat.systole)) {
293 		pr_err("%s: heartbeat still allocated\n",
294 		       engine->name);
295 		err = -EINVAL;
296 		goto err_beat;
297 	}
298 
299 err_beat:
300 	intel_engine_set_heartbeat(engine, CONFIG_DRM_I915_HEARTBEAT_INTERVAL);
301 err_pm:
302 	intel_engine_pm_put(engine);
303 	return err;
304 }
305 
306 static int live_heartbeat_off(void *arg)
307 {
308 	struct intel_gt *gt = arg;
309 	struct intel_engine_cs *engine;
310 	enum intel_engine_id id;
311 	int err = 0;
312 
313 	/* Check that we can turn off heartbeat and not interrupt VIP */
314 	if (!CONFIG_DRM_I915_HEARTBEAT_INTERVAL)
315 		return 0;
316 
317 	for_each_engine(engine, gt, id) {
318 		if (!intel_engine_has_preemption(engine))
319 			continue;
320 
321 		err = __live_heartbeat_off(engine);
322 		if (err)
323 			break;
324 	}
325 
326 	return err;
327 }
328 
329 int intel_heartbeat_live_selftests(struct drm_i915_private *i915)
330 {
331 	static const struct i915_subtest tests[] = {
332 		SUBTEST(live_idle_flush),
333 		SUBTEST(live_idle_pulse),
334 		SUBTEST(live_heartbeat_fast),
335 		SUBTEST(live_heartbeat_off),
336 	};
337 	int saved_hangcheck;
338 	int err;
339 
340 	if (intel_gt_is_wedged(&i915->gt))
341 		return 0;
342 
343 	saved_hangcheck = i915_modparams.enable_hangcheck;
344 	i915_modparams.enable_hangcheck = INT_MAX;
345 
346 	err = intel_gt_live_subtests(tests, &i915->gt);
347 
348 	i915_modparams.enable_hangcheck = saved_hangcheck;
349 	return err;
350 }
351