1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include "xe_debugfs.h" 7 8 #include <linux/bits.h> 9 #include <linux/debugfs.h> 10 #include <linux/fault-inject.h> 11 #include <linux/string_helpers.h> 12 13 #include <drm/drm_debugfs.h> 14 15 #include "regs/xe_pmt.h" 16 #include "xe_bo.h" 17 #include "xe_device.h" 18 #include "xe_force_wake.h" 19 #include "xe_gt.h" 20 #include "xe_gt_debugfs.h" 21 #include "xe_gt_printk.h" 22 #include "xe_guc_ads.h" 23 #include "xe_hw_engine.h" 24 #include "xe_mmio.h" 25 #include "xe_pagefault.h" 26 #include "xe_pcode.h" 27 #include "xe_pm.h" 28 #include "xe_psmi.h" 29 #include "xe_pxp_debugfs.h" 30 #include "xe_sriov.h" 31 #include "xe_sriov_pf_debugfs.h" 32 #include "xe_sriov_vf.h" 33 #include "xe_step.h" 34 #include "xe_tile_debugfs.h" 35 #include "xe_ttm_vram_mgr.h" 36 #include "xe_vsec.h" 37 #include "xe_wa.h" 38 39 #ifdef CONFIG_DRM_XE_DEBUG 40 #include "xe_bo_evict.h" 41 #include "xe_migrate.h" 42 #include "xe_vm.h" 43 #endif 44 45 DECLARE_FAULT_ATTR(gt_reset_failure); 46 DECLARE_FAULT_ATTR(inject_csc_hw_error); 47 DECLARE_FAULT_ATTR(wedge_cold_reset); 48 DECLARE_FAULT_ATTR(inject_mempage_offline); 49 50 static bool csc_hw_error_available(struct xe_device *xe) 51 { 52 return !IS_SRIOV_VF(xe) && xe->info.platform == XE_BATTLEMAGE; 53 } 54 55 static bool is_crescent_island_pf(struct xe_device *xe) 56 { 57 return !IS_SRIOV_VF(xe) && xe->info.platform == XE_CRESCENTISLAND; 58 } 59 60 /* 61 * Fault injection table. Each entry registers a debugfs attribute; add a 62 * matching FAULT_ACTION() below for every entry added here. 63 */ 64 static struct { 65 const char *name; 66 struct fault_attr *attr; 67 bool (*is_visible)(struct xe_device *xe); 68 } xe_fault_inject_entry[] = { 69 { .name = "fail_gt_reset", 70 .attr = >_reset_failure }, 71 { .name = "inject_csc_hw_error", 72 .attr = &inject_csc_hw_error, 73 .is_visible = csc_hw_error_available }, 74 { .name = "wedge_cold_reset", 75 .attr = &wedge_cold_reset }, 76 { .name = "inject_mempage_offline", 77 .attr = &inject_mempage_offline, 78 .is_visible = is_crescent_island_pf }, 79 }; 80 81 /* 82 * FAULT_ACTION(name, fault_attr) - generate xe_fault_<name>() accessor. 83 * Add one entry per row in xe_fault_inject_entry[]. 84 */ 85 #define FAULT_ACTION(name, fault_attr) \ 86 bool xe_fault_##name(void) \ 87 { \ 88 return should_fail(&(fault_attr), 1); \ 89 } 90 91 FAULT_ACTION(gt_reset, gt_reset_failure) 92 FAULT_ACTION(csc_hw_error, inject_csc_hw_error) 93 FAULT_ACTION(wedge_cold_reset, wedge_cold_reset) 94 FAULT_ACTION(mempage_offline, inject_mempage_offline) 95 96 static ssize_t inject_mempage_offline_trigger(struct file *f, 97 const char __user *ubuf, 98 size_t size, loff_t *pos) 99 { 100 struct xe_device *xe = file_inode(f)->i_private; 101 struct xe_tile *tile = xe_device_get_root_tile(xe); 102 struct xe_vram_region *vr = tile->mem.vram; 103 u64 pfn; 104 int ret; 105 106 if (!vr) 107 return -ENODEV; 108 109 ret = kstrtou64_from_user(ubuf, size, 0, &pfn); 110 if (ret) 111 return ret; 112 113 if (!xe_fault_mempage_offline()) 114 return size; 115 116 xe_warn(xe, "Page offlining test interface accessed. Notice: Offlined or reserved memory pages cannot be reclaimed dynamically. A driver rebind (unbind and bind loop) is required post-test to clean up.\n"); 117 if (pfn == 0) 118 return xe_ttm_vram_inject_fault(xe) ?: size; 119 120 /* User provided PFN - convert to DPA and inject */ 121 return xe_ttm_vram_handle_addr_fault(xe, pfn << PAGE_SHIFT) ?: size; 122 } 123 124 static const struct file_operations inject_mempage_offline_fops = { 125 .owner = THIS_MODULE, 126 .write = inject_mempage_offline_trigger, 127 }; 128 129 static void xe_fault_inject_debugfs_register(struct xe_device *xe, 130 struct dentry *root) 131 { 132 int i; 133 134 for (i = 0; i < ARRAY_SIZE(xe_fault_inject_entry); i++) { 135 if (xe_fault_inject_entry[i].is_visible && 136 !xe_fault_inject_entry[i].is_visible(xe)) 137 continue; 138 139 fault_create_debugfs_attr(xe_fault_inject_entry[i].name, root, 140 xe_fault_inject_entry[i].attr); 141 } 142 143 if (is_crescent_island_pf(xe)) { 144 debugfs_create_file("inject_mempage_offline_trigger", 0200, 145 root, xe, &inject_mempage_offline_fops); 146 } 147 } 148 149 static void read_residency_counter(struct xe_device *xe, struct xe_mmio *mmio, 150 u32 offset, const char *name, struct drm_printer *p) 151 { 152 u64 residency = 0; 153 int ret; 154 155 ret = xe_pmt_telem_read(xe->drm.dev, 156 xe_mmio_read32(mmio, PUNIT_TELEMETRY_GUID), 157 &residency, offset, sizeof(residency)); 158 if (ret != sizeof(residency)) { 159 drm_warn(&xe->drm, "%s counter failed to read, ret %d\n", name, ret); 160 return; 161 } 162 163 drm_printf(p, "%s : %llu\n", name, residency); 164 } 165 166 static struct xe_device *node_to_xe(struct drm_info_node *node) 167 { 168 return to_xe_device(node->minor->dev); 169 } 170 171 static void print_engine_class_mask(struct drm_printer *p, u16 mask) 172 { 173 if (!mask) { 174 drm_printf(p, " none\n"); 175 return; 176 } 177 178 for (enum xe_engine_class ec = 0; ec < XE_ENGINE_CLASS_MAX; ec++) { 179 if (mask & BIT(ec)) 180 drm_printf(p, " %s", xe_hw_engine_class_to_str(ec)); 181 } 182 drm_printf(p, "\n"); 183 } 184 185 static void print_engine_mask(struct drm_printer *p, struct xe_gt *gt, u64 mask) 186 { 187 struct xe_hw_engine *hwe; 188 enum xe_hw_engine_id id; 189 190 if (!mask) { 191 drm_printf(p, " none\n"); 192 return; 193 } 194 195 for_each_hw_engine(hwe, gt, id) { 196 if (mask & BIT_ULL(id)) 197 drm_printf(p, " %s", hwe->name); 198 } 199 drm_printf(p, "\n"); 200 } 201 202 static int info(struct seq_file *m, void *data) 203 { 204 struct xe_device *xe = node_to_xe(m->private); 205 struct drm_printer p = drm_seq_file_printer(m); 206 struct xe_gt *gt; 207 u8 id; 208 209 guard(xe_pm_runtime)(xe); 210 211 drm_printf(&p, "graphics_verx100 %d\n", xe->info.graphics_verx100); 212 drm_printf(&p, "media_verx100 %d\n", xe->info.media_verx100); 213 drm_printf(&p, "stepping G:%s M:%s B:%s\n", 214 xe_step_name(xe->info.step.graphics), 215 xe_step_name(xe->info.step.media), 216 xe_step_name(xe->info.step.basedie)); 217 drm_printf(&p, "is_dgfx %s\n", str_yes_no(xe->info.is_dgfx)); 218 drm_printf(&p, "platform %d\n", xe->info.platform); 219 drm_printf(&p, "subplatform %d\n", 220 xe->info.subplatform > XE_SUBPLATFORM_NONE ? xe->info.subplatform : 0); 221 drm_printf(&p, "devid 0x%x\n", xe->info.devid); 222 drm_printf(&p, "revid %d\n", xe->info.revid); 223 drm_printf(&p, "tile_count %d\n", xe->info.tile_count); 224 drm_printf(&p, "vm_max_level %d\n", xe->info.vm_max_level); 225 drm_printf(&p, "has_flat_ccs %s\n", str_yes_no(xe->info.has_flat_ccs)); 226 drm_printf(&p, "has_usm %s\n", str_yes_no(xe->info.has_usm)); 227 drm_printf(&p, "skip_guc_pc %s\n", str_yes_no(xe->info.skip_guc_pc)); 228 drm_printf(&p, "multi_lrc_engine_classes"); 229 print_engine_class_mask(&p, xe->info.multi_lrc_mask); 230 for_each_gt(gt, xe, id) { 231 drm_printf(&p, "gt%d force wake %d\n", id, 232 xe_force_wake_ref(gt_to_fw(gt), XE_FW_GT)); 233 drm_printf(&p, "gt%d engines", id); 234 print_engine_mask(&p, gt, gt->info.engine_mask); 235 drm_printf(&p, "gt%d multi_queue_engine_classes", id); 236 print_engine_class_mask(&p, gt->info.multi_queue_engine_class_mask); 237 } 238 239 return 0; 240 } 241 242 static int sriov_info(struct seq_file *m, void *data) 243 { 244 struct xe_device *xe = node_to_xe(m->private); 245 struct drm_printer p = drm_seq_file_printer(m); 246 247 xe_sriov_print_info(xe, &p); 248 return 0; 249 } 250 251 static int pagefault_info(struct seq_file *m, void *data) 252 { 253 struct xe_device *xe = node_to_xe(m->private); 254 struct drm_printer p = drm_seq_file_printer(m); 255 256 xe_pagefault_print_info(xe, &p); 257 return 0; 258 } 259 260 static int workarounds(struct xe_device *xe, struct drm_printer *p) 261 { 262 guard(xe_pm_runtime)(xe); 263 xe_wa_device_dump(xe, p); 264 265 return 0; 266 } 267 268 static int workaround_info(struct seq_file *m, void *data) 269 { 270 struct xe_device *xe = node_to_xe(m->private); 271 struct drm_printer p = drm_seq_file_printer(m); 272 273 workarounds(xe, &p); 274 return 0; 275 } 276 277 static int pcode_info(struct seq_file *m, void *data) 278 { 279 struct xe_device *xe = node_to_xe(m->private); 280 struct drm_printer p = drm_seq_file_printer(m); 281 struct xe_pcode_version version; 282 int ret = 0; 283 284 ret = xe_get_pcode_version(xe, &version); 285 if (ret) 286 return ret; 287 288 drm_printf(&p, "pcode version: %u.%u.%u\n", version.major, 289 version.minor, version.engg); 290 return 0; 291 } 292 293 static int dgfx_pkg_residencies_show(struct seq_file *m, void *data) 294 { 295 struct xe_device *xe; 296 struct xe_mmio *mmio; 297 struct drm_printer p; 298 299 xe = node_to_xe(m->private); 300 p = drm_seq_file_printer(m); 301 guard(xe_pm_runtime)(xe); 302 mmio = xe_root_tile_mmio(xe); 303 static const struct { 304 u32 offset; 305 const char *name; 306 } residencies[] = { 307 {BMG_G2_RESIDENCY_OFFSET, "Package G2"}, 308 {BMG_G6_RESIDENCY_OFFSET, "Package G6"}, 309 {BMG_G7_RESIDENCY_OFFSET, "Package G7"}, 310 {BMG_G8_RESIDENCY_OFFSET, "Package G8"}, 311 {BMG_G10_RESIDENCY_OFFSET, "Package G10"}, 312 {BMG_MODS_RESIDENCY_OFFSET, "Package ModS"} 313 }; 314 315 for (int i = 0; i < ARRAY_SIZE(residencies); i++) 316 read_residency_counter(xe, mmio, residencies[i].offset, residencies[i].name, &p); 317 318 return 0; 319 } 320 321 static int dgfx_pcie_link_residencies_show(struct seq_file *m, void *data) 322 { 323 struct xe_device *xe; 324 struct xe_mmio *mmio; 325 struct drm_printer p; 326 327 xe = node_to_xe(m->private); 328 p = drm_seq_file_printer(m); 329 guard(xe_pm_runtime)(xe); 330 mmio = xe_root_tile_mmio(xe); 331 332 static const struct { 333 u32 offset; 334 const char *name; 335 } residencies[] = { 336 {BMG_PCIE_LINK_L0_RESIDENCY_OFFSET, "PCIE LINK L0 RESIDENCY"}, 337 {BMG_PCIE_LINK_L1_RESIDENCY_OFFSET, "PCIE LINK L1 RESIDENCY"}, 338 {BMG_PCIE_LINK_L1_2_RESIDENCY_OFFSET, "PCIE LINK L1.2 RESIDENCY"} 339 }; 340 341 for (int i = 0; i < ARRAY_SIZE(residencies); i++) 342 read_residency_counter(xe, mmio, residencies[i].offset, residencies[i].name, &p); 343 344 return 0; 345 } 346 347 static const struct drm_info_list debugfs_list[] = { 348 {"info", info, 0}, 349 { .name = "sriov_info", .show = sriov_info, }, 350 { .name = "workarounds", .show = workaround_info, }, 351 { .name = "pagefault_info", .show = pagefault_info, }, 352 }; 353 354 static const struct drm_info_list pcode_info_debugfs[] = { 355 { .name = "pcode_info", .show = pcode_info, }, 356 }; 357 358 static const struct drm_info_list debugfs_residencies[] = { 359 { .name = "dgfx_pkg_residencies", .show = dgfx_pkg_residencies_show, }, 360 { .name = "dgfx_pcie_link_residencies", .show = dgfx_pcie_link_residencies_show, }, 361 }; 362 363 static int forcewake_open(struct inode *inode, struct file *file) 364 { 365 struct xe_device *xe = inode->i_private; 366 struct xe_gt *gt; 367 u8 id, last_gt; 368 unsigned int fw_ref; 369 370 xe_pm_runtime_get(xe); 371 for_each_gt(gt, xe, id) { 372 last_gt = id; 373 374 fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL); 375 if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL)) 376 goto err_fw_get; 377 } 378 379 return 0; 380 381 err_fw_get: 382 for_each_gt(gt, xe, id) { 383 if (id < last_gt) 384 xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL); 385 else if (id == last_gt) 386 xe_force_wake_put(gt_to_fw(gt), fw_ref); 387 else 388 break; 389 } 390 391 xe_pm_runtime_put(xe); 392 return -ETIMEDOUT; 393 } 394 395 static int forcewake_release(struct inode *inode, struct file *file) 396 { 397 struct xe_device *xe = inode->i_private; 398 struct xe_gt *gt; 399 u8 id; 400 401 for_each_gt(gt, xe, id) 402 xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL); 403 xe_pm_runtime_put(xe); 404 405 return 0; 406 } 407 408 static const struct file_operations forcewake_all_fops = { 409 .owner = THIS_MODULE, 410 .open = forcewake_open, 411 .release = forcewake_release, 412 }; 413 414 static ssize_t wedged_mode_show(struct file *f, char __user *ubuf, 415 size_t size, loff_t *pos) 416 { 417 struct xe_device *xe = file_inode(f)->i_private; 418 char buf[32]; 419 int len = 0; 420 421 len = scnprintf(buf, sizeof(buf), "%d\n", xe->wedged.mode); 422 423 return simple_read_from_buffer(ubuf, size, pos, buf, len); 424 } 425 426 static int __wedged_mode_set_reset_policy(struct xe_gt *gt, enum xe_wedged_mode mode) 427 { 428 bool enable_engine_reset; 429 int ret; 430 431 enable_engine_reset = (mode != XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET); 432 ret = xe_guc_ads_scheduler_policy_toggle_reset(>->uc.guc.ads, 433 enable_engine_reset); 434 if (ret) 435 xe_gt_err(gt, "Failed to update GuC ADS scheduler policy (%pe)\n", ERR_PTR(ret)); 436 437 return ret; 438 } 439 440 static int wedged_mode_set_reset_policy(struct xe_device *xe, enum xe_wedged_mode mode) 441 { 442 struct xe_gt *gt; 443 int ret; 444 u8 id; 445 446 guard(xe_pm_runtime)(xe); 447 for_each_gt(gt, xe, id) { 448 ret = __wedged_mode_set_reset_policy(gt, mode); 449 if (ret) { 450 if (id > 0) { 451 xe->wedged.inconsistent_reset = true; 452 drm_err(&xe->drm, "Inconsistent reset policy state between GTs\n"); 453 } 454 return ret; 455 } 456 } 457 458 xe->wedged.inconsistent_reset = false; 459 460 return 0; 461 } 462 463 static bool wedged_mode_needs_policy_update(struct xe_device *xe, enum xe_wedged_mode mode) 464 { 465 if (xe->wedged.inconsistent_reset) 466 return true; 467 468 if (xe->wedged.mode == mode) 469 return false; 470 471 if (xe->wedged.mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET || 472 mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET) 473 return true; 474 475 return false; 476 } 477 478 static ssize_t wedged_mode_set(struct file *f, const char __user *ubuf, 479 size_t size, loff_t *pos) 480 { 481 struct xe_device *xe = file_inode(f)->i_private; 482 u32 wedged_mode; 483 ssize_t ret; 484 485 ret = kstrtouint_from_user(ubuf, size, 0, &wedged_mode); 486 if (ret) 487 return ret; 488 489 ret = xe_device_validate_wedged_mode(xe, wedged_mode); 490 if (ret) 491 return ret; 492 493 if (wedged_mode_needs_policy_update(xe, wedged_mode)) { 494 ret = wedged_mode_set_reset_policy(xe, wedged_mode); 495 if (ret) 496 return ret; 497 } 498 499 xe->wedged.mode = wedged_mode; 500 501 return size; 502 } 503 504 static const struct file_operations wedged_mode_fops = { 505 .owner = THIS_MODULE, 506 .read = wedged_mode_show, 507 .write = wedged_mode_set, 508 }; 509 510 static ssize_t page_reclaim_hw_assist_show(struct file *f, char __user *ubuf, 511 size_t size, loff_t *pos) 512 { 513 struct xe_device *xe = file_inode(f)->i_private; 514 char buf[8]; 515 int len; 516 517 len = scnprintf(buf, sizeof(buf), "%d\n", xe->info.has_page_reclaim_hw_assist); 518 return simple_read_from_buffer(ubuf, size, pos, buf, len); 519 } 520 521 static ssize_t page_reclaim_hw_assist_set(struct file *f, const char __user *ubuf, 522 size_t size, loff_t *pos) 523 { 524 struct xe_device *xe = file_inode(f)->i_private; 525 bool val; 526 ssize_t ret; 527 528 ret = kstrtobool_from_user(ubuf, size, &val); 529 if (ret) 530 return ret; 531 532 xe->info.has_page_reclaim_hw_assist = val; 533 534 return size; 535 } 536 537 static const struct file_operations page_reclaim_hw_assist_fops = { 538 .owner = THIS_MODULE, 539 .read = page_reclaim_hw_assist_show, 540 .write = page_reclaim_hw_assist_set, 541 }; 542 543 static ssize_t atomic_svm_timeslice_ms_show(struct file *f, char __user *ubuf, 544 size_t size, loff_t *pos) 545 { 546 struct xe_device *xe = file_inode(f)->i_private; 547 char buf[32]; 548 int len = 0; 549 550 len = scnprintf(buf, sizeof(buf), "%d\n", xe->atomic_svm_timeslice_ms); 551 552 return simple_read_from_buffer(ubuf, size, pos, buf, len); 553 } 554 555 static ssize_t atomic_svm_timeslice_ms_set(struct file *f, 556 const char __user *ubuf, 557 size_t size, loff_t *pos) 558 { 559 struct xe_device *xe = file_inode(f)->i_private; 560 u32 atomic_svm_timeslice_ms; 561 ssize_t ret; 562 563 ret = kstrtouint_from_user(ubuf, size, 0, &atomic_svm_timeslice_ms); 564 if (ret) 565 return ret; 566 567 xe->atomic_svm_timeslice_ms = atomic_svm_timeslice_ms; 568 569 return size; 570 } 571 572 static const struct file_operations atomic_svm_timeslice_ms_fops = { 573 .owner = THIS_MODULE, 574 .read = atomic_svm_timeslice_ms_show, 575 .write = atomic_svm_timeslice_ms_set, 576 }; 577 578 static ssize_t min_run_period_lr_ms_show(struct file *f, char __user *ubuf, 579 size_t size, loff_t *pos) 580 { 581 struct xe_device *xe = file_inode(f)->i_private; 582 char buf[32]; 583 int len = 0; 584 585 len = scnprintf(buf, sizeof(buf), "%d\n", xe->min_run_period_lr_ms); 586 587 return simple_read_from_buffer(ubuf, size, pos, buf, len); 588 } 589 590 static ssize_t min_run_period_lr_ms_set(struct file *f, const char __user *ubuf, 591 size_t size, loff_t *pos) 592 { 593 struct xe_device *xe = file_inode(f)->i_private; 594 u32 min_run_period_lr_ms; 595 ssize_t ret; 596 597 ret = kstrtouint_from_user(ubuf, size, 0, &min_run_period_lr_ms); 598 if (ret) 599 return ret; 600 601 xe->min_run_period_lr_ms = min_run_period_lr_ms; 602 603 return size; 604 } 605 606 static const struct file_operations min_run_period_lr_ms_fops = { 607 .owner = THIS_MODULE, 608 .read = min_run_period_lr_ms_show, 609 .write = min_run_period_lr_ms_set, 610 }; 611 612 static ssize_t min_run_period_pf_ms_show(struct file *f, char __user *ubuf, 613 size_t size, loff_t *pos) 614 { 615 struct xe_device *xe = file_inode(f)->i_private; 616 char buf[32]; 617 int len = 0; 618 619 len = scnprintf(buf, sizeof(buf), "%d\n", xe->min_run_period_pf_ms); 620 621 return simple_read_from_buffer(ubuf, size, pos, buf, len); 622 } 623 624 static ssize_t min_run_period_pf_ms_set(struct file *f, const char __user *ubuf, 625 size_t size, loff_t *pos) 626 { 627 struct xe_device *xe = file_inode(f)->i_private; 628 u32 min_run_period_pf_ms; 629 ssize_t ret; 630 631 ret = kstrtouint_from_user(ubuf, size, 0, &min_run_period_pf_ms); 632 if (ret) 633 return ret; 634 635 xe->min_run_period_pf_ms = min_run_period_pf_ms; 636 637 return size; 638 } 639 640 static const struct file_operations min_run_period_pf_ms_fops = { 641 .owner = THIS_MODULE, 642 .read = min_run_period_pf_ms_show, 643 .write = min_run_period_pf_ms_set, 644 }; 645 646 static ssize_t disable_late_binding_show(struct file *f, char __user *ubuf, 647 size_t size, loff_t *pos) 648 { 649 struct xe_device *xe = file_inode(f)->i_private; 650 struct xe_late_bind *late_bind = &xe->late_bind; 651 char buf[32]; 652 int len; 653 654 len = scnprintf(buf, sizeof(buf), "%d\n", late_bind->disable); 655 656 return simple_read_from_buffer(ubuf, size, pos, buf, len); 657 } 658 659 static ssize_t disable_late_binding_set(struct file *f, const char __user *ubuf, 660 size_t size, loff_t *pos) 661 { 662 struct xe_device *xe = file_inode(f)->i_private; 663 struct xe_late_bind *late_bind = &xe->late_bind; 664 bool val; 665 int ret; 666 667 ret = kstrtobool_from_user(ubuf, size, &val); 668 if (ret) 669 return ret; 670 671 late_bind->disable = val; 672 return size; 673 } 674 675 static const struct file_operations disable_late_binding_fops = { 676 .owner = THIS_MODULE, 677 .read = disable_late_binding_show, 678 .write = disable_late_binding_set, 679 }; 680 681 #ifdef CONFIG_DRM_XE_DEBUG_PAGE_SIZE 682 static const char * const page_size_alloc_mode_names[] = { 683 [XE_PAGE_SIZE_ALLOC_CTRL_MODE_NONE] = "none", 684 [XE_PAGE_SIZE_ALLOC_CTRL_MODE_ONLY_2M] = "only_2m", 685 [XE_PAGE_SIZE_ALLOC_CTRL_MODE_ONLY_1G] = "only_1g", 686 [XE_PAGE_SIZE_ALLOC_CTRL_MODE_MIXED] = "mixed", 687 }; 688 689 static ssize_t page_size_alloc_mode_show(struct file *f, char __user *ubuf, 690 size_t size, loff_t *pos) 691 { 692 struct xe_device *xe = file_inode(f)->i_private; 693 char buf[32]; 694 int len; 695 enum xe_page_size_alloc_ctrl_mode mode; 696 697 mode = READ_ONCE(xe->page_size_alloc_ctrl.mode); 698 if (mode >= ARRAY_SIZE(page_size_alloc_mode_names) || 699 !page_size_alloc_mode_names[mode]) 700 len = scnprintf(buf, sizeof(buf), "unknown\n"); 701 else 702 len = scnprintf(buf, sizeof(buf), "%s\n", 703 page_size_alloc_mode_names[mode]); 704 return simple_read_from_buffer(ubuf, size, pos, buf, len); 705 } 706 707 static ssize_t page_size_alloc_mode_set(struct file *f, const char __user *ubuf, 708 size_t size, loff_t *pos) 709 { 710 struct xe_device *xe = file_inode(f)->i_private; 711 int ret; 712 char buf[32]; 713 int mode; 714 715 if (*pos) 716 return -ESPIPE; 717 718 if (size > sizeof(buf) - 1) 719 return -EINVAL; 720 721 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, pos, ubuf, size); 722 if (ret < 0) 723 return ret; 724 buf[ret] = '\0'; 725 726 mode = sysfs_match_string(page_size_alloc_mode_names, buf); 727 if (mode < 0) 728 return mode; 729 730 mutex_lock(&xe->page_size_alloc_ctrl.lock); 731 if (mode == XE_PAGE_SIZE_ALLOC_CTRL_MODE_MIXED) 732 xe->page_size_alloc_ctrl.cur_index = 0; 733 WRITE_ONCE(xe->page_size_alloc_ctrl.mode, 734 (enum xe_page_size_alloc_ctrl_mode)mode); 735 mutex_unlock(&xe->page_size_alloc_ctrl.lock); 736 737 return size; 738 } 739 740 static const struct file_operations page_size_alloc_mode_fops = { 741 .owner = THIS_MODULE, 742 .read = page_size_alloc_mode_show, 743 .write = page_size_alloc_mode_set, 744 }; 745 #endif 746 747 void xe_debugfs_register(struct xe_device *xe) 748 { 749 struct ttm_device *bdev = &xe->ttm; 750 struct drm_minor *minor = xe->drm.primary; 751 struct dentry *root = minor->debugfs_root; 752 struct ttm_resource_manager *man; 753 struct xe_tile *tile; 754 struct xe_gt *gt; 755 u8 tile_id; 756 u8 id; 757 758 drm_debugfs_create_files(debugfs_list, 759 ARRAY_SIZE(debugfs_list), 760 root, minor); 761 762 if (xe->info.platform == XE_BATTLEMAGE && !IS_SRIOV_VF(xe)) { 763 drm_debugfs_create_files(debugfs_residencies, 764 ARRAY_SIZE(debugfs_residencies), 765 root, minor); 766 } 767 768 /* 769 * Pcode version read from PMT is currently only supported on CRI and BMG platforms in PF 770 * mode, as both platforms support the necessary telemetry read mechanism and have a fixed 771 * PUNIT_VERSION_OFFSET. 772 * Attempting this access on other platforms must be verified before enabling support. 773 */ 774 if (!IS_SRIOV_VF(xe) && 775 (xe->info.platform == XE_CRESCENTISLAND || xe->info.platform == XE_BATTLEMAGE)) 776 drm_debugfs_create_files(pcode_info_debugfs, 777 ARRAY_SIZE(pcode_info_debugfs), 778 root, minor); 779 780 debugfs_create_file("forcewake_all", 0400, root, xe, 781 &forcewake_all_fops); 782 783 debugfs_create_file("wedged_mode", 0600, root, xe, 784 &wedged_mode_fops); 785 786 debugfs_create_file("atomic_svm_timeslice_ms", 0600, root, xe, 787 &atomic_svm_timeslice_ms_fops); 788 789 debugfs_create_file("min_run_period_lr_ms", 0600, root, xe, 790 &min_run_period_lr_ms_fops); 791 792 debugfs_create_file("min_run_period_pf_ms", 0600, root, xe, 793 &min_run_period_pf_ms_fops); 794 795 debugfs_create_file("disable_late_binding", 0600, root, xe, 796 &disable_late_binding_fops); 797 798 #ifdef CONFIG_DRM_XE_DEBUG_PAGE_SIZE 799 /* 800 * Expose a debugfs knob to control user BO page-size allocation: 801 * "none" - default behavior 802 * "only_2m" - force 2M page allocations 803 * "only_1g" - force 1G page allocations 804 * "mixed" - select 4K, 64K, 2M, and 1G in round-robin order 805 */ 806 if (xe_debug_page_size_supported(xe)) 807 debugfs_create_file("page_size_alloc_mode", 0600, root, xe, 808 &page_size_alloc_mode_fops); 809 #endif 810 /* 811 * Don't expose page reclaim configuration file if not supported by the 812 * hardware initially. 813 */ 814 if (xe->info.has_page_reclaim_hw_assist) 815 debugfs_create_file("page_reclaim_hw_assist", 0600, root, xe, 816 &page_reclaim_hw_assist_fops); 817 818 man = ttm_manager_type(bdev, XE_PL_TT); 819 ttm_resource_manager_create_debugfs(man, root, "gtt_mm"); 820 821 man = ttm_manager_type(bdev, XE_PL_STOLEN); 822 if (man) 823 ttm_resource_manager_create_debugfs(man, root, "stolen_mm"); 824 825 xe_ttm_vram_debugfs_init(xe, root); 826 827 for_each_tile(tile, xe, tile_id) 828 xe_tile_debugfs_register(tile); 829 830 for_each_gt(gt, xe, id) 831 xe_gt_debugfs_register(gt); 832 833 xe_pxp_debugfs_register(xe->pxp); 834 835 xe_psmi_debugfs_register(xe); 836 837 xe_fault_inject_debugfs_register(xe, root); 838 839 if (IS_SRIOV_PF(xe)) 840 xe_sriov_pf_debugfs_register(xe, root); 841 else if (IS_SRIOV_VF(xe)) 842 xe_sriov_vf_debugfs_register(xe, root); 843 } 844