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, ×lice_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