2 * SPDX-License-Identifier: MIT
4 * Copyright © 2018 Intel Corporation
7 #include <linux/sort.h>
11 #include "intel_gt_requests.h"
12 #include "i915_selftest.h"
13 #include "selftest_engine_heartbeat.h"
15 static int timeline_sync(struct intel_timeline *tl)
17 struct dma_fence *fence;
20 fence = i915_active_fence_get(&tl->last_request);
24 timeout = dma_fence_wait_timeout(fence, true, HZ / 2);
32 static int engine_sync_barrier(struct intel_engine_cs *engine)
34 return timeline_sync(engine->kernel_context->timeline);
38 struct i915_active active;
42 static int pulse_active(struct i915_active *active)
44 kref_get(&container_of(active, struct pulse, active)->kref);
48 static void pulse_free(struct kref *kref)
50 kfree(container_of(kref, struct pulse, kref));
53 static void pulse_put(struct pulse *p)
55 kref_put(&p->kref, pulse_free);
58 static void pulse_retire(struct i915_active *active)
60 pulse_put(container_of(active, struct pulse, active));
63 static struct pulse *pulse_create(void)
67 p = kmalloc(sizeof(*p), GFP_KERNEL);
72 i915_active_init(&p->active, pulse_active, pulse_retire);
77 static void pulse_unlock_wait(struct pulse *p)
79 i915_active_unlock_wait(&p->active);
82 static int __live_idle_pulse(struct intel_engine_cs *engine,
83 int (*fn)(struct intel_engine_cs *cs))
88 GEM_BUG_ON(!intel_engine_pm_is_awake(engine));
94 err = i915_active_acquire(&p->active);
98 err = i915_active_acquire_preallocate_barrier(&p->active, engine);
100 i915_active_release(&p->active);
104 i915_active_acquire_barrier(&p->active);
105 i915_active_release(&p->active);
107 GEM_BUG_ON(i915_active_is_idle(&p->active));
108 GEM_BUG_ON(llist_empty(&engine->barrier_tasks));
114 GEM_BUG_ON(!llist_empty(&engine->barrier_tasks));
116 if (engine_sync_barrier(engine)) {
117 struct drm_printer m = drm_err_printer("pulse");
119 pr_err("%s: no heartbeat pulse?\n", engine->name);
120 intel_engine_dump(engine, &m, "%s", engine->name);
126 GEM_BUG_ON(READ_ONCE(engine->serial) != engine->wakeref_serial);
128 pulse_unlock_wait(p); /* synchronize with the retirement callback */
130 if (!i915_active_is_idle(&p->active)) {
131 struct drm_printer m = drm_err_printer("pulse");
133 pr_err("%s: heartbeat pulse did not flush idle tasks\n",
135 i915_active_print(&p->active, &m);
146 static int live_idle_flush(void *arg)
148 struct intel_gt *gt = arg;
149 struct intel_engine_cs *engine;
150 enum intel_engine_id id;
153 /* Check that we can flush the idle barriers */
155 for_each_engine(engine, gt, id) {
156 st_engine_heartbeat_disable(engine);
157 err = __live_idle_pulse(engine, intel_engine_flush_barriers);
158 st_engine_heartbeat_enable(engine);
166 static int live_idle_pulse(void *arg)
168 struct intel_gt *gt = arg;
169 struct intel_engine_cs *engine;
170 enum intel_engine_id id;
173 /* Check that heartbeat pulses flush the idle barriers */
175 for_each_engine(engine, gt, id) {
176 st_engine_heartbeat_disable(engine);
177 err = __live_idle_pulse(engine, intel_engine_pulse);
178 st_engine_heartbeat_enable(engine);
179 if (err && err != -ENODEV)
188 static int cmp_u32(const void *_a, const void *_b)
190 const u32 *a = _a, *b = _b;
195 static int __live_heartbeat_fast(struct intel_engine_cs *engine)
197 struct intel_context *ce;
198 struct i915_request *rq;
204 ce = intel_context_create(engine);
208 intel_engine_pm_get(engine);
210 err = intel_engine_set_heartbeat(engine, 1);
214 for (i = 0; i < ARRAY_SIZE(times); i++) {
215 /* Manufacture a tick */
217 while (READ_ONCE(engine->heartbeat.systole))
218 flush_delayed_work(&engine->heartbeat.work);
220 engine->serial++; /* quick, pretend we are not idle! */
221 flush_delayed_work(&engine->heartbeat.work);
222 if (!delayed_work_pending(&engine->heartbeat.work)) {
223 pr_err("%s: heartbeat did not start\n",
230 rq = READ_ONCE(engine->heartbeat.systole);
232 rq = i915_request_get_rcu(rq);
237 while (rq == READ_ONCE(engine->heartbeat.systole))
238 yield(); /* work is on the local cpu! */
241 i915_request_put(rq);
242 times[i] = ktime_us_delta(t1, t0);
245 sort(times, ARRAY_SIZE(times), sizeof(times[0]), cmp_u32, NULL);
247 pr_info("%s: Heartbeat delay: %uus [%u, %u]\n",
249 times[ARRAY_SIZE(times) / 2],
251 times[ARRAY_SIZE(times) - 1]);
253 /* Min work delay is 2 * 2 (worst), +1 for scheduling, +1 for slack */
254 if (times[ARRAY_SIZE(times) / 2] > jiffies_to_usecs(6)) {
255 pr_err("%s: Heartbeat delay was %uus, expected less than %dus\n",
257 times[ARRAY_SIZE(times) / 2],
258 jiffies_to_usecs(6));
262 intel_engine_set_heartbeat(engine, CONFIG_DRM_I915_HEARTBEAT_INTERVAL);
264 intel_engine_pm_put(engine);
265 intel_context_put(ce);
269 static int live_heartbeat_fast(void *arg)
271 struct intel_gt *gt = arg;
272 struct intel_engine_cs *engine;
273 enum intel_engine_id id;
276 /* Check that the heartbeat ticks at the desired rate. */
277 if (!CONFIG_DRM_I915_HEARTBEAT_INTERVAL)
280 for_each_engine(engine, gt, id) {
281 err = __live_heartbeat_fast(engine);
289 static int __live_heartbeat_off(struct intel_engine_cs *engine)
293 intel_engine_pm_get(engine);
296 flush_delayed_work(&engine->heartbeat.work);
297 if (!delayed_work_pending(&engine->heartbeat.work)) {
298 pr_err("%s: heartbeat not running\n",
304 err = intel_engine_set_heartbeat(engine, 0);
309 flush_delayed_work(&engine->heartbeat.work);
310 if (delayed_work_pending(&engine->heartbeat.work)) {
311 pr_err("%s: heartbeat still running\n",
317 if (READ_ONCE(engine->heartbeat.systole)) {
318 pr_err("%s: heartbeat still allocated\n",
325 intel_engine_set_heartbeat(engine, CONFIG_DRM_I915_HEARTBEAT_INTERVAL);
327 intel_engine_pm_put(engine);
331 static int live_heartbeat_off(void *arg)
333 struct intel_gt *gt = arg;
334 struct intel_engine_cs *engine;
335 enum intel_engine_id id;
338 /* Check that we can turn off heartbeat and not interrupt VIP */
339 if (!CONFIG_DRM_I915_HEARTBEAT_INTERVAL)
342 for_each_engine(engine, gt, id) {
343 if (!intel_engine_has_preemption(engine))
346 err = __live_heartbeat_off(engine);
354 int intel_heartbeat_live_selftests(struct drm_i915_private *i915)
356 static const struct i915_subtest tests[] = {
357 SUBTEST(live_idle_flush),
358 SUBTEST(live_idle_pulse),
359 SUBTEST(live_heartbeat_fast),
360 SUBTEST(live_heartbeat_off),
365 if (intel_gt_is_wedged(&i915->gt))
368 saved_hangcheck = i915->params.enable_hangcheck;
369 i915->params.enable_hangcheck = INT_MAX;
371 err = intel_gt_live_subtests(tests, &i915->gt);
373 i915->params.enable_hangcheck = saved_hangcheck;
377 void st_engine_heartbeat_disable(struct intel_engine_cs *engine)
379 engine->props.heartbeat_interval_ms = 0;
381 intel_engine_pm_get(engine);
382 intel_engine_park_heartbeat(engine);
385 void st_engine_heartbeat_enable(struct intel_engine_cs *engine)
387 intel_engine_pm_put(engine);
389 engine->props.heartbeat_interval_ms =
390 engine->defaults.heartbeat_interval_ms;