1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2019 Intel Corporation
4  */
5 
6 #include <linux/kobject.h>
7 #include <linux/sysfs.h>
8 
9 #include "i915_drv.h"
10 #include "intel_engine.h"
11 #include "intel_engine_heartbeat.h"
12 #include "sysfs_engines.h"
13 
14 struct kobj_engine {
15 	struct kobject base;
16 	struct intel_engine_cs *engine;
17 };
18 
19 static struct intel_engine_cs *kobj_to_engine(struct kobject *kobj)
20 {
21 	return container_of(kobj, struct kobj_engine, base)->engine;
22 }
23 
24 static ssize_t
25 name_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
26 {
27 	return sprintf(buf, "%s\n", kobj_to_engine(kobj)->name);
28 }
29 
30 static struct kobj_attribute name_attr =
31 __ATTR(name, 0444, name_show, NULL);
32 
33 static ssize_t
34 class_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
35 {
36 	return sprintf(buf, "%d\n", kobj_to_engine(kobj)->uabi_class);
37 }
38 
39 static struct kobj_attribute class_attr =
40 __ATTR(class, 0444, class_show, NULL);
41 
42 static ssize_t
43 inst_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
44 {
45 	return sprintf(buf, "%d\n", kobj_to_engine(kobj)->uabi_instance);
46 }
47 
48 static struct kobj_attribute inst_attr =
49 __ATTR(instance, 0444, inst_show, NULL);
50 
51 static ssize_t
52 mmio_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
53 {
54 	return sprintf(buf, "0x%x\n", kobj_to_engine(kobj)->mmio_base);
55 }
56 
57 static struct kobj_attribute mmio_attr =
58 __ATTR(mmio_base, 0444, mmio_show, NULL);
59 
60 static const char * const vcs_caps[] = {
61 	[ilog2(I915_VIDEO_CLASS_CAPABILITY_HEVC)] = "hevc",
62 	[ilog2(I915_VIDEO_AND_ENHANCE_CLASS_CAPABILITY_SFC)] = "sfc",
63 };
64 
65 static const char * const vecs_caps[] = {
66 	[ilog2(I915_VIDEO_AND_ENHANCE_CLASS_CAPABILITY_SFC)] = "sfc",
67 };
68 
69 static ssize_t repr_trim(char *buf, ssize_t len)
70 {
71 	/* Trim off the trailing space and replace with a newline */
72 	if (len > PAGE_SIZE)
73 		len = PAGE_SIZE;
74 	if (len > 0)
75 		buf[len - 1] = '\n';
76 
77 	return len;
78 }
79 
80 static ssize_t
81 __caps_show(struct intel_engine_cs *engine,
82 	    u32 caps, char *buf, bool show_unknown)
83 {
84 	const char * const *repr;
85 	int count, n;
86 	ssize_t len;
87 
88 	BUILD_BUG_ON(!typecheck(typeof(caps), engine->uabi_capabilities));
89 
90 	switch (engine->class) {
91 	case VIDEO_DECODE_CLASS:
92 		repr = vcs_caps;
93 		count = ARRAY_SIZE(vcs_caps);
94 		break;
95 
96 	case VIDEO_ENHANCEMENT_CLASS:
97 		repr = vecs_caps;
98 		count = ARRAY_SIZE(vecs_caps);
99 		break;
100 
101 	default:
102 		repr = NULL;
103 		count = 0;
104 		break;
105 	}
106 	GEM_BUG_ON(count > BITS_PER_TYPE(typeof(caps)));
107 
108 	len = 0;
109 	for_each_set_bit(n,
110 			 (unsigned long *)&caps,
111 			 show_unknown ? BITS_PER_TYPE(typeof(caps)) : count) {
112 		if (n >= count || !repr[n]) {
113 			if (GEM_WARN_ON(show_unknown))
114 				len += snprintf(buf + len, PAGE_SIZE - len,
115 						"[%x] ", n);
116 		} else {
117 			len += snprintf(buf + len, PAGE_SIZE - len,
118 					"%s ", repr[n]);
119 		}
120 		if (GEM_WARN_ON(len >= PAGE_SIZE))
121 			break;
122 	}
123 	return repr_trim(buf, len);
124 }
125 
126 static ssize_t
127 caps_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
128 {
129 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
130 
131 	return __caps_show(engine, engine->uabi_capabilities, buf, true);
132 }
133 
134 static struct kobj_attribute caps_attr =
135 __ATTR(capabilities, 0444, caps_show, NULL);
136 
137 static ssize_t
138 all_caps_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
139 {
140 	return __caps_show(kobj_to_engine(kobj), -1, buf, false);
141 }
142 
143 static struct kobj_attribute all_caps_attr =
144 __ATTR(known_capabilities, 0444, all_caps_show, NULL);
145 
146 static ssize_t
147 max_spin_store(struct kobject *kobj, struct kobj_attribute *attr,
148 	       const char *buf, size_t count)
149 {
150 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
151 	unsigned long long duration;
152 	int err;
153 
154 	/*
155 	 * When waiting for a request, if is it currently being executed
156 	 * on the GPU, we busywait for a short while before sleeping. The
157 	 * premise is that most requests are short, and if it is already
158 	 * executing then there is a good chance that it will complete
159 	 * before we can setup the interrupt handler and go to sleep.
160 	 * We try to offset the cost of going to sleep, by first spinning
161 	 * on the request -- if it completed in less time than it would take
162 	 * to go sleep, process the interrupt and return back to the client,
163 	 * then we have saved the client some latency, albeit at the cost
164 	 * of spinning on an expensive CPU core.
165 	 *
166 	 * While we try to avoid waiting at all for a request that is unlikely
167 	 * to complete, deciding how long it is worth spinning is for is an
168 	 * arbitrary decision: trading off power vs latency.
169 	 */
170 
171 	err = kstrtoull(buf, 0, &duration);
172 	if (err)
173 		return err;
174 
175 	if (duration > jiffies_to_nsecs(2))
176 		return -EINVAL;
177 
178 	WRITE_ONCE(engine->props.max_busywait_duration_ns, duration);
179 
180 	return count;
181 }
182 
183 static ssize_t
184 max_spin_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
185 {
186 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
187 
188 	return sprintf(buf, "%lu\n", engine->props.max_busywait_duration_ns);
189 }
190 
191 static struct kobj_attribute max_spin_attr =
192 __ATTR(max_busywait_duration_ns, 0644, max_spin_show, max_spin_store);
193 
194 static ssize_t
195 timeslice_store(struct kobject *kobj, struct kobj_attribute *attr,
196 		const char *buf, size_t count)
197 {
198 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
199 	unsigned long long duration;
200 	int err;
201 
202 	/*
203 	 * Execlists uses a scheduling quantum (a timeslice) to alternate
204 	 * execution between ready-to-run contexts of equal priority. This
205 	 * ensures that all users (though only if they of equal importance)
206 	 * have the opportunity to run and prevents livelocks where contexts
207 	 * may have implicit ordering due to userspace semaphores.
208 	 */
209 
210 	err = kstrtoull(buf, 0, &duration);
211 	if (err)
212 		return err;
213 
214 	if (duration > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT))
215 		return -EINVAL;
216 
217 	WRITE_ONCE(engine->props.timeslice_duration_ms, duration);
218 
219 	if (execlists_active(&engine->execlists))
220 		set_timer_ms(&engine->execlists.timer, duration);
221 
222 	return count;
223 }
224 
225 static ssize_t
226 timeslice_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
227 {
228 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
229 
230 	return sprintf(buf, "%lu\n", engine->props.timeslice_duration_ms);
231 }
232 
233 static struct kobj_attribute timeslice_duration_attr =
234 __ATTR(timeslice_duration_ms, 0644, timeslice_show, timeslice_store);
235 
236 static ssize_t
237 stop_store(struct kobject *kobj, struct kobj_attribute *attr,
238 	   const char *buf, size_t count)
239 {
240 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
241 	unsigned long long duration;
242 	int err;
243 
244 	/*
245 	 * When we allow ourselves to sleep before a GPU reset after disabling
246 	 * submission, even for a few milliseconds, gives an innocent context
247 	 * the opportunity to clear the GPU before the reset occurs. However,
248 	 * how long to sleep depends on the typical non-preemptible duration
249 	 * (a similar problem to determining the ideal preempt-reset timeout
250 	 * or even the heartbeat interval).
251 	 */
252 
253 	err = kstrtoull(buf, 0, &duration);
254 	if (err)
255 		return err;
256 
257 	if (duration > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT))
258 		return -EINVAL;
259 
260 	WRITE_ONCE(engine->props.stop_timeout_ms, duration);
261 	return count;
262 }
263 
264 static ssize_t
265 stop_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
266 {
267 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
268 
269 	return sprintf(buf, "%lu\n", engine->props.stop_timeout_ms);
270 }
271 
272 static struct kobj_attribute stop_timeout_attr =
273 __ATTR(stop_timeout_ms, 0644, stop_show, stop_store);
274 
275 static ssize_t
276 preempt_timeout_store(struct kobject *kobj, struct kobj_attribute *attr,
277 		      const char *buf, size_t count)
278 {
279 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
280 	unsigned long long timeout;
281 	int err;
282 
283 	/*
284 	 * After initialising a preemption request, we give the current
285 	 * resident a small amount of time to vacate the GPU. The preemption
286 	 * request is for a higher priority context and should be immediate to
287 	 * maintain high quality of service (and avoid priority inversion).
288 	 * However, the preemption granularity of the GPU can be quite coarse
289 	 * and so we need a compromise.
290 	 */
291 
292 	err = kstrtoull(buf, 0, &timeout);
293 	if (err)
294 		return err;
295 
296 	if (timeout > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT))
297 		return -EINVAL;
298 
299 	WRITE_ONCE(engine->props.preempt_timeout_ms, timeout);
300 
301 	if (READ_ONCE(engine->execlists.pending[0]))
302 		set_timer_ms(&engine->execlists.preempt, timeout);
303 
304 	return count;
305 }
306 
307 static ssize_t
308 preempt_timeout_show(struct kobject *kobj, struct kobj_attribute *attr,
309 		     char *buf)
310 {
311 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
312 
313 	return sprintf(buf, "%lu\n", engine->props.preempt_timeout_ms);
314 }
315 
316 static struct kobj_attribute preempt_timeout_attr =
317 __ATTR(preempt_timeout_ms, 0644, preempt_timeout_show, preempt_timeout_store);
318 
319 static ssize_t
320 heartbeat_store(struct kobject *kobj, struct kobj_attribute *attr,
321 		const char *buf, size_t count)
322 {
323 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
324 	unsigned long long delay;
325 	int err;
326 
327 	/*
328 	 * We monitor the health of the system via periodic heartbeat pulses.
329 	 * The pulses also provide the opportunity to perform garbage
330 	 * collection.  However, we interpret an incomplete pulse (a missed
331 	 * heartbeat) as an indication that the system is no longer responsive,
332 	 * i.e. hung, and perform an engine or full GPU reset. Given that the
333 	 * preemption granularity can be very coarse on a system, the optimal
334 	 * value for any workload is unknowable!
335 	 */
336 
337 	err = kstrtoull(buf, 0, &delay);
338 	if (err)
339 		return err;
340 
341 	if (delay >= jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT))
342 		return -EINVAL;
343 
344 	err = intel_engine_set_heartbeat(engine, delay);
345 	if (err)
346 		return err;
347 
348 	return count;
349 }
350 
351 static ssize_t
352 heartbeat_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
353 {
354 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
355 
356 	return sprintf(buf, "%lu\n", engine->props.heartbeat_interval_ms);
357 }
358 
359 static struct kobj_attribute heartbeat_interval_attr =
360 __ATTR(heartbeat_interval_ms, 0644, heartbeat_show, heartbeat_store);
361 
362 static void kobj_engine_release(struct kobject *kobj)
363 {
364 	kfree(kobj);
365 }
366 
367 static struct kobj_type kobj_engine_type = {
368 	.release = kobj_engine_release,
369 	.sysfs_ops = &kobj_sysfs_ops
370 };
371 
372 static struct kobject *
373 kobj_engine(struct kobject *dir, struct intel_engine_cs *engine)
374 {
375 	struct kobj_engine *ke;
376 
377 	ke = kzalloc(sizeof(*ke), GFP_KERNEL);
378 	if (!ke)
379 		return NULL;
380 
381 	kobject_init(&ke->base, &kobj_engine_type);
382 	ke->engine = engine;
383 
384 	if (kobject_add(&ke->base, dir, "%s", engine->name)) {
385 		kobject_put(&ke->base);
386 		return NULL;
387 	}
388 
389 	/* xfer ownership to sysfs tree */
390 	return &ke->base;
391 }
392 
393 void intel_engines_add_sysfs(struct drm_i915_private *i915)
394 {
395 	static const struct attribute *files[] = {
396 		&name_attr.attr,
397 		&class_attr.attr,
398 		&inst_attr.attr,
399 		&mmio_attr.attr,
400 		&caps_attr.attr,
401 		&all_caps_attr.attr,
402 		&max_spin_attr.attr,
403 		&stop_timeout_attr.attr,
404 #if CONFIG_DRM_I915_HEARTBEAT_INTERVAL
405 		&heartbeat_interval_attr.attr,
406 #endif
407 		NULL
408 	};
409 
410 	struct device *kdev = i915->drm.primary->kdev;
411 	struct intel_engine_cs *engine;
412 	struct kobject *dir;
413 
414 	dir = kobject_create_and_add("engine", &kdev->kobj);
415 	if (!dir)
416 		return;
417 
418 	for_each_uabi_engine(engine, i915) {
419 		struct kobject *kobj;
420 
421 		kobj = kobj_engine(dir, engine);
422 		if (!kobj)
423 			goto err_engine;
424 
425 		if (sysfs_create_files(kobj, files))
426 			goto err_object;
427 
428 		if (intel_engine_has_timeslices(engine) &&
429 		    sysfs_create_file(kobj, &timeslice_duration_attr.attr))
430 			goto err_engine;
431 
432 		if (intel_engine_has_preempt_reset(engine) &&
433 		    sysfs_create_file(kobj, &preempt_timeout_attr.attr))
434 			goto err_engine;
435 
436 		if (0) {
437 err_object:
438 			kobject_put(kobj);
439 err_engine:
440 			dev_err(kdev, "Failed to add sysfs engine '%s'\n",
441 				engine->name);
442 			break;
443 		}
444 	}
445 }
446