1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include "xe_debugfs.h" 7 8 #include <linux/debugfs.h> 9 #include <linux/fault-inject.h> 10 #include <linux/string_helpers.h> 11 12 #include <drm/drm_debugfs.h> 13 14 #include "regs/xe_pmt.h" 15 #include "xe_bo.h" 16 #include "xe_device.h" 17 #include "xe_force_wake.h" 18 #include "xe_gt.h" 19 #include "xe_gt_debugfs.h" 20 #include "xe_gt_printk.h" 21 #include "xe_guc_ads.h" 22 #include "xe_hw_engine.h" 23 #include "xe_mmio.h" 24 #include "xe_pm.h" 25 #include "xe_psmi.h" 26 #include "xe_pxp_debugfs.h" 27 #include "xe_sriov.h" 28 #include "xe_sriov_pf_debugfs.h" 29 #include "xe_sriov_vf.h" 30 #include "xe_step.h" 31 #include "xe_tile_debugfs.h" 32 #include "xe_vsec.h" 33 #include "xe_wa.h" 34 35 #ifdef CONFIG_DRM_XE_DEBUG 36 #include "xe_bo_evict.h" 37 #include "xe_migrate.h" 38 #include "xe_vm.h" 39 #endif 40 41 DECLARE_FAULT_ATTR(gt_reset_failure); 42 DECLARE_FAULT_ATTR(inject_csc_hw_error); 43 44 static void read_residency_counter(struct xe_device *xe, struct xe_mmio *mmio, 45 u32 offset, const char *name, struct drm_printer *p) 46 { 47 u64 residency = 0; 48 int ret; 49 50 ret = xe_pmt_telem_read(xe->drm.dev, 51 xe_mmio_read32(mmio, PUNIT_TELEMETRY_GUID), 52 &residency, offset, sizeof(residency)); 53 if (ret != sizeof(residency)) { 54 drm_warn(&xe->drm, "%s counter failed to read, ret %d\n", name, ret); 55 return; 56 } 57 58 drm_printf(p, "%s : %llu\n", name, residency); 59 } 60 61 static struct xe_device *node_to_xe(struct drm_info_node *node) 62 { 63 return to_xe_device(node->minor->dev); 64 } 65 66 static void print_engine_class_mask(struct drm_printer *p, u16 mask) 67 { 68 if (!mask) { 69 drm_printf(p, " none\n"); 70 return; 71 } 72 73 for (enum xe_engine_class ec = 0; ec < XE_ENGINE_CLASS_MAX; ec++) { 74 if (mask & BIT(ec)) 75 drm_printf(p, " %s", xe_hw_engine_class_to_str(ec)); 76 } 77 drm_printf(p, "\n"); 78 } 79 80 static void print_engine_mask(struct drm_printer *p, struct xe_gt *gt, u64 mask) 81 { 82 struct xe_hw_engine *hwe; 83 enum xe_hw_engine_id id; 84 85 if (!mask) { 86 drm_printf(p, " none\n"); 87 return; 88 } 89 90 for_each_hw_engine(hwe, gt, id) { 91 if (mask & BIT_ULL(id)) 92 drm_printf(p, " %s", hwe->name); 93 } 94 drm_printf(p, "\n"); 95 } 96 97 static int info(struct seq_file *m, void *data) 98 { 99 struct xe_device *xe = node_to_xe(m->private); 100 struct drm_printer p = drm_seq_file_printer(m); 101 struct xe_gt *gt; 102 u8 id; 103 104 guard(xe_pm_runtime)(xe); 105 106 drm_printf(&p, "graphics_verx100 %d\n", xe->info.graphics_verx100); 107 drm_printf(&p, "media_verx100 %d\n", xe->info.media_verx100); 108 drm_printf(&p, "stepping G:%s M:%s B:%s\n", 109 xe_step_name(xe->info.step.graphics), 110 xe_step_name(xe->info.step.media), 111 xe_step_name(xe->info.step.basedie)); 112 drm_printf(&p, "is_dgfx %s\n", str_yes_no(xe->info.is_dgfx)); 113 drm_printf(&p, "platform %d\n", xe->info.platform); 114 drm_printf(&p, "subplatform %d\n", 115 xe->info.subplatform > XE_SUBPLATFORM_NONE ? xe->info.subplatform : 0); 116 drm_printf(&p, "devid 0x%x\n", xe->info.devid); 117 drm_printf(&p, "revid %d\n", xe->info.revid); 118 drm_printf(&p, "tile_count %d\n", xe->info.tile_count); 119 drm_printf(&p, "vm_max_level %d\n", xe->info.vm_max_level); 120 drm_printf(&p, "force_execlist %s\n", str_yes_no(xe->info.force_execlist)); 121 drm_printf(&p, "has_flat_ccs %s\n", str_yes_no(xe->info.has_flat_ccs)); 122 drm_printf(&p, "has_usm %s\n", str_yes_no(xe->info.has_usm)); 123 drm_printf(&p, "skip_guc_pc %s\n", str_yes_no(xe->info.skip_guc_pc)); 124 drm_printf(&p, "multi_lrc_engine_classes"); 125 print_engine_class_mask(&p, xe->info.multi_lrc_mask); 126 for_each_gt(gt, xe, id) { 127 drm_printf(&p, "gt%d force wake %d\n", id, 128 xe_force_wake_ref(gt_to_fw(gt), XE_FW_GT)); 129 drm_printf(&p, "gt%d engines", id); 130 print_engine_mask(&p, gt, gt->info.engine_mask); 131 drm_printf(&p, "gt%d multi_queue_engine_classes", id); 132 print_engine_class_mask(&p, gt->info.multi_queue_engine_class_mask); 133 } 134 135 return 0; 136 } 137 138 static int sriov_info(struct seq_file *m, void *data) 139 { 140 struct xe_device *xe = node_to_xe(m->private); 141 struct drm_printer p = drm_seq_file_printer(m); 142 143 xe_sriov_print_info(xe, &p); 144 return 0; 145 } 146 147 static int workarounds(struct xe_device *xe, struct drm_printer *p) 148 { 149 guard(xe_pm_runtime)(xe); 150 xe_wa_device_dump(xe, p); 151 152 return 0; 153 } 154 155 static int workaround_info(struct seq_file *m, void *data) 156 { 157 struct xe_device *xe = node_to_xe(m->private); 158 struct drm_printer p = drm_seq_file_printer(m); 159 160 workarounds(xe, &p); 161 return 0; 162 } 163 164 static int dgfx_pkg_residencies_show(struct seq_file *m, void *data) 165 { 166 struct xe_device *xe; 167 struct xe_mmio *mmio; 168 struct drm_printer p; 169 170 xe = node_to_xe(m->private); 171 p = drm_seq_file_printer(m); 172 guard(xe_pm_runtime)(xe); 173 mmio = xe_root_tile_mmio(xe); 174 static const struct { 175 u32 offset; 176 const char *name; 177 } residencies[] = { 178 {BMG_G2_RESIDENCY_OFFSET, "Package G2"}, 179 {BMG_G6_RESIDENCY_OFFSET, "Package G6"}, 180 {BMG_G7_RESIDENCY_OFFSET, "Package G7"}, 181 {BMG_G8_RESIDENCY_OFFSET, "Package G8"}, 182 {BMG_G10_RESIDENCY_OFFSET, "Package G10"}, 183 {BMG_MODS_RESIDENCY_OFFSET, "Package ModS"} 184 }; 185 186 for (int i = 0; i < ARRAY_SIZE(residencies); i++) 187 read_residency_counter(xe, mmio, residencies[i].offset, residencies[i].name, &p); 188 189 return 0; 190 } 191 192 static int dgfx_pcie_link_residencies_show(struct seq_file *m, void *data) 193 { 194 struct xe_device *xe; 195 struct xe_mmio *mmio; 196 struct drm_printer p; 197 198 xe = node_to_xe(m->private); 199 p = drm_seq_file_printer(m); 200 guard(xe_pm_runtime)(xe); 201 mmio = xe_root_tile_mmio(xe); 202 203 static const struct { 204 u32 offset; 205 const char *name; 206 } residencies[] = { 207 {BMG_PCIE_LINK_L0_RESIDENCY_OFFSET, "PCIE LINK L0 RESIDENCY"}, 208 {BMG_PCIE_LINK_L1_RESIDENCY_OFFSET, "PCIE LINK L1 RESIDENCY"}, 209 {BMG_PCIE_LINK_L1_2_RESIDENCY_OFFSET, "PCIE LINK L1.2 RESIDENCY"} 210 }; 211 212 for (int i = 0; i < ARRAY_SIZE(residencies); i++) 213 read_residency_counter(xe, mmio, residencies[i].offset, residencies[i].name, &p); 214 215 return 0; 216 } 217 218 static const struct drm_info_list debugfs_list[] = { 219 {"info", info, 0}, 220 { .name = "sriov_info", .show = sriov_info, }, 221 { .name = "workarounds", .show = workaround_info, }, 222 }; 223 224 static const struct drm_info_list debugfs_residencies[] = { 225 { .name = "dgfx_pkg_residencies", .show = dgfx_pkg_residencies_show, }, 226 { .name = "dgfx_pcie_link_residencies", .show = dgfx_pcie_link_residencies_show, }, 227 }; 228 229 static int forcewake_open(struct inode *inode, struct file *file) 230 { 231 struct xe_device *xe = inode->i_private; 232 struct xe_gt *gt; 233 u8 id, last_gt; 234 unsigned int fw_ref; 235 236 xe_pm_runtime_get(xe); 237 for_each_gt(gt, xe, id) { 238 last_gt = id; 239 240 fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL); 241 if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL)) 242 goto err_fw_get; 243 } 244 245 return 0; 246 247 err_fw_get: 248 for_each_gt(gt, xe, id) { 249 if (id < last_gt) 250 xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL); 251 else if (id == last_gt) 252 xe_force_wake_put(gt_to_fw(gt), fw_ref); 253 else 254 break; 255 } 256 257 xe_pm_runtime_put(xe); 258 return -ETIMEDOUT; 259 } 260 261 static int forcewake_release(struct inode *inode, struct file *file) 262 { 263 struct xe_device *xe = inode->i_private; 264 struct xe_gt *gt; 265 u8 id; 266 267 for_each_gt(gt, xe, id) 268 xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL); 269 xe_pm_runtime_put(xe); 270 271 return 0; 272 } 273 274 static const struct file_operations forcewake_all_fops = { 275 .owner = THIS_MODULE, 276 .open = forcewake_open, 277 .release = forcewake_release, 278 }; 279 280 static ssize_t wedged_mode_show(struct file *f, char __user *ubuf, 281 size_t size, loff_t *pos) 282 { 283 struct xe_device *xe = file_inode(f)->i_private; 284 char buf[32]; 285 int len = 0; 286 287 len = scnprintf(buf, sizeof(buf), "%d\n", xe->wedged.mode); 288 289 return simple_read_from_buffer(ubuf, size, pos, buf, len); 290 } 291 292 static int __wedged_mode_set_reset_policy(struct xe_gt *gt, enum xe_wedged_mode mode) 293 { 294 bool enable_engine_reset; 295 int ret; 296 297 enable_engine_reset = (mode != XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET); 298 ret = xe_guc_ads_scheduler_policy_toggle_reset(>->uc.guc.ads, 299 enable_engine_reset); 300 if (ret) 301 xe_gt_err(gt, "Failed to update GuC ADS scheduler policy (%pe)\n", ERR_PTR(ret)); 302 303 return ret; 304 } 305 306 static int wedged_mode_set_reset_policy(struct xe_device *xe, enum xe_wedged_mode mode) 307 { 308 struct xe_gt *gt; 309 int ret; 310 u8 id; 311 312 guard(xe_pm_runtime)(xe); 313 for_each_gt(gt, xe, id) { 314 ret = __wedged_mode_set_reset_policy(gt, mode); 315 if (ret) { 316 if (id > 0) { 317 xe->wedged.inconsistent_reset = true; 318 drm_err(&xe->drm, "Inconsistent reset policy state between GTs\n"); 319 } 320 return ret; 321 } 322 } 323 324 xe->wedged.inconsistent_reset = false; 325 326 return 0; 327 } 328 329 static bool wedged_mode_needs_policy_update(struct xe_device *xe, enum xe_wedged_mode mode) 330 { 331 if (xe->wedged.inconsistent_reset) 332 return true; 333 334 if (xe->wedged.mode == mode) 335 return false; 336 337 if (xe->wedged.mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET || 338 mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET) 339 return true; 340 341 return false; 342 } 343 344 static ssize_t wedged_mode_set(struct file *f, const char __user *ubuf, 345 size_t size, loff_t *pos) 346 { 347 struct xe_device *xe = file_inode(f)->i_private; 348 u32 wedged_mode; 349 ssize_t ret; 350 351 ret = kstrtouint_from_user(ubuf, size, 0, &wedged_mode); 352 if (ret) 353 return ret; 354 355 ret = xe_device_validate_wedged_mode(xe, wedged_mode); 356 if (ret) 357 return ret; 358 359 if (wedged_mode_needs_policy_update(xe, wedged_mode)) { 360 ret = wedged_mode_set_reset_policy(xe, wedged_mode); 361 if (ret) 362 return ret; 363 } 364 365 xe->wedged.mode = wedged_mode; 366 367 return size; 368 } 369 370 static const struct file_operations wedged_mode_fops = { 371 .owner = THIS_MODULE, 372 .read = wedged_mode_show, 373 .write = wedged_mode_set, 374 }; 375 376 static ssize_t page_reclaim_hw_assist_show(struct file *f, char __user *ubuf, 377 size_t size, loff_t *pos) 378 { 379 struct xe_device *xe = file_inode(f)->i_private; 380 char buf[8]; 381 int len; 382 383 len = scnprintf(buf, sizeof(buf), "%d\n", xe->info.has_page_reclaim_hw_assist); 384 return simple_read_from_buffer(ubuf, size, pos, buf, len); 385 } 386 387 static ssize_t page_reclaim_hw_assist_set(struct file *f, const char __user *ubuf, 388 size_t size, loff_t *pos) 389 { 390 struct xe_device *xe = file_inode(f)->i_private; 391 bool val; 392 ssize_t ret; 393 394 ret = kstrtobool_from_user(ubuf, size, &val); 395 if (ret) 396 return ret; 397 398 xe->info.has_page_reclaim_hw_assist = val; 399 400 return size; 401 } 402 403 static const struct file_operations page_reclaim_hw_assist_fops = { 404 .owner = THIS_MODULE, 405 .read = page_reclaim_hw_assist_show, 406 .write = page_reclaim_hw_assist_set, 407 }; 408 409 static ssize_t atomic_svm_timeslice_ms_show(struct file *f, char __user *ubuf, 410 size_t size, loff_t *pos) 411 { 412 struct xe_device *xe = file_inode(f)->i_private; 413 char buf[32]; 414 int len = 0; 415 416 len = scnprintf(buf, sizeof(buf), "%d\n", xe->atomic_svm_timeslice_ms); 417 418 return simple_read_from_buffer(ubuf, size, pos, buf, len); 419 } 420 421 static ssize_t atomic_svm_timeslice_ms_set(struct file *f, 422 const char __user *ubuf, 423 size_t size, loff_t *pos) 424 { 425 struct xe_device *xe = file_inode(f)->i_private; 426 u32 atomic_svm_timeslice_ms; 427 ssize_t ret; 428 429 ret = kstrtouint_from_user(ubuf, size, 0, &atomic_svm_timeslice_ms); 430 if (ret) 431 return ret; 432 433 xe->atomic_svm_timeslice_ms = atomic_svm_timeslice_ms; 434 435 return size; 436 } 437 438 static const struct file_operations atomic_svm_timeslice_ms_fops = { 439 .owner = THIS_MODULE, 440 .read = atomic_svm_timeslice_ms_show, 441 .write = atomic_svm_timeslice_ms_set, 442 }; 443 444 static ssize_t min_run_period_lr_ms_show(struct file *f, char __user *ubuf, 445 size_t size, loff_t *pos) 446 { 447 struct xe_device *xe = file_inode(f)->i_private; 448 char buf[32]; 449 int len = 0; 450 451 len = scnprintf(buf, sizeof(buf), "%d\n", xe->min_run_period_lr_ms); 452 453 return simple_read_from_buffer(ubuf, size, pos, buf, len); 454 } 455 456 static ssize_t min_run_period_lr_ms_set(struct file *f, const char __user *ubuf, 457 size_t size, loff_t *pos) 458 { 459 struct xe_device *xe = file_inode(f)->i_private; 460 u32 min_run_period_lr_ms; 461 ssize_t ret; 462 463 ret = kstrtouint_from_user(ubuf, size, 0, &min_run_period_lr_ms); 464 if (ret) 465 return ret; 466 467 xe->min_run_period_lr_ms = min_run_period_lr_ms; 468 469 return size; 470 } 471 472 static const struct file_operations min_run_period_lr_ms_fops = { 473 .owner = THIS_MODULE, 474 .read = min_run_period_lr_ms_show, 475 .write = min_run_period_lr_ms_set, 476 }; 477 478 static ssize_t min_run_period_pf_ms_show(struct file *f, char __user *ubuf, 479 size_t size, loff_t *pos) 480 { 481 struct xe_device *xe = file_inode(f)->i_private; 482 char buf[32]; 483 int len = 0; 484 485 len = scnprintf(buf, sizeof(buf), "%d\n", xe->min_run_period_pf_ms); 486 487 return simple_read_from_buffer(ubuf, size, pos, buf, len); 488 } 489 490 static ssize_t min_run_period_pf_ms_set(struct file *f, const char __user *ubuf, 491 size_t size, loff_t *pos) 492 { 493 struct xe_device *xe = file_inode(f)->i_private; 494 u32 min_run_period_pf_ms; 495 ssize_t ret; 496 497 ret = kstrtouint_from_user(ubuf, size, 0, &min_run_period_pf_ms); 498 if (ret) 499 return ret; 500 501 xe->min_run_period_pf_ms = min_run_period_pf_ms; 502 503 return size; 504 } 505 506 static const struct file_operations min_run_period_pf_ms_fops = { 507 .owner = THIS_MODULE, 508 .read = min_run_period_pf_ms_show, 509 .write = min_run_period_pf_ms_set, 510 }; 511 512 static ssize_t disable_late_binding_show(struct file *f, char __user *ubuf, 513 size_t size, loff_t *pos) 514 { 515 struct xe_device *xe = file_inode(f)->i_private; 516 struct xe_late_bind *late_bind = &xe->late_bind; 517 char buf[32]; 518 int len; 519 520 len = scnprintf(buf, sizeof(buf), "%d\n", late_bind->disable); 521 522 return simple_read_from_buffer(ubuf, size, pos, buf, len); 523 } 524 525 static ssize_t disable_late_binding_set(struct file *f, const char __user *ubuf, 526 size_t size, loff_t *pos) 527 { 528 struct xe_device *xe = file_inode(f)->i_private; 529 struct xe_late_bind *late_bind = &xe->late_bind; 530 bool val; 531 int ret; 532 533 ret = kstrtobool_from_user(ubuf, size, &val); 534 if (ret) 535 return ret; 536 537 late_bind->disable = val; 538 return size; 539 } 540 541 static const struct file_operations disable_late_binding_fops = { 542 .owner = THIS_MODULE, 543 .read = disable_late_binding_show, 544 .write = disable_late_binding_set, 545 }; 546 547 void xe_debugfs_register(struct xe_device *xe) 548 { 549 struct ttm_device *bdev = &xe->ttm; 550 struct drm_minor *minor = xe->drm.primary; 551 struct dentry *root = minor->debugfs_root; 552 struct ttm_resource_manager *man; 553 struct xe_tile *tile; 554 struct xe_gt *gt; 555 u8 tile_id; 556 u8 id; 557 558 drm_debugfs_create_files(debugfs_list, 559 ARRAY_SIZE(debugfs_list), 560 root, minor); 561 562 if (xe->info.platform == XE_BATTLEMAGE && !IS_SRIOV_VF(xe)) { 563 drm_debugfs_create_files(debugfs_residencies, 564 ARRAY_SIZE(debugfs_residencies), 565 root, minor); 566 fault_create_debugfs_attr("inject_csc_hw_error", root, 567 &inject_csc_hw_error); 568 } 569 570 debugfs_create_file("forcewake_all", 0400, root, xe, 571 &forcewake_all_fops); 572 573 debugfs_create_file("wedged_mode", 0600, root, xe, 574 &wedged_mode_fops); 575 576 debugfs_create_file("atomic_svm_timeslice_ms", 0600, root, xe, 577 &atomic_svm_timeslice_ms_fops); 578 579 debugfs_create_file("min_run_period_lr_ms", 0600, root, xe, 580 &min_run_period_lr_ms_fops); 581 582 debugfs_create_file("min_run_period_pf_ms", 0600, root, xe, 583 &min_run_period_pf_ms_fops); 584 585 debugfs_create_file("disable_late_binding", 0600, root, xe, 586 &disable_late_binding_fops); 587 588 /* 589 * Don't expose page reclaim configuration file if not supported by the 590 * hardware initially. 591 */ 592 if (xe->info.has_page_reclaim_hw_assist) 593 debugfs_create_file("page_reclaim_hw_assist", 0600, root, xe, 594 &page_reclaim_hw_assist_fops); 595 596 man = ttm_manager_type(bdev, XE_PL_TT); 597 ttm_resource_manager_create_debugfs(man, root, "gtt_mm"); 598 599 man = ttm_manager_type(bdev, XE_PL_STOLEN); 600 if (man) 601 ttm_resource_manager_create_debugfs(man, root, "stolen_mm"); 602 603 for_each_tile(tile, xe, tile_id) 604 xe_tile_debugfs_register(tile); 605 606 for_each_gt(gt, xe, id) 607 xe_gt_debugfs_register(gt); 608 609 xe_pxp_debugfs_register(xe->pxp); 610 611 xe_psmi_debugfs_register(xe); 612 613 fault_create_debugfs_attr("fail_gt_reset", root, >_reset_failure); 614 615 if (IS_SRIOV_PF(xe)) 616 xe_sriov_pf_debugfs_register(xe, root); 617 else if (IS_SRIOV_VF(xe)) 618 xe_sriov_vf_debugfs_register(xe, root); 619 } 620