History

Merge tag 'drm-xe-next-2025-04-17' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next

Core Changes: Fix drm_gpusvm kernel-doc (Lucas) Driver Changes: - Release guc ids before cancelling work (Tejas) - Remove a duplicated pc_start_call (Rodrigo) - Fix an incorrect assert in previous userptr fixes (Thomas) - Remove gen11 assertions and prefixes (Lucas) - Drop sentinels from arg to xe_rtp_process_to_src (Lucas) - Temporarily disable D3Cold on BMG (Rodrigo) - Fix MOCS debugfs LNCF readout (Tvrtko) - Some ring flush cleanups (Tvrtko) - Use unsigned int for alignment in fb pinning code (Tvrtko) - Retry and wait longer for GuC PC start (Rodrigo) - Recognize 3DSTATE_COARSE_PIXEL in LRC dumps (Matt Roper) - Remove reduntant check in xe_vm_create_ioctl() (Xin) - A bunch of SRIOV updates (Michal) - Add stats for SVM page-faults (Francois) - Fix an UAF (Harish) - Expose fan speed (Raag) - Fix exporting xe buffer objects multiple times (Tomasz) - Apply a workaround (Vinay) - Simplify pinned bo iteration (Thomas) - Remove an incorrect "static" keywork (Lucas) - Add support for separate firmware files on each GT (Lucas) - Survivability handling fixes (Lucas) - Allow to inject error in early probe (Lucas) - Fix unmet direct dependencies warning (Yue Haibing) - More error injection during probe (Francois) - Coding style fix (Maarten) - Additional stats support (Riana) - Add fault injection for xe_oa_alloc_regs (Nakshrtra) - Add a BMG PCI ID (Matt Roper) - Some SVM fixes and preliminary SVM multi-device work (Thomas) - Switch the migrate code from drm managed to dev managed (Aradhya) - Fix an out-of-bounds shift when invalidating TLB (Thomas) - Ensure fixed_slice_mode gets set after ccs_mode change (Niranjana) - Use local fence in error path of xe_migrate_clear (Matthew Brost) - More Workarounds (Julia) - Define sysfs_ops on all directories (Tejas) - Set power state to D3Cold during s2idle/s3 (Badal) - Devcoredump output fix (John) - Avoid plain 64-bit division (Arnd Bergmann) - Reword a debug message (John) - Don't print a hwconfig error message when forcing execlists (Stuart) - Restore an error code to avoid a smatch warning (Rodrigo) - Invalidate L3 read-only cachelines for geometry streams too (Kenneth) - Make PPHWSP size explicit in xe_gt_lrc_size() (Gustavo) - Add GT frequency events (Vinay) - Fix xe_pt_stage_bind_walk kerneldoc (Thomas) - Add a workaround (Aradhya) - Rework pinned save/restore (Matthew Auld, Matthew Brost) - Allow non-contig VRAM kernel BO (Matthew Auld) - Support non-contig VRAM provisioning for SRIOV (Matthew Auld) - Allow scratch-pages for unmapped parts of page-faulting VMs. (Oak) - Ensure XE_BO_FLAG_CPU_ADDR_MIRROR had a unique value (Matt Roper) - Fix taking an invalid lock on wedge (Lucas) - Configs and documentation for survivability mode (Riana) - Remove an unused macro (Shuicheng) - Work around a page-fault full error (Matt Brost) - Enable a SRIOV workaround (John) - Bump the recommended GuC version (John) - Allow to drop VRAM resizing (Lucas) - Don't expose privileged debugfs files if VF (Michal) - Don't show GGTT/LMEM debugfs files under media GT (Michal) - Adjust ring-buffer emission for maximum possible size (Tvrtko) - Fix notifier vs folio lock deadlock (Matthew Auld) - Stop relying on placement for dma-buf unmap Matthew Auld) Signed-off-by: Dave Airlie <airlied@redhat.com>

Dave Airlie committed 1 year ago

Commit d2b9e2f2 parents 55df7c0 d75588784 files · +2131 −820Browse files

Unified · Split

84 files
  1. Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon +24 −0
  2. Documentation/gpu/xe/index.rst +1 −0
  3. Documentation/gpu/xe/xe_configfs.rst +10 −0
  4. Documentation/gpu/xe/xe_pcode.rst +7 −0
  5. drivers/gpu/drm/xe/Kconfig +14 −2
  6. drivers/gpu/drm/xe/Makefile +2 −1
  7. drivers/gpu/drm/xe/abi/guc_actions_abi.h +1 −0
  8. drivers/gpu/drm/xe/abi/guc_klvs_abi.h +1 −0
  9. drivers/gpu/drm/xe/display/intel_fbdev_fb.c +2 −2
  10. drivers/gpu/drm/xe/display/xe_plane_initial.c +1 −1
  11. drivers/gpu/drm/xe/instructions/xe_alu_commands.h +79 −0
  12. drivers/gpu/drm/xe/instructions/xe_gfxpipe_commands.h +1 −0
  13. drivers/gpu/drm/xe/instructions/xe_mi_commands.h +5 −0
  14. drivers/gpu/drm/xe/regs/xe_engine_regs.h +4 −0
  15. drivers/gpu/drm/xe/regs/xe_gt_regs.h +12 −1
  16. drivers/gpu/drm/xe/regs/xe_pcode_regs.h +3 −0
  17. drivers/gpu/drm/xe/tests/xe_bo.c +2 −2
  18. drivers/gpu/drm/xe/tests/xe_migrate.c +3 −6
  19. drivers/gpu/drm/xe/xe_bo.c +239 −164
  20. drivers/gpu/drm/xe/xe_bo.h +14 −9
  21. drivers/gpu/drm/xe/xe_bo_evict.c +179 −130
  22. drivers/gpu/drm/xe/xe_bo_evict.h +5 −2
  23. drivers/gpu/drm/xe/xe_bo_types.h +2 −0
  24. drivers/gpu/drm/xe/xe_configfs.c +250 −0
  25. drivers/gpu/drm/xe/xe_configfs.h +24 −0
  26. drivers/gpu/drm/xe/xe_device.c +19 −10
  27. drivers/gpu/drm/xe/xe_device_types.h +24 −8
  28. drivers/gpu/drm/xe/xe_dma_buf.c +1 −4
  29. drivers/gpu/drm/xe/xe_force_wake.c +0 −6
  30. drivers/gpu/drm/xe/xe_ggtt.c +1 −1
  31. drivers/gpu/drm/xe/xe_gt.c +63 −21
  32. drivers/gpu/drm/xe/xe_gt_debugfs.c +22 −8
  33. drivers/gpu/drm/xe/xe_gt_mcr.c +2 −1
  34. drivers/gpu/drm/xe/xe_gt_pagefault.c +10 −3
  35. drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c +14 −6
  36. drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c +49 −17
  37. drivers/gpu/drm/xe/xe_gt_sriov_pf_service.c +0 −6
  38. drivers/gpu/drm/xe/xe_gt_stats.c +1 −0
  39. drivers/gpu/drm/xe/xe_gt_stats_types.h +1 −0
  40. drivers/gpu/drm/xe/xe_guc.c +2 −1
  41. drivers/gpu/drm/xe/xe_guc_ads.c +54 −33
  42. drivers/gpu/drm/xe/xe_guc_ct.c +3 −2
  43. drivers/gpu/drm/xe/xe_guc_debugfs.c +83 −65
  44. drivers/gpu/drm/xe/xe_guc_engine_activity.c +172 −28
  45. drivers/gpu/drm/xe/xe_guc_engine_activity.h +5 −2
  46. drivers/gpu/drm/xe/xe_guc_engine_activity_types.h +11 −1
  47. drivers/gpu/drm/xe/xe_guc_log.c +2 −1
  48. drivers/gpu/drm/xe/xe_guc_pc.c +17 −1
  49. drivers/gpu/drm/xe/xe_guc_pc.h +1 −0
  50. drivers/gpu/drm/xe/xe_guc_submit.c +9 −0
  51. drivers/gpu/drm/xe/xe_guc_types.h +5 −0
  52. drivers/gpu/drm/xe/xe_hmm.c +0 −24
  53. drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c +1 −0
  54. drivers/gpu/drm/xe/xe_hwmon.c +124 −1
  55. drivers/gpu/drm/xe/xe_lmtt.c +1 −1
  56. drivers/gpu/drm/xe/xe_lrc.c +18 −10
  57. drivers/gpu/drm/xe/xe_memirq.c +1 −1
  58. drivers/gpu/drm/xe/xe_migrate.c +15 −9
  59. drivers/gpu/drm/xe/xe_mmio.c +7 −4
  60. drivers/gpu/drm/xe/xe_module.c +7 −2
  61. drivers/gpu/drm/xe/xe_oa.c +1 −0
  62. drivers/gpu/drm/xe/xe_pci.c +19 −10
  63. drivers/gpu/drm/xe/xe_pci_sriov.c +20 −0
  64. drivers/gpu/drm/xe/xe_pcode.c +2 −0
  65. drivers/gpu/drm/xe/xe_pcode_api.h +3 −0
  66. drivers/gpu/drm/xe/xe_pm.c +4 −4
  67. drivers/gpu/drm/xe/xe_pmu.c +67 −10
  68. drivers/gpu/drm/xe/xe_pt.c +140 −98
  69. drivers/gpu/drm/xe/xe_query.c +1 −1
  70. drivers/gpu/drm/xe/xe_reg_sr.c +3 −0
  71. drivers/gpu/drm/xe/xe_ring_ops_types.h +1 −1
  72. drivers/gpu/drm/xe/xe_rtp.c +0 −3
  73. drivers/gpu/drm/xe/xe_sa.c +2 −1
  74. drivers/gpu/drm/xe/xe_survivability_mode.c +50 −19
  75. drivers/gpu/drm/xe/xe_survivability_mode.h +1 −0
  76. drivers/gpu/drm/xe/xe_svm.c +21 −2
  77. drivers/gpu/drm/xe/xe_svm.h +57 −23
  78. drivers/gpu/drm/xe/xe_uc_fw.c +55 −39
  79. drivers/gpu/drm/xe/xe_vm.c +29 −10
  80. drivers/gpu/drm/xe/xe_vm_types.h +2 −0
  81. drivers/gpu/drm/xe/xe_vram.c +4 −1
  82. drivers/gpu/drm/xe/xe_wa.c +12 −0
  83. drivers/gpu/drm/xe/xe_wa_oob.rules +2 −0
  84. include/uapi/drm/xe_drm.h +5 −1
Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon+24−0
@@ -124,3 +124,27 @@ Contact: intel-xe@lists.freedesktop.org · 123 unmodified lines
124Description: RO. VRAM temperature in millidegree Celsius.124Description: RO. VRAM temperature in millidegree Celsius.
125 125
126 Only supported for particular Intel Xe graphics platforms.126 Only supported for particular Intel Xe graphics platforms.
127
128What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/fan1_input
129Date: March 2025
130KernelVersion: 6.14
131Contact: intel-xe@lists.freedesktop.org
132Description: RO. Fan 1 speed in RPM.
133
134 Only supported for particular Intel Xe graphics platforms.
135
136What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/fan2_input
137Date: March 2025
138KernelVersion: 6.14
139Contact: intel-xe@lists.freedesktop.org
140Description: RO. Fan 2 speed in RPM.
141
142 Only supported for particular Intel Xe graphics platforms.
143
144What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/fan3_input
145Date: March 2025
146KernelVersion: 6.14
147Contact: intel-xe@lists.freedesktop.org
148Description: RO. Fan 3 speed in RPM.
149
150 Only supported for particular Intel Xe graphics platforms.
Documentation/gpu/xe/index.rst+1−0
@@ -25,3 +25,4 @@ DG2, etc is provided to prototype the driver. · 24 unmodified lines
25 xe_debugging25 xe_debugging
26 xe_devcoredump26 xe_devcoredump
27 xe-drm-usage-stats.rst27 xe-drm-usage-stats.rst
28 xe_configfs
Documentation/gpu/xe/xe_configfs.rst+10−0
@@ -0,0 +1,10 @@
1.. SPDX-License-Identifier: GPL-2.0+
2
3.. _xe_configfs:
4
5============
6Xe Configfs
7============
8
9.. kernel-doc:: drivers/gpu/drm/xe/xe_configfs.c
10 :doc: Xe Configfs
Documentation/gpu/xe/xe_pcode.rst+7−0
@@ -12,3 +12,10 @@ Internal API · 11 unmodified lines
12 12
13.. kernel-doc:: drivers/gpu/drm/xe/xe_pcode.c13.. kernel-doc:: drivers/gpu/drm/xe/xe_pcode.c
14 :internal:14 :internal:
15
16==================
17Boot Survivability
18==================
19
20.. kernel-doc:: drivers/gpu/drm/xe/xe_survivability_mode.c
21 :doc: Xe Boot Survivability
drivers/gpu/drm/xe/Kconfig+14−2
@@ -39,7 +39,6 @@ config DRM_XE · 38 unmodified lines
39 select DRM_TTM_HELPER39 select DRM_TTM_HELPER
40 select DRM_EXEC40 select DRM_EXEC
41 select DRM_GPUVM41 select DRM_GPUVM
42 select DRM_GPUSVM if !UML && DEVICE_PRIVATE
43 select DRM_SCHED42 select DRM_SCHED
44 select MMU_NOTIFIER43 select MMU_NOTIFIER
45 select WANT_DEV_COREDUMP44 select WANT_DEV_COREDUMP
@@ -74,9 +73,22 @@ config DRM_XE_DP_TUNNEL · 28 unmodified lines
74 73
75 If in doubt say "Y".74 If in doubt say "Y".
76 75
76config DRM_XE_GPUSVM
77 bool "Enable CPU to GPU address mirroring"
78 depends on DRM_XE
79 depends on !UML
80 depends on DEVICE_PRIVATE
81 default y
82 select DRM_GPUSVM
83 help
84 Enable this option if you want support for CPU to GPU address
85 mirroring.
86
87 If in doubut say "Y".
88
77config DRM_XE_DEVMEM_MIRROR89config DRM_XE_DEVMEM_MIRROR
78 bool "Enable device memory mirror"90 bool "Enable device memory mirror"
79 depends on DRM_XE91 depends on DRM_XE_GPUSVM
80 select GET_FREE_REGION92 select GET_FREE_REGION
81 default y93 default y
82 help94 help
drivers/gpu/drm/xe/Makefile+2−1
@@ -125,12 +125,13 @@ xe-y += xe_bb.o \ · 124 unmodified lines
125 xe_wopcm.o125 xe_wopcm.o
126 126
127xe-$(CONFIG_HMM_MIRROR) += xe_hmm.o127xe-$(CONFIG_HMM_MIRROR) += xe_hmm.o
128xe-$(CONFIG_DRM_GPUSVM) += xe_svm.o128xe-$(CONFIG_DRM_XE_GPUSVM) += xe_svm.o
129 129
130# graphics hardware monitoring (HWMON) support130# graphics hardware monitoring (HWMON) support
131xe-$(CONFIG_HWMON) += xe_hwmon.o131xe-$(CONFIG_HWMON) += xe_hwmon.o
132 132
133xe-$(CONFIG_PERF_EVENTS) += xe_pmu.o133xe-$(CONFIG_PERF_EVENTS) += xe_pmu.o
134xe-$(CONFIG_CONFIGFS_FS) += xe_configfs.o
134 135
135# graphics virtualization (SR-IOV) support136# graphics virtualization (SR-IOV) support
136xe-y += \137xe-y += \
drivers/gpu/drm/xe/abi/guc_actions_abi.h+1−0
@@ -141,6 +141,7 @@ enum xe_guc_action { · 140 unmodified lines
141 XE_GUC_ACTION_CLIENT_SOFT_RESET = 0x5507,141 XE_GUC_ACTION_CLIENT_SOFT_RESET = 0x5507,
142 XE_GUC_ACTION_SET_ENG_UTIL_BUFF = 0x550A,142 XE_GUC_ACTION_SET_ENG_UTIL_BUFF = 0x550A,
143 XE_GUC_ACTION_SET_DEVICE_ENGINE_ACTIVITY_BUFFER = 0x550C,143 XE_GUC_ACTION_SET_DEVICE_ENGINE_ACTIVITY_BUFFER = 0x550C,
144 XE_GUC_ACTION_SET_FUNCTION_ENGINE_ACTIVITY_BUFFER = 0x550D,
144 XE_GUC_ACTION_NOTIFY_MEMORY_CAT_ERROR = 0x6000,145 XE_GUC_ACTION_NOTIFY_MEMORY_CAT_ERROR = 0x6000,
145 XE_GUC_ACTION_REPORT_PAGE_FAULT_REQ_DESC = 0x6002,146 XE_GUC_ACTION_REPORT_PAGE_FAULT_REQ_DESC = 0x6002,
146 XE_GUC_ACTION_PAGE_FAULT_RES_DESC = 0x6003,147 XE_GUC_ACTION_PAGE_FAULT_RES_DESC = 0x6003,
drivers/gpu/drm/xe/abi/guc_klvs_abi.h+1−0
@@ -367,6 +367,7 @@ enum xe_guc_klv_ids { · 366 unmodified lines
367 GUC_WA_KLV_NP_RD_WRITE_TO_CLEAR_RCSM_AT_CGP_LATE_RESTORE = 0x9008,367 GUC_WA_KLV_NP_RD_WRITE_TO_CLEAR_RCSM_AT_CGP_LATE_RESTORE = 0x9008,
368 GUC_WORKAROUND_KLV_ID_BACK_TO_BACK_RCS_ENGINE_RESET = 0x9009,368 GUC_WORKAROUND_KLV_ID_BACK_TO_BACK_RCS_ENGINE_RESET = 0x9009,
369 GUC_WA_KLV_WAKE_POWER_DOMAINS_FOR_OUTBOUND_MMIO = 0x900a,369 GUC_WA_KLV_WAKE_POWER_DOMAINS_FOR_OUTBOUND_MMIO = 0x900a,
370 GUC_WA_KLV_RESET_BB_STACK_PTR_ON_VF_SWITCH = 0x900b,
370};371};
371 372
372#endif373#endif
drivers/gpu/drm/xe/display/intel_fbdev_fb.c+2−2
@@ -45,7 +45,7 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, · 44 unmodified lines
45 NULL, size,45 NULL, size,
46 ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT |46 ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT |
47 XE_BO_FLAG_STOLEN |47 XE_BO_FLAG_STOLEN |
48 XE_BO_FLAG_GGTT | XE_BO_FLAG_PINNED);48 XE_BO_FLAG_GGTT);
49 if (!IS_ERR(obj))49 if (!IS_ERR(obj))
50 drm_info(&xe->drm, "Allocated fbdev into stolen\n");50 drm_info(&xe->drm, "Allocated fbdev into stolen\n");
51 else51 else
@@ -56,7 +56,7 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, · 4 unmodified lines
56 obj = xe_bo_create_pin_map(xe, xe_device_get_root_tile(xe), NULL, size,56 obj = xe_bo_create_pin_map(xe, xe_device_get_root_tile(xe), NULL, size,
57 ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT |57 ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT |
58 XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) |58 XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) |
59 XE_BO_FLAG_GGTT | XE_BO_FLAG_PINNED);59 XE_BO_FLAG_GGTT);
60 }60 }
61 61
62 if (IS_ERR(obj)) {62 if (IS_ERR(obj)) {
drivers/gpu/drm/xe/display/xe_plane_initial.c+1−1
@@ -83,7 +83,7 @@ initial_plane_bo(struct xe_device *xe, · 82 unmodified lines
83 if (plane_config->size == 0)83 if (plane_config->size == 0)
84 return NULL;84 return NULL;
85 85
86 flags = XE_BO_FLAG_PINNED | XE_BO_FLAG_SCANOUT | XE_BO_FLAG_GGTT;86 flags = XE_BO_FLAG_SCANOUT | XE_BO_FLAG_GGTT;
87 87
88 base = round_down(plane_config->base, page_size);88 base = round_down(plane_config->base, page_size);
89 if (IS_DGFX(xe)) {89 if (IS_DGFX(xe)) {
drivers/gpu/drm/xe/instructions/xe_alu_commands.h+79−0
@@ -0,0 +1,79 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright © 2025 Intel Corporation
4 */
5
6#ifndef _XE_ALU_COMMANDS_H_
7#define _XE_ALU_COMMANDS_H_
8
9#include "instructions/xe_instr_defs.h"
10
11/* Instruction Opcodes */
12#define CS_ALU_OPCODE_NOOP 0x000
13#define CS_ALU_OPCODE_FENCE_RD 0x001
14#define CS_ALU_OPCODE_FENCE_WR 0x002
15#define CS_ALU_OPCODE_LOAD 0x080
16#define CS_ALU_OPCODE_LOADINV 0x480
17#define CS_ALU_OPCODE_LOAD0 0x081
18#define CS_ALU_OPCODE_LOAD1 0x481
19#define CS_ALU_OPCODE_LOADIND 0x082
20#define CS_ALU_OPCODE_ADD 0x100
21#define CS_ALU_OPCODE_SUB 0x101
22#define CS_ALU_OPCODE_AND 0x102
23#define CS_ALU_OPCODE_OR 0x103
24#define CS_ALU_OPCODE_XOR 0x104
25#define CS_ALU_OPCODE_SHL 0x105
26#define CS_ALU_OPCODE_SHR 0x106
27#define CS_ALU_OPCODE_SAR 0x107
28#define CS_ALU_OPCODE_STORE 0x180
29#define CS_ALU_OPCODE_STOREINV 0x580
30#define CS_ALU_OPCODE_STOREIND 0x181
31
32/* Instruction Operands */
33#define CS_ALU_OPERAND_REG(n) REG_FIELD_PREP(GENMASK(3, 0), (n))
34#define CS_ALU_OPERAND_REG0 0x0
35#define CS_ALU_OPERAND_REG1 0x1
36#define CS_ALU_OPERAND_REG2 0x2
37#define CS_ALU_OPERAND_REG3 0x3
38#define CS_ALU_OPERAND_REG4 0x4
39#define CS_ALU_OPERAND_REG5 0x5
40#define CS_ALU_OPERAND_REG6 0x6
41#define CS_ALU_OPERAND_REG7 0x7
42#define CS_ALU_OPERAND_REG8 0x8
43#define CS_ALU_OPERAND_REG9 0x9
44#define CS_ALU_OPERAND_REG10 0xa
45#define CS_ALU_OPERAND_REG11 0xb
46#define CS_ALU_OPERAND_REG12 0xc
47#define CS_ALU_OPERAND_REG13 0xd
48#define CS_ALU_OPERAND_REG14 0xe
49#define CS_ALU_OPERAND_REG15 0xf
50#define CS_ALU_OPERAND_SRCA 0x20
51#define CS_ALU_OPERAND_SRCB 0x21
52#define CS_ALU_OPERAND_ACCU 0x31
53#define CS_ALU_OPERAND_ZF 0x32
54#define CS_ALU_OPERAND_CF 0x33
55#define CS_ALU_OPERAND_NA 0 /* N/A operand */
56
57/* Command Streamer ALU Instructions */
58#define CS_ALU_INSTR(opcode, op1, op2) (REG_FIELD_PREP(GENMASK(31, 20), (opcode)) | \
59 REG_FIELD_PREP(GENMASK(19, 10), (op1)) | \
60 REG_FIELD_PREP(GENMASK(9, 0), (op2)))
61
62#define __CS_ALU_INSTR(opcode, op1, op2) CS_ALU_INSTR(CS_ALU_OPCODE_##opcode, \
63 CS_ALU_OPERAND_##op1, \
64 CS_ALU_OPERAND_##op2)
65
66#define CS_ALU_INSTR_NOOP __CS_ALU_INSTR(NOOP, NA, NA)
67#define CS_ALU_INSTR_LOAD(op1, op2) __CS_ALU_INSTR(LOAD, op1, op2)
68#define CS_ALU_INSTR_LOADINV(op1, op2) __CS_ALU_INSTR(LOADINV, op1, op2)
69#define CS_ALU_INSTR_LOAD0(op1) __CS_ALU_INSTR(LOAD0, op1, NA)
70#define CS_ALU_INSTR_LOAD1(op1) __CS_ALU_INSTR(LOAD1, op1, NA)
71#define CS_ALU_INSTR_ADD __CS_ALU_INSTR(ADD, NA, NA)
72#define CS_ALU_INSTR_SUB __CS_ALU_INSTR(SUB, NA, NA)
73#define CS_ALU_INSTR_AND __CS_ALU_INSTR(AND, NA, NA)
74#define CS_ALU_INSTR_OR __CS_ALU_INSTR(OR, NA, NA)
75#define CS_ALU_INSTR_XOR __CS_ALU_INSTR(XOR, NA, NA)
76#define CS_ALU_INSTR_STORE(op1, op2) __CS_ALU_INSTR(STORE, op1, op2)
77#define CS_ALU_INSTR_STOREINV(op1, op2) __CS_ALU_INSTR(STOREINV, op1, op2)
78
79#endif
drivers/gpu/drm/xe/instructions/xe_gfxpipe_commands.h+1−0
@@ -137,6 +137,7 @@ · 136 unmodified lines
137#define CMD_3DSTATE_CLIP_MESH GFXPIPE_3D_CMD(0x0, 0x81)137#define CMD_3DSTATE_CLIP_MESH GFXPIPE_3D_CMD(0x0, 0x81)
138#define CMD_3DSTATE_SBE_MESH GFXPIPE_3D_CMD(0x0, 0x82)138#define CMD_3DSTATE_SBE_MESH GFXPIPE_3D_CMD(0x0, 0x82)
139#define CMD_3DSTATE_CPSIZE_CONTROL_BUFFER GFXPIPE_3D_CMD(0x0, 0x83)139#define CMD_3DSTATE_CPSIZE_CONTROL_BUFFER GFXPIPE_3D_CMD(0x0, 0x83)
140#define CMD_3DSTATE_COARSE_PIXEL GFXPIPE_3D_CMD(0x0, 0x89)
140 141
141#define CMD_3DSTATE_DRAWING_RECTANGLE GFXPIPE_3D_CMD(0x1, 0x0)142#define CMD_3DSTATE_DRAWING_RECTANGLE GFXPIPE_3D_CMD(0x1, 0x0)
142#define CMD_3DSTATE_CHROMA_KEY GFXPIPE_3D_CMD(0x1, 0x4)143#define CMD_3DSTATE_CHROMA_KEY GFXPIPE_3D_CMD(0x1, 0x4)
drivers/gpu/drm/xe/instructions/xe_mi_commands.h+5−0
@@ -32,6 +32,7 @@ · 31 unmodified lines
32#define MI_BATCH_BUFFER_END __MI_INSTR(0xA)32#define MI_BATCH_BUFFER_END __MI_INSTR(0xA)
33#define MI_TOPOLOGY_FILTER __MI_INSTR(0xD)33#define MI_TOPOLOGY_FILTER __MI_INSTR(0xD)
34#define MI_FORCE_WAKEUP __MI_INSTR(0x1D)34#define MI_FORCE_WAKEUP __MI_INSTR(0x1D)
35#define MI_MATH(n) (__MI_INSTR(0x1A) | XE_INSTR_NUM_DW((n) + 1))
35 36
36#define MI_STORE_DATA_IMM __MI_INSTR(0x20)37#define MI_STORE_DATA_IMM __MI_INSTR(0x20)
37#define MI_SDI_GGTT REG_BIT(22)38#define MI_SDI_GGTT REG_BIT(22)
@@ -61,6 +62,10 @@ · 23 unmodified lines
61#define MI_LOAD_REGISTER_MEM (__MI_INSTR(0x29) | XE_INSTR_NUM_DW(4))62#define MI_LOAD_REGISTER_MEM (__MI_INSTR(0x29) | XE_INSTR_NUM_DW(4))
62#define MI_LRM_USE_GGTT REG_BIT(22)63#define MI_LRM_USE_GGTT REG_BIT(22)
63 64
65#define MI_LOAD_REGISTER_REG (__MI_INSTR(0x2a) | XE_INSTR_NUM_DW(3))
66#define MI_LRR_DST_CS_MMIO REG_BIT(19)
67#define MI_LRR_SRC_CS_MMIO REG_BIT(18)
68
64#define MI_COPY_MEM_MEM (__MI_INSTR(0x2e) | XE_INSTR_NUM_DW(5))69#define MI_COPY_MEM_MEM (__MI_INSTR(0x2e) | XE_INSTR_NUM_DW(5))
65#define MI_COPY_MEM_MEM_SRC_GGTT REG_BIT(22)70#define MI_COPY_MEM_MEM_SRC_GGTT REG_BIT(22)
66#define MI_COPY_MEM_MEM_DST_GGTT REG_BIT(21)71#define MI_COPY_MEM_MEM_DST_GGTT REG_BIT(21)
drivers/gpu/drm/xe/regs/xe_engine_regs.h+4−0
@@ -188,6 +188,10 @@ · 187 unmodified lines
188#define PREEMPT_GPGPU_LEVEL_MASK PREEMPT_GPGPU_LEVEL(1, 1)188#define PREEMPT_GPGPU_LEVEL_MASK PREEMPT_GPGPU_LEVEL(1, 1)
189#define PREEMPT_3D_OBJECT_LEVEL REG_BIT(0)189#define PREEMPT_3D_OBJECT_LEVEL REG_BIT(0)
190 190
191#define CS_GPR_DATA(base, n) XE_REG((base) + 0x600 + (n) * 4)
192#define CS_GPR_REG(base, n) CS_GPR_DATA((base), (n) * 2)
193#define CS_GPR_REG_UDW(base, n) CS_GPR_DATA((base), (n) * 2 + 1)
194
191#define VDBOX_CGCTL3F08(base) XE_REG((base) + 0x3f08)195#define VDBOX_CGCTL3F08(base) XE_REG((base) + 0x3f08)
192#define CG3DDISHRS_CLKGATE_DIS REG_BIT(5)196#define CG3DDISHRS_CLKGATE_DIS REG_BIT(5)
193 197
drivers/gpu/drm/xe/regs/xe_gt_regs.h+12−1
@@ -62,7 +62,6 @@ · 61 unmodified lines
62#define LE_SSE_MASK REG_GENMASK(18, 17)62#define LE_SSE_MASK REG_GENMASK(18, 17)
63#define LE_SSE(value) REG_FIELD_PREP(LE_SSE_MASK, value)63#define LE_SSE(value) REG_FIELD_PREP(LE_SSE_MASK, value)
64#define LE_COS_MASK REG_GENMASK(16, 15)64#define LE_COS_MASK REG_GENMASK(16, 15)
65#define LE_COS(value) REG_FIELD_PREP(LE_COS_MASK)
66#define LE_SCF_MASK REG_BIT(14)65#define LE_SCF_MASK REG_BIT(14)
67#define LE_SCF(value) REG_FIELD_PREP(LE_SCF_MASK, value)66#define LE_SCF(value) REG_FIELD_PREP(LE_SCF_MASK, value)
68#define LE_PFM_MASK REG_GENMASK(13, 11)67#define LE_PFM_MASK REG_GENMASK(13, 11)
@@ -392,6 +391,18 @@ · 323 unmodified lines
392#define XEHP_L3NODEARBCFG XE_REG_MCR(0xb0b4)391#define XEHP_L3NODEARBCFG XE_REG_MCR(0xb0b4)
393#define XEHP_LNESPARE REG_BIT(19)392#define XEHP_LNESPARE REG_BIT(19)
394 393
394#define LSN_VC_REG2 XE_REG_MCR(0xb0c8)
395#define LSN_LNI_WGT_MASK REG_GENMASK(31, 28)
396#define LSN_LNI_WGT(value) REG_FIELD_PREP(LSN_LNI_WGT_MASK, value)
397#define LSN_LNE_WGT_MASK REG_GENMASK(27, 24)
398#define LSN_LNE_WGT(value) REG_FIELD_PREP(LSN_LNE_WGT_MASK, value)
399#define LSN_DIM_X_WGT_MASK REG_GENMASK(23, 20)
400#define LSN_DIM_X_WGT(value) REG_FIELD_PREP(LSN_DIM_X_WGT_MASK, value)
401#define LSN_DIM_Y_WGT_MASK REG_GENMASK(19, 16)
402#define LSN_DIM_Y_WGT(value) REG_FIELD_PREP(LSN_DIM_Y_WGT_MASK, value)
403#define LSN_DIM_Z_WGT_MASK REG_GENMASK(15, 12)
404#define LSN_DIM_Z_WGT(value) REG_FIELD_PREP(LSN_DIM_Z_WGT_MASK, value)
405
395#define L3SQCREG2 XE_REG_MCR(0xb104)406#define L3SQCREG2 XE_REG_MCR(0xb104)
396#define COMPMEMRD256BOVRFETCHEN REG_BIT(20)407#define COMPMEMRD256BOVRFETCHEN REG_BIT(20)
397 408
drivers/gpu/drm/xe/regs/xe_pcode_regs.h+3−0
@@ -21,6 +21,9 @@ · 20 unmodified lines
21#define BMG_PACKAGE_POWER_SKU XE_REG(0x138098)21#define BMG_PACKAGE_POWER_SKU XE_REG(0x138098)
22#define BMG_PACKAGE_POWER_SKU_UNIT XE_REG(0x1380dc)22#define BMG_PACKAGE_POWER_SKU_UNIT XE_REG(0x1380dc)
23#define BMG_PACKAGE_ENERGY_STATUS XE_REG(0x138120)23#define BMG_PACKAGE_ENERGY_STATUS XE_REG(0x138120)
24#define BMG_FAN_1_SPEED XE_REG(0x138140)
25#define BMG_FAN_2_SPEED XE_REG(0x138170)
26#define BMG_FAN_3_SPEED XE_REG(0x1381a0)
24#define BMG_VRAM_TEMPERATURE XE_REG(0x1382c0)27#define BMG_VRAM_TEMPERATURE XE_REG(0x1382c0)
25#define BMG_PACKAGE_TEMPERATURE XE_REG(0x138434)28#define BMG_PACKAGE_TEMPERATURE XE_REG(0x138434)
26#define BMG_PACKAGE_RAPL_LIMIT XE_REG(0x138440)29#define BMG_PACKAGE_RAPL_LIMIT XE_REG(0x138440)
drivers/gpu/drm/xe/tests/xe_bo.c+2−2
@@ -252,7 +252,7 @@ static int evict_test_run_tile(struct xe_device *xe, struct xe_tile *tile, struc · 251 unmodified lines
252 252
253 for_each_gt(__gt, xe, id)253 for_each_gt(__gt, xe, id)
254 xe_gt_sanitize(__gt);254 xe_gt_sanitize(__gt);
255 err = xe_bo_restore_kernel(xe);255 err = xe_bo_restore_early(xe);
256 /*256 /*
257 * Snapshotting the CTB and copying back a potentially old257 * Snapshotting the CTB and copying back a potentially old
258 * version seems risky, depending on what might have been258 * version seems risky, depending on what might have been
@@ -273,7 +273,7 @@ static int evict_test_run_tile(struct xe_device *xe, struct xe_tile *tile, struc · 14 unmodified lines
273 goto cleanup_all;273 goto cleanup_all;
274 }274 }
275 275
276 err = xe_bo_restore_user(xe);276 err = xe_bo_restore_late(xe);
277 if (err) {277 if (err) {
278 KUNIT_FAIL(test, "restore user err=%pe\n", ERR_PTR(err));278 KUNIT_FAIL(test, "restore user err=%pe\n", ERR_PTR(err));
279 goto cleanup_all;279 goto cleanup_all;
drivers/gpu/drm/xe/tests/xe_migrate.c+3−6
@@ -202,8 +202,7 @@ static void xe_migrate_sanity_test(struct xe_migrate *m, struct kunit *test) · 201 unmodified lines
202 202
203 big = xe_bo_create_pin_map(xe, tile, m->q->vm, SZ_4M,203 big = xe_bo_create_pin_map(xe, tile, m->q->vm, SZ_4M,
204 ttm_bo_type_kernel,204 ttm_bo_type_kernel,
205 XE_BO_FLAG_VRAM_IF_DGFX(tile) |205 XE_BO_FLAG_VRAM_IF_DGFX(tile));
206 XE_BO_FLAG_PINNED);
207 if (IS_ERR(big)) {206 if (IS_ERR(big)) {
208 KUNIT_FAIL(test, "Failed to allocate bo: %li\n", PTR_ERR(big));207 KUNIT_FAIL(test, "Failed to allocate bo: %li\n", PTR_ERR(big));
209 goto vunmap;208 goto vunmap;
@@ -211,8 +210,7 @@ static void xe_migrate_sanity_test(struct xe_migrate *m, struct kunit *test) · 1 unmodified line
211 210
212 pt = xe_bo_create_pin_map(xe, tile, m->q->vm, XE_PAGE_SIZE,211 pt = xe_bo_create_pin_map(xe, tile, m->q->vm, XE_PAGE_SIZE,
213 ttm_bo_type_kernel,212 ttm_bo_type_kernel,
214 XE_BO_FLAG_VRAM_IF_DGFX(tile) |213 XE_BO_FLAG_VRAM_IF_DGFX(tile));
215 XE_BO_FLAG_PINNED);
216 if (IS_ERR(pt)) {214 if (IS_ERR(pt)) {
217 KUNIT_FAIL(test, "Failed to allocate fake pt: %li\n",215 KUNIT_FAIL(test, "Failed to allocate fake pt: %li\n",
218 PTR_ERR(pt));216 PTR_ERR(pt));
@@ -222,8 +220,7 @@ static void xe_migrate_sanity_test(struct xe_migrate *m, struct kunit *test) · 3 unmodified lines
222 tiny = xe_bo_create_pin_map(xe, tile, m->q->vm,220 tiny = xe_bo_create_pin_map(xe, tile, m->q->vm,
223 2 * SZ_4K,221 2 * SZ_4K,
224 ttm_bo_type_kernel,222 ttm_bo_type_kernel,
225 XE_BO_FLAG_VRAM_IF_DGFX(tile) |223 XE_BO_FLAG_VRAM_IF_DGFX(tile));
226 XE_BO_FLAG_PINNED);
227 if (IS_ERR(tiny)) {224 if (IS_ERR(tiny)) {
228 KUNIT_FAIL(test, "Failed to allocate tiny fake pt: %li\n",225 KUNIT_FAIL(test, "Failed to allocate tiny fake pt: %li\n",
229 PTR_ERR(tiny));226 PTR_ERR(tiny));
drivers/gpu/drm/xe/xe_bo.c+239−164
@@ -55,6 +55,8 @@ static struct ttm_placement sys_placement = { · 54 unmodified lines
55 .placement = &sys_placement_flags,55 .placement = &sys_placement_flags,
56};56};
57 57
58static struct ttm_placement purge_placement;
59
58static const struct ttm_place tt_placement_flags[] = {60static const struct ttm_place tt_placement_flags[] = {
59 {61 {
60 .fpfn = 0,62 .fpfn = 0,
@@ -189,11 +191,18 @@ static void try_add_system(struct xe_device *xe, struct xe_bo *bo, · 128 unmodified lines
189 191
190static bool force_contiguous(u32 bo_flags)192static bool force_contiguous(u32 bo_flags)
191{193{
194 if (bo_flags & XE_BO_FLAG_STOLEN)
195 return true; /* users expect this */
196 else if (bo_flags & XE_BO_FLAG_PINNED &&
197 !(bo_flags & XE_BO_FLAG_PINNED_LATE_RESTORE))
198 return true; /* needs vmap */
199
192 /*200 /*
193 * For eviction / restore on suspend / resume objects pinned in VRAM201 * For eviction / restore on suspend / resume objects pinned in VRAM
194 * must be contiguous, also only contiguous BOs support xe_bo_vmap.202 * must be contiguous, also only contiguous BOs support xe_bo_vmap.
195 */203 */
196 return bo_flags & (XE_BO_FLAG_PINNED | XE_BO_FLAG_GGTT);204 return bo_flags & XE_BO_FLAG_NEEDS_CPU_ACCESS &&
205 bo_flags & XE_BO_FLAG_PINNED;
197}206}
198 207
199static void add_vram(struct xe_device *xe, struct xe_bo *bo,208static void add_vram(struct xe_device *xe, struct xe_bo *bo,
@@ -281,6 +290,8 @@ int xe_bo_placement_for_flags(struct xe_device *xe, struct xe_bo *bo, · 81 unmodified lines
281static void xe_evict_flags(struct ttm_buffer_object *tbo,290static void xe_evict_flags(struct ttm_buffer_object *tbo,
282 struct ttm_placement *placement)291 struct ttm_placement *placement)
283{292{
293 struct xe_device *xe = container_of(tbo->bdev, typeof(*xe), ttm);
294 bool device_unplugged = drm_dev_is_unplugged(&xe->drm);
284 struct xe_bo *bo;295 struct xe_bo *bo;
285 296
286 if (!xe_bo_is_xe_bo(tbo)) {297 if (!xe_bo_is_xe_bo(tbo)) {
@@ -290,7 +301,7 @@ static void xe_evict_flags(struct ttm_buffer_object *tbo, · 3 unmodified lines
290 return;301 return;
291 }302 }
292 303
293 *placement = sys_placement;304 *placement = device_unplugged ? purge_placement : sys_placement;
294 return;305 return;
295 }306 }
296 307
@@ -300,6 +311,11 @@ static void xe_evict_flags(struct ttm_buffer_object *tbo, · 3 unmodified lines
300 return;311 return;
301 }312 }
302 313
314 if (device_unplugged && !tbo->base.dma_buf) {
315 *placement = purge_placement;
316 return;
317 }
318
303 /*319 /*
304 * For xe, sg bos that are evicted to system just triggers a320 * For xe, sg bos that are evicted to system just triggers a
305 * rebind of the sg list upon subsequent validation to XE_PL_TT.321 * rebind of the sg list upon subsequent validation to XE_PL_TT.
@@ -657,11 +673,20 @@ static int xe_bo_move_dmabuf(struct ttm_buffer_object *ttm_bo, · 351 unmodified lines
657 struct xe_ttm_tt *xe_tt = container_of(ttm_bo->ttm, struct xe_ttm_tt,673 struct xe_ttm_tt *xe_tt = container_of(ttm_bo->ttm, struct xe_ttm_tt,
658 ttm);674 ttm);
659 struct xe_device *xe = ttm_to_xe_device(ttm_bo->bdev);675 struct xe_device *xe = ttm_to_xe_device(ttm_bo->bdev);
676 bool device_unplugged = drm_dev_is_unplugged(&xe->drm);
660 struct sg_table *sg;677 struct sg_table *sg;
661 678
662 xe_assert(xe, attach);679 xe_assert(xe, attach);
663 xe_assert(xe, ttm_bo->ttm);680 xe_assert(xe, ttm_bo->ttm);
664 681
682 if (device_unplugged && new_res->mem_type == XE_PL_SYSTEM &&
683 ttm_bo->sg) {
684 dma_resv_wait_timeout(ttm_bo->base.resv, DMA_RESV_USAGE_BOOKKEEP,
685 false, MAX_SCHEDULE_TIMEOUT);
686 dma_buf_unmap_attachment(attach, ttm_bo->sg, DMA_BIDIRECTIONAL);
687 ttm_bo->sg = NULL;
688 }
689
665 if (new_res->mem_type == XE_PL_SYSTEM)690 if (new_res->mem_type == XE_PL_SYSTEM)
666 goto out;691 goto out;
667 692
@@ -898,79 +923,44 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict, · 230 unmodified lines
898 xe_pm_runtime_get_noresume(xe);923 xe_pm_runtime_get_noresume(xe);
899 }924 }
900 925
901 if (xe_bo_is_pinned(bo) && !xe_bo_is_user(bo)) {926 if (move_lacks_source) {
902 /*927 u32 flags = 0;
903 * Kernel memory that is pinned should only be moved on suspend
904 * / resume, some of the pinned memory is required for the
905 * device to resume / use the GPU to move other evicted memory
906 * (user memory) around. This likely could be optimized a bit
907 * further where we find the minimum set of pinned memory
908 * required for resume but for simplity doing a memcpy for all
909 * pinned memory.
910 */
911 ret = xe_bo_vmap(bo);
912 if (!ret) {
913 ret = ttm_bo_move_memcpy(ttm_bo, ctx, new_mem);
914
915 /* Create a new VMAP once kernel BO back in VRAM */
916 if (!ret && resource_is_vram(new_mem)) {
917 struct xe_vram_region *vram = res_to_mem_region(new_mem);
918 void __iomem *new_addr = vram->mapping +
919 (new_mem->start << PAGE_SHIFT);
920
921 if (XE_WARN_ON(new_mem->start == XE_BO_INVALID_OFFSET)) {
922 ret = -EINVAL;
923 xe_pm_runtime_put(xe);
924 goto out;
925 }
926 928
927 xe_assert(xe, new_mem->start ==929 if (mem_type_is_vram(new_mem->mem_type))
928 bo->placements->fpfn);930 flags |= XE_MIGRATE_CLEAR_FLAG_FULL;
931 else if (handle_system_ccs)
932 flags |= XE_MIGRATE_CLEAR_FLAG_CCS_DATA;
929 933
930 iosys_map_set_vaddr_iomem(&bo->vmap, new_addr);934 fence = xe_migrate_clear(migrate, bo, new_mem, flags);
931 }
932 }
933 } else {935 } else {
934 if (move_lacks_source) {936 fence = xe_migrate_copy(migrate, bo, bo, old_mem, new_mem,
935 u32 flags = 0;937 handle_system_ccs);
936 938 }
937 if (mem_type_is_vram(new_mem->mem_type))939 if (IS_ERR(fence)) {
938 flags |= XE_MIGRATE_CLEAR_FLAG_FULL;940 ret = PTR_ERR(fence);
939 else if (handle_system_ccs)941 xe_pm_runtime_put(xe);
940 flags |= XE_MIGRATE_CLEAR_FLAG_CCS_DATA;942 goto out;
941 943 }
942 fence = xe_migrate_clear(migrate, bo, new_mem, flags);944 if (!move_lacks_source) {
943 }945 ret = ttm_bo_move_accel_cleanup(ttm_bo, fence, evict, true,
944 else946 new_mem);
945 fence = xe_migrate_copy(migrate, bo, bo, old_mem,947 if (ret) {
946 new_mem, handle_system_ccs);948 dma_fence_wait(fence, false);
947 if (IS_ERR(fence)) {
948 ret = PTR_ERR(fence);
949 xe_pm_runtime_put(xe);
950 goto out;
951 }
952 if (!move_lacks_source) {
953 ret = ttm_bo_move_accel_cleanup(ttm_bo, fence, evict,
954 true, new_mem);
955 if (ret) {
956 dma_fence_wait(fence, false);
957 ttm_bo_move_null(ttm_bo, new_mem);
958 ret = 0;
959 }
960 } else {
961 /*
962 * ttm_bo_move_accel_cleanup() may blow up if
963 * bo->resource == NULL, so just attach the
964 * fence and set the new resource.
965 */
966 dma_resv_add_fence(ttm_bo->base.resv, fence,
967 DMA_RESV_USAGE_KERNEL);
968 ttm_bo_move_null(ttm_bo, new_mem);949 ttm_bo_move_null(ttm_bo, new_mem);
950 ret = 0;
969 }951 }
970 952 } else {
971 dma_fence_put(fence);953 /*
954 * ttm_bo_move_accel_cleanup() may blow up if
955 * bo->resource == NULL, so just attach the
956 * fence and set the new resource.
957 */
958 dma_resv_add_fence(ttm_bo->base.resv, fence,
959 DMA_RESV_USAGE_KERNEL);
960 ttm_bo_move_null(ttm_bo, new_mem);
972 }961 }
973 962
963 dma_fence_put(fence);
974 xe_pm_runtime_put(xe);964 xe_pm_runtime_put(xe);
975 965
976out:966out:
@@ -1107,59 +1097,93 @@ out_unref: · 130 unmodified lines
1107 */1097 */
1108int xe_bo_evict_pinned(struct xe_bo *bo)1098int xe_bo_evict_pinned(struct xe_bo *bo)
1109{1099{
1110 struct ttm_place place = {1100 struct xe_device *xe = ttm_to_xe_device(bo->ttm.bdev);
1111 .mem_type = XE_PL_TT,1101 struct xe_bo *backup;
1112 };1102 bool unmap = false;
1113 struct ttm_placement placement = {1103 int ret = 0;
1114 .placement = &place,
1115 .num_placement = 1,
1116 };
1117 struct ttm_operation_ctx ctx = {
1118 .interruptible = false,
1119 .gfp_retry_mayfail = true,
1120 };
1121 struct ttm_resource *new_mem;
1122 int ret;
1123 1104
1124 xe_bo_assert_held(bo);1105 xe_bo_lock(bo, false);
1125 1106
1126 if (WARN_ON(!bo->ttm.resource))1107 if (WARN_ON(!bo->ttm.resource)) {
1127 return -EINVAL;1108 ret = -EINVAL;
1109 goto out_unlock_bo;
1110 }
1128 1111
1129 if (WARN_ON(!xe_bo_is_pinned(bo)))1112 if (WARN_ON(!xe_bo_is_pinned(bo))) {
1130 return -EINVAL;1113 ret = -EINVAL;
1114 goto out_unlock_bo;
1115 }
1131 1116
1132 if (!xe_bo_is_vram(bo))1117 if (!xe_bo_is_vram(bo))
1133 return 0;1118 goto out_unlock_bo;
1134 1119
1135 ret = ttm_bo_mem_space(&bo->ttm, &placement, &new_mem, &ctx);1120 if (bo->flags & XE_BO_FLAG_PINNED_NORESTORE)
1136 if (ret)1121 goto out_unlock_bo;
1137 return ret;
1138 1122
1139 if (!bo->ttm.ttm) {1123 backup = xe_bo_create_locked(xe, NULL, NULL, bo->size, ttm_bo_type_kernel,
1140 bo->ttm.ttm = xe_ttm_tt_create(&bo->ttm, 0);1124 XE_BO_FLAG_SYSTEM | XE_BO_FLAG_NEEDS_CPU_ACCESS |
1141 if (!bo->ttm.ttm) {1125 XE_BO_FLAG_PINNED);
1142 ret = -ENOMEM;1126 if (IS_ERR(backup)) {
1143 goto err_res_free;1127 ret = PTR_ERR(backup);
1144 }1128 goto out_unlock_bo;
1145 }1129 }
1146 1130
1147 ret = ttm_bo_populate(&bo->ttm, &ctx);1131 if (xe_bo_is_user(bo) || (bo->flags & XE_BO_FLAG_PINNED_LATE_RESTORE)) {
1148 if (ret)1132 struct xe_migrate *migrate;
1149 goto err_res_free;1133 struct dma_fence *fence;
1150 1134
1151 ret = dma_resv_reserve_fences(bo->ttm.base.resv, 1);1135 if (bo->tile)
1152 if (ret)1136 migrate = bo->tile->migrate;
1153 goto err_res_free;1137 else
1138 migrate = mem_type_to_migrate(xe, bo->ttm.resource->mem_type);
1154 1139
1155 ret = xe_bo_move(&bo->ttm, false, &ctx, new_mem, NULL);1140 ret = dma_resv_reserve_fences(bo->ttm.base.resv, 1);
1156 if (ret)1141 if (ret)
1157 goto err_res_free;1142 goto out_backup;
1158 1143
1159 return 0;1144 ret = dma_resv_reserve_fences(backup->ttm.base.resv, 1);
1145 if (ret)
1146 goto out_backup;
1160 1147
1161err_res_free:1148 fence = xe_migrate_copy(migrate, bo, backup, bo->ttm.resource,
1162 ttm_resource_free(&bo->ttm, &new_mem);1149 backup->ttm.resource, false);
1150 if (IS_ERR(fence)) {
1151 ret = PTR_ERR(fence);
1152 goto out_backup;
1153 }
1154
1155 dma_resv_add_fence(bo->ttm.base.resv, fence,
1156 DMA_RESV_USAGE_KERNEL);
1157 dma_resv_add_fence(backup->ttm.base.resv, fence,
1158 DMA_RESV_USAGE_KERNEL);
1159 dma_fence_put(fence);
1160 } else {
1161 ret = xe_bo_vmap(backup);
1162 if (ret)
1163 goto out_backup;
1164
1165 if (iosys_map_is_null(&bo->vmap)) {
1166 ret = xe_bo_vmap(bo);
1167 if (ret)
1168 goto out_backup;
1169 unmap = true;
1170 }
1171
1172 xe_map_memcpy_from(xe, backup->vmap.vaddr, &bo->vmap, 0,
1173 bo->size);
1174 }
1175
1176 bo->backup_obj = backup;
1177
1178out_backup:
1179 xe_bo_vunmap(backup);
1180 xe_bo_unlock(backup);
1181 if (ret)
1182 xe_bo_put(backup);
1183out_unlock_bo:
1184 if (unmap)
1185 xe_bo_vunmap(bo);
1186 xe_bo_unlock(bo);
1163 return ret;1187 return ret;
1164}1188}
1165 1189
@@ -1180,50 +1204,110 @@ int xe_bo_restore_pinned(struct xe_bo *bo) · 14 unmodified lines
1180 .interruptible = false,1204 .interruptible = false,
1181 .gfp_retry_mayfail = false,1205 .gfp_retry_mayfail = false,
1182 };1206 };
1183 struct ttm_resource *new_mem;1207 struct xe_device *xe = ttm_to_xe_device(bo->ttm.bdev);
1184 struct ttm_place *place = &bo->placements[0];1208 struct xe_bo *backup = bo->backup_obj;
1209 bool unmap = false;
1185 int ret;1210 int ret;
1186 1211
1187 xe_bo_assert_held(bo);1212 if (!backup)
1213 return 0;
1188 1214
1189 if (WARN_ON(!bo->ttm.resource))1215 xe_bo_lock(backup, false);
1190 return -EINVAL;
1191 1216
1192 if (WARN_ON(!xe_bo_is_pinned(bo)))1217 ret = ttm_bo_validate(&backup->ttm, &backup->placement, &ctx);
1193 return -EINVAL;1218 if (ret)
1219 goto out_backup;
1194 1220
1195 if (WARN_ON(xe_bo_is_vram(bo)))1221 if (WARN_ON(!dma_resv_trylock(bo->ttm.base.resv))) {
1196 return -EINVAL;1222 ret = -EBUSY;
1223 goto out_backup;
1224 }
1197 1225
1198 if (WARN_ON(!bo->ttm.ttm && !xe_bo_is_stolen(bo)))1226 if (xe_bo_is_user(bo) || (bo->flags & XE_BO_FLAG_PINNED_LATE_RESTORE)) {
1199 return -EINVAL;1227 struct xe_migrate *migrate;
1228 struct dma_fence *fence;
1200 1229
1201 if (!mem_type_is_vram(place->mem_type))1230 if (bo->tile)
1202 return 0;1231 migrate = bo->tile->migrate;
1232 else
1233 migrate = mem_type_to_migrate(xe, bo->ttm.resource->mem_type);
1203 1234
1204 ret = ttm_bo_mem_space(&bo->ttm, &bo->placement, &new_mem, &ctx);1235 ret = dma_resv_reserve_fences(bo->ttm.base.resv, 1);
1205 if (ret)1236 if (ret)
1206 return ret;1237 goto out_unlock_bo;
1207 1238
1208 ret = ttm_bo_populate(&bo->ttm, &ctx);1239 ret = dma_resv_reserve_fences(backup->ttm.base.resv, 1);
1209 if (ret)1240 if (ret)
1210 goto err_res_free;1241 goto out_unlock_bo;
1211 1242
1212 ret = dma_resv_reserve_fences(bo->ttm.base.resv, 1);1243 fence = xe_migrate_copy(migrate, backup, bo,
1213 if (ret)1244 backup->ttm.resource, bo->ttm.resource,
1214 goto err_res_free;1245 false);
1246 if (IS_ERR(fence)) {
1247 ret = PTR_ERR(fence);
1248 goto out_unlock_bo;
1249 }
1215 1250
1216 ret = xe_bo_move(&bo->ttm, false, &ctx, new_mem, NULL);1251 dma_resv_add_fence(bo->ttm.base.resv, fence,
1217 if (ret)1252 DMA_RESV_USAGE_KERNEL);
1218 goto err_res_free;1253 dma_resv_add_fence(backup->ttm.base.resv, fence,
1254 DMA_RESV_USAGE_KERNEL);
1255 dma_fence_put(fence);
1256 } else {
1257 ret = xe_bo_vmap(backup);
1258 if (ret)
1259 goto out_unlock_bo;
1219 1260
1220 return 0;1261 if (iosys_map_is_null(&bo->vmap)) {
1262 ret = xe_bo_vmap(bo);
1263 if (ret)
1264 goto out_unlock_bo;
1265 unmap = true;
1266 }
1221 1267
1222err_res_free:1268 xe_map_memcpy_to(xe, &bo->vmap, 0, backup->vmap.vaddr,
1223 ttm_resource_free(&bo->ttm, &new_mem);1269 bo->size);
1270 }
1271
1272 bo->backup_obj = NULL;
1273
1274out_unlock_bo:
1275 if (unmap)
1276 xe_bo_vunmap(bo);
1277 xe_bo_unlock(bo);
1278out_backup:
1279 xe_bo_vunmap(backup);
1280 xe_bo_unlock(backup);
1281 if (!bo->backup_obj)
1282 xe_bo_put(backup);
1224 return ret;1283 return ret;
1225}1284}
1226 1285
1286int xe_bo_dma_unmap_pinned(struct xe_bo *bo)
1287{
1288 struct ttm_buffer_object *ttm_bo = &bo->ttm;
1289 struct ttm_tt *tt = ttm_bo->ttm;
1290
1291 if (tt) {
1292 struct xe_ttm_tt *xe_tt = container_of(tt, typeof(*xe_tt), ttm);
1293
1294 if (ttm_bo->type == ttm_bo_type_sg && ttm_bo->sg) {
1295 dma_buf_unmap_attachment(ttm_bo->base.import_attach,
1296 ttm_bo->sg,
1297 DMA_BIDIRECTIONAL);
1298 ttm_bo->sg = NULL;
1299 xe_tt->sg = NULL;
1300 } else if (xe_tt->sg) {
1301 dma_unmap_sgtable(xe_tt->xe->drm.dev, xe_tt->sg,
1302 DMA_BIDIRECTIONAL, 0);
1303 sg_free_table(xe_tt->sg);
1304 xe_tt->sg = NULL;
1305 }
1306 }
1307
1308 return 0;
1309}
1310
1227static unsigned long xe_ttm_io_mem_pfn(struct ttm_buffer_object *ttm_bo,1311static unsigned long xe_ttm_io_mem_pfn(struct ttm_buffer_object *ttm_bo,
1228 unsigned long page_offset)1312 unsigned long page_offset)
1229{1313{
@@ -1947,7 +2031,7 @@ struct xe_bo *xe_bo_create_pin_map_at_aligned(struct xe_device *xe, · 717 unmodified lines
1947 flags |= XE_BO_FLAG_GGTT;2031 flags |= XE_BO_FLAG_GGTT;
1948 2032
1949 bo = xe_bo_create_locked_range(xe, tile, vm, size, start, end, type,2033 bo = xe_bo_create_locked_range(xe, tile, vm, size, start, end, type,
1950 flags | XE_BO_FLAG_NEEDS_CPU_ACCESS,2034 flags | XE_BO_FLAG_NEEDS_CPU_ACCESS | XE_BO_FLAG_PINNED,
1951 alignment);2035 alignment);
1952 if (IS_ERR(bo))2036 if (IS_ERR(bo))
1953 return bo;2037 return bo;
@@ -2049,7 +2133,8 @@ int xe_managed_bo_reinit_in_vram(struct xe_device *xe, struct xe_tile *tile, str · 95 unmodified lines
2049 struct xe_bo *bo;2133 struct xe_bo *bo;
2050 u32 dst_flags = XE_BO_FLAG_VRAM_IF_DGFX(tile) | XE_BO_FLAG_GGTT;2134 u32 dst_flags = XE_BO_FLAG_VRAM_IF_DGFX(tile) | XE_BO_FLAG_GGTT;
2051 2135
2052 dst_flags |= (*src)->flags & XE_BO_FLAG_GGTT_INVALIDATE;2136 dst_flags |= (*src)->flags & (XE_BO_FLAG_GGTT_INVALIDATE |
2137 XE_BO_FLAG_PINNED_NORESTORE);
2053 2138
2054 xe_assert(xe, IS_DGFX(xe));2139 xe_assert(xe, IS_DGFX(xe));
2055 xe_assert(xe, !(*src)->vmap.is_iomem);2140 xe_assert(xe, !(*src)->vmap.is_iomem);
@@ -2073,10 +2158,16 @@ uint64_t vram_region_gpu_offset(struct ttm_resource *res) · 17 unmodified lines
2073{2158{
2074 struct xe_device *xe = ttm_to_xe_device(res->bo->bdev);2159 struct xe_device *xe = ttm_to_xe_device(res->bo->bdev);
2075 2160
2076 if (res->mem_type == XE_PL_STOLEN)2161 switch (res->mem_type) {
2162 case XE_PL_STOLEN:
2077 return xe_ttm_stolen_gpu_offset(xe);2163 return xe_ttm_stolen_gpu_offset(xe);
2078 2164 case XE_PL_TT:
2079 return res_to_mem_region(res)->dpa_base;2165 case XE_PL_SYSTEM:
2166 return 0;
2167 default:
2168 return res_to_mem_region(res)->dpa_base;
2169 }
2170 return 0;
2080}2171}
2081 2172
2082/**2173/**
@@ -2102,12 +2193,9 @@ int xe_bo_pin_external(struct xe_bo *bo) · 19 unmodified lines
2102 if (err)2193 if (err)
2103 return err;2194 return err;
2104 2195
2105 if (xe_bo_is_vram(bo)) {2196 spin_lock(&xe->pinned.lock);
2106 spin_lock(&xe->pinned.lock);2197 list_add_tail(&bo->pinned_link, &xe->pinned.late.external);
2107 list_add_tail(&bo->pinned_link,2198 spin_unlock(&xe->pinned.lock);
2108 &xe->pinned.external_vram);
2109 spin_unlock(&xe->pinned.lock);
2110 }
2111 }2199 }
2112 2200
2113 ttm_bo_pin(&bo->ttm);2201 ttm_bo_pin(&bo->ttm);
@@ -2149,25 +2237,12 @@ int xe_bo_pin(struct xe_bo *bo) · 35 unmodified lines
2149 if (err)2237 if (err)
2150 return err;2238 return err;
2151 2239
2152 /*
2153 * For pinned objects in on DGFX, which are also in vram, we expect
2154 * these to be in contiguous VRAM memory. Required eviction / restore
2155 * during suspend / resume (force restore to same physical address).
2156 */
2157 if (IS_DGFX(xe) && !(IS_ENABLED(CONFIG_DRM_XE_DEBUG) &&
2158 bo->flags & XE_BO_FLAG_INTERNAL_TEST)) {
2159 if (mem_type_is_vram(place->mem_type)) {
2160 xe_assert(xe, place->flags & TTM_PL_FLAG_CONTIGUOUS);
2161
2162 place->fpfn = (xe_bo_addr(bo, 0, PAGE_SIZE) -
2163 vram_region_gpu_offset(bo->ttm.resource)) >> PAGE_SHIFT;
2164 place->lpfn = place->fpfn + (bo->size >> PAGE_SHIFT);
2165 }
2166 }
2167
2168 if (mem_type_is_vram(place->mem_type) || bo->flags & XE_BO_FLAG_GGTT) {2240 if (mem_type_is_vram(place->mem_type) || bo->flags & XE_BO_FLAG_GGTT) {
2169 spin_lock(&xe->pinned.lock);2241 spin_lock(&xe->pinned.lock);
2170 list_add_tail(&bo->pinned_link, &xe->pinned.kernel_bo_present);2242 if (bo->flags & XE_BO_FLAG_PINNED_LATE_RESTORE)
2243 list_add_tail(&bo->pinned_link, &xe->pinned.late.kernel_bo_present);
2244 else
2245 list_add_tail(&bo->pinned_link, &xe->pinned.early.kernel_bo_present);
2171 spin_unlock(&xe->pinned.lock);2246 spin_unlock(&xe->pinned.lock);
2172 }2247 }
2173 2248
drivers/gpu/drm/xe/xe_bo.h+14−9
@@ -39,20 +39,23 @@ · 38 unmodified lines
39#define XE_BO_FLAG_NEEDS_64K BIT(15)39#define XE_BO_FLAG_NEEDS_64K BIT(15)
40#define XE_BO_FLAG_NEEDS_2M BIT(16)40#define XE_BO_FLAG_NEEDS_2M BIT(16)
41#define XE_BO_FLAG_GGTT_INVALIDATE BIT(17)41#define XE_BO_FLAG_GGTT_INVALIDATE BIT(17)
42#define XE_BO_FLAG_GGTT0 BIT(18)42#define XE_BO_FLAG_PINNED_NORESTORE BIT(18)
43#define XE_BO_FLAG_GGTT1 BIT(19)43#define XE_BO_FLAG_PINNED_LATE_RESTORE BIT(19)
44#define XE_BO_FLAG_GGTT2 BIT(20)44#define XE_BO_FLAG_GGTT0 BIT(20)
45#define XE_BO_FLAG_GGTT3 BIT(21)45#define XE_BO_FLAG_GGTT1 BIT(21)
46#define XE_BO_FLAG_GGTT_ALL (XE_BO_FLAG_GGTT0 | \46#define XE_BO_FLAG_GGTT2 BIT(22)
47 XE_BO_FLAG_GGTT1 | \47#define XE_BO_FLAG_GGTT3 BIT(23)
48 XE_BO_FLAG_GGTT2 | \48#define XE_BO_FLAG_CPU_ADDR_MIRROR BIT(24)
49 XE_BO_FLAG_GGTT3)
50#define XE_BO_FLAG_CPU_ADDR_MIRROR BIT(22)
51 49
52/* this one is trigger internally only */50/* this one is trigger internally only */
53#define XE_BO_FLAG_INTERNAL_TEST BIT(30)51#define XE_BO_FLAG_INTERNAL_TEST BIT(30)
54#define XE_BO_FLAG_INTERNAL_64K BIT(31)52#define XE_BO_FLAG_INTERNAL_64K BIT(31)
55 53
54#define XE_BO_FLAG_GGTT_ALL (XE_BO_FLAG_GGTT0 | \
55 XE_BO_FLAG_GGTT1 | \
56 XE_BO_FLAG_GGTT2 | \
57 XE_BO_FLAG_GGTT3)
58
56#define XE_BO_FLAG_GGTTx(tile) \59#define XE_BO_FLAG_GGTTx(tile) \
57 (XE_BO_FLAG_GGTT0 << (tile)->id)60 (XE_BO_FLAG_GGTT0 << (tile)->id)
58 61
@@ -276,6 +279,8 @@ int xe_bo_evict(struct xe_bo *bo); · 217 unmodified lines
276int xe_bo_evict_pinned(struct xe_bo *bo);279int xe_bo_evict_pinned(struct xe_bo *bo);
277int xe_bo_restore_pinned(struct xe_bo *bo);280int xe_bo_restore_pinned(struct xe_bo *bo);
278 281
282int xe_bo_dma_unmap_pinned(struct xe_bo *bo);
283
279extern const struct ttm_device_funcs xe_ttm_funcs;284extern const struct ttm_device_funcs xe_ttm_funcs;
280extern const char *const xe_mem_type_to_name[];285extern const char *const xe_mem_type_to_name[];
281 286
drivers/gpu/drm/xe/xe_bo_evict.c+179−130
@@ -10,6 +10,42 @@ · 9 unmodified lines
10#include "xe_ggtt.h"10#include "xe_ggtt.h"
11#include "xe_tile.h"11#include "xe_tile.h"
12 12
13typedef int (*xe_pinned_fn)(struct xe_bo *bo);
14
15static int xe_bo_apply_to_pinned(struct xe_device *xe,
16 struct list_head *pinned_list,
17 struct list_head *new_list,
18 const xe_pinned_fn pinned_fn)
19{
20 LIST_HEAD(still_in_list);
21 struct xe_bo *bo;
22 int ret = 0;
23
24 spin_lock(&xe->pinned.lock);
25 while (!ret) {
26 bo = list_first_entry_or_null(pinned_list, typeof(*bo),
27 pinned_link);
28 if (!bo)
29 break;
30 xe_bo_get(bo);
31 list_move_tail(&bo->pinned_link, &still_in_list);
32 spin_unlock(&xe->pinned.lock);
33
34 ret = pinned_fn(bo);
35 if (ret && pinned_list != new_list) {
36 spin_lock(&xe->pinned.lock);
37 list_move(&bo->pinned_link, pinned_list);
38 spin_unlock(&xe->pinned.lock);
39 }
40 xe_bo_put(bo);
41 spin_lock(&xe->pinned.lock);
42 }
43 list_splice_tail(&still_in_list, new_list);
44 spin_unlock(&xe->pinned.lock);
45
46 return ret;
47}
48
13/**49/**
14 * xe_bo_evict_all - evict all BOs from VRAM50 * xe_bo_evict_all - evict all BOs from VRAM
15 *51 *
@@ -27,9 +63,7 @@ · 11 unmodified lines
27int xe_bo_evict_all(struct xe_device *xe)63int xe_bo_evict_all(struct xe_device *xe)
28{64{
29 struct ttm_device *bdev = &xe->ttm;65 struct ttm_device *bdev = &xe->ttm;
30 struct xe_bo *bo;
31 struct xe_tile *tile;66 struct xe_tile *tile;
32 struct list_head still_in_list;
33 u32 mem_type;67 u32 mem_type;
34 u8 id;68 u8 id;
35 int ret;69 int ret;
@@ -57,34 +91,13 @@ int xe_bo_evict_all(struct xe_device *xe) · 21 unmodified lines
57 }91 }
58 }92 }
59 93
60 /* Pinned user memory in VRAM */94 ret = xe_bo_apply_to_pinned(xe, &xe->pinned.late.external,
61 INIT_LIST_HEAD(&still_in_list);95 &xe->pinned.late.external,
62 spin_lock(&xe->pinned.lock);96 xe_bo_evict_pinned);
63 for (;;) {
64 bo = list_first_entry_or_null(&xe->pinned.external_vram,
65 typeof(*bo), pinned_link);
66 if (!bo)
67 break;
68 xe_bo_get(bo);
69 list_move_tail(&bo->pinned_link, &still_in_list);
70 spin_unlock(&xe->pinned.lock);
71
72 xe_bo_lock(bo, false);
73 ret = xe_bo_evict_pinned(bo);
74 xe_bo_unlock(bo);
75 xe_bo_put(bo);
76 if (ret) {
77 spin_lock(&xe->pinned.lock);
78 list_splice_tail(&still_in_list,
79 &xe->pinned.external_vram);
80 spin_unlock(&xe->pinned.lock);
81 return ret;
82 }
83 97
84 spin_lock(&xe->pinned.lock);98 if (!ret)
85 }99 ret = xe_bo_apply_to_pinned(xe, &xe->pinned.late.kernel_bo_present,
86 list_splice_tail(&still_in_list, &xe->pinned.external_vram);100 &xe->pinned.late.evicted, xe_bo_evict_pinned);
87 spin_unlock(&xe->pinned.lock);
88 101
89 /*102 /*
90 * Wait for all user BO to be evicted as those evictions depend on the103 * Wait for all user BO to be evicted as those evictions depend on the
@@ -93,32 +106,49 @@ int xe_bo_evict_all(struct xe_device *xe) · 2 unmodified lines
93 for_each_tile(tile, xe, id)106 for_each_tile(tile, xe, id)
94 xe_tile_migrate_wait(tile);107 xe_tile_migrate_wait(tile);
95 108
96 spin_lock(&xe->pinned.lock);109 if (ret)
97 for (;;) {110 return ret;
98 bo = list_first_entry_or_null(&xe->pinned.kernel_bo_present,
99 typeof(*bo), pinned_link);
100 if (!bo)
101 break;
102 xe_bo_get(bo);
103 list_move_tail(&bo->pinned_link, &xe->pinned.evicted);
104 spin_unlock(&xe->pinned.lock);
105 111
106 xe_bo_lock(bo, false);112 return xe_bo_apply_to_pinned(xe, &xe->pinned.early.kernel_bo_present,
107 ret = xe_bo_evict_pinned(bo);113 &xe->pinned.early.evicted,
108 xe_bo_unlock(bo);114 xe_bo_evict_pinned);
109 xe_bo_put(bo);115}
110 if (ret)
111 return ret;
112 116
113 spin_lock(&xe->pinned.lock);117static int xe_bo_restore_and_map_ggtt(struct xe_bo *bo)
118{
119 struct xe_device *xe = xe_bo_device(bo);
120 int ret;
121
122 ret = xe_bo_restore_pinned(bo);
123 if (ret)
124 return ret;
125
126 if (bo->flags & XE_BO_FLAG_GGTT) {
127 struct xe_tile *tile;
128 u8 id;
129
130 for_each_tile(tile, xe_bo_device(bo), id) {
131 if (tile != bo->tile && !(bo->flags & XE_BO_FLAG_GGTTx(tile)))
132 continue;
133
134 mutex_lock(&tile->mem.ggtt->lock);
135 xe_ggtt_map_bo(tile->mem.ggtt, bo);
136 mutex_unlock(&tile->mem.ggtt->lock);
137 }
114 }138 }
115 spin_unlock(&xe->pinned.lock);139
140 /*
141 * We expect validate to trigger a move VRAM and our move code
142 * should setup the iosys map.
143 */
144 xe_assert(xe, !(bo->flags & XE_BO_FLAG_PINNED_LATE_RESTORE) ||
145 !iosys_map_is_null(&bo->vmap));
116 146
117 return 0;147 return 0;
118}148}
119 149
120/**150/**
121 * xe_bo_restore_kernel - restore kernel BOs to VRAM151 * xe_bo_restore_early - restore early phase kernel BOs to VRAM
122 *152 *
123 * @xe: xe device153 * @xe: xe device
124 *154 *
@@ -128,111 +158,130 @@ int xe_bo_evict_all(struct xe_device *xe) · 3 unmodified lines
128 * This function should be called early, before trying to init the GT, on device158 * This function should be called early, before trying to init the GT, on device
129 * resume.159 * resume.
130 */160 */
131int xe_bo_restore_kernel(struct xe_device *xe)161int xe_bo_restore_early(struct xe_device *xe)
132{162{
133 struct xe_bo *bo;163 return xe_bo_apply_to_pinned(xe, &xe->pinned.early.evicted,
134 int ret;164 &xe->pinned.early.kernel_bo_present,
165 xe_bo_restore_and_map_ggtt);
166}
135 167
136 spin_lock(&xe->pinned.lock);168/**
137 for (;;) {169 * xe_bo_restore_late - restore pinned late phase BOs
138 bo = list_first_entry_or_null(&xe->pinned.evicted,170 *
139 typeof(*bo), pinned_link);171 * @xe: xe device
140 if (!bo)172 *
141 break;173 * Move pinned user and kernel BOs which can use blitter from temporary
142 xe_bo_get(bo);174 * (typically system) memory to VRAM. All moves done via TTM calls.
143 list_move_tail(&bo->pinned_link, &xe->pinned.kernel_bo_present);175 *
144 spin_unlock(&xe->pinned.lock);176 * This function should be called late, after GT init, on device resume.
177 */
178int xe_bo_restore_late(struct xe_device *xe)
179{
180 struct xe_tile *tile;
181 int ret, id;
145 182
146 xe_bo_lock(bo, false);183 ret = xe_bo_apply_to_pinned(xe, &xe->pinned.late.evicted,
147 ret = xe_bo_restore_pinned(bo);184 &xe->pinned.late.kernel_bo_present,
148 xe_bo_unlock(bo);185 xe_bo_restore_and_map_ggtt);
149 if (ret) {
150 xe_bo_put(bo);
151 return ret;
152 }
153 186
154 if (bo->flags & XE_BO_FLAG_GGTT) {187 for_each_tile(tile, xe, id)
155 struct xe_tile *tile;188 xe_tile_migrate_wait(tile);
156 u8 id;
157 189
158 for_each_tile(tile, xe, id) {190 if (ret)
159 if (tile != bo->tile && !(bo->flags & XE_BO_FLAG_GGTTx(tile)))191 return ret;
160 continue;
161 192
162 mutex_lock(&tile->mem.ggtt->lock);193 if (!IS_DGFX(xe))
163 xe_ggtt_map_bo(tile->mem.ggtt, bo);194 return 0;
164 mutex_unlock(&tile->mem.ggtt->lock);
165 }
166 }
167 195
168 /*196 /* Pinned user memory in VRAM should be validated on resume */
169 * We expect validate to trigger a move VRAM and our move code197 ret = xe_bo_apply_to_pinned(xe, &xe->pinned.late.external,
170 * should setup the iosys map.198 &xe->pinned.late.external,
171 */199 xe_bo_restore_pinned);
172 xe_assert(xe, !iosys_map_is_null(&bo->vmap));
173 200
174 xe_bo_put(bo);201 /* Wait for restore to complete */
202 for_each_tile(tile, xe, id)
203 xe_tile_migrate_wait(tile);
175 204
176 spin_lock(&xe->pinned.lock);205 return ret;
177 }206}
178 spin_unlock(&xe->pinned.lock);
179 207
180 return 0;208static void xe_bo_pci_dev_remove_pinned(struct xe_device *xe)
209{
210 struct xe_tile *tile;
211 unsigned int id;
212
213 (void)xe_bo_apply_to_pinned(xe, &xe->pinned.late.external,
214 &xe->pinned.late.external,
215 xe_bo_dma_unmap_pinned);
216 for_each_tile(tile, xe, id)
217 xe_tile_migrate_wait(tile);
181}218}
182 219
183/**220/**
184 * xe_bo_restore_user - restore pinned user BOs to VRAM221 * xe_bo_pci_dev_remove_all() - Handle bos when the pci_device is about to be removed
185 *222 * @xe: The xe device.
186 * @xe: xe device
187 *223 *
188 * Move pinned user BOs from temporary (typically system) memory to VRAM via224 * On pci_device removal we need to drop all dma mappings and move
189 * CPU. All moves done via TTM calls.225 * the data of exported bos out to system. This includes SVM bos and
226 * exported dma-buf bos. This is done by evicting all bos, but
227 * the evict placement in xe_evict_flags() is chosen such that all
228 * bos except those mentioned are purged, and thus their memory
229 * is released.
190 *230 *
191 * This function should be called late, after GT init, on device resume.231 * For pinned bos, we're unmapping dma.
192 */232 */
193int xe_bo_restore_user(struct xe_device *xe)233void xe_bo_pci_dev_remove_all(struct xe_device *xe)
194{234{
195 struct xe_bo *bo;235 unsigned int mem_type;
196 struct xe_tile *tile;
197 struct list_head still_in_list;
198 u8 id;
199 int ret;
200 236
201 if (!IS_DGFX(xe))237 /*
202 return 0;238 * Move pagemap bos and exported dma-buf to system, and
239 * purge everything else.
240 */
241 for (mem_type = XE_PL_VRAM1; mem_type >= XE_PL_TT; --mem_type) {
242 struct ttm_resource_manager *man =
243 ttm_manager_type(&xe->ttm, mem_type);
203 244
204 /* Pinned user memory in VRAM should be validated on resume */245 if (man) {
205 INIT_LIST_HEAD(&still_in_list);246 int ret = ttm_resource_manager_evict_all(&xe->ttm, man);
206 spin_lock(&xe->pinned.lock);
207 for (;;) {
208 bo = list_first_entry_or_null(&xe->pinned.external_vram,
209 typeof(*bo), pinned_link);
210 if (!bo)
211 break;
212 list_move_tail(&bo->pinned_link, &still_in_list);
213 xe_bo_get(bo);
214 spin_unlock(&xe->pinned.lock);
215 247
216 xe_bo_lock(bo, false);248 drm_WARN_ON(&xe->drm, ret);
217 ret = xe_bo_restore_pinned(bo);
218 xe_bo_unlock(bo);
219 xe_bo_put(bo);
220 if (ret) {
221 spin_lock(&xe->pinned.lock);
222 list_splice_tail(&still_in_list,
223 &xe->pinned.external_vram);
224 spin_unlock(&xe->pinned.lock);
225 return ret;
226 }249 }
227
228 spin_lock(&xe->pinned.lock);
229 }250 }
230 list_splice_tail(&still_in_list, &xe->pinned.external_vram);
231 spin_unlock(&xe->pinned.lock);
232 251
233 /* Wait for restore to complete */252 xe_bo_pci_dev_remove_pinned(xe);
234 for_each_tile(tile, xe, id)253}
235 xe_tile_migrate_wait(tile);
236 254
237 return 0;255static void xe_bo_pinned_fini(void *arg)
256{
257 struct xe_device *xe = arg;
258
259 (void)xe_bo_apply_to_pinned(xe, &xe->pinned.late.kernel_bo_present,
260 &xe->pinned.late.kernel_bo_present,
261 xe_bo_dma_unmap_pinned);
262 (void)xe_bo_apply_to_pinned(xe, &xe->pinned.early.kernel_bo_present,
263 &xe->pinned.early.kernel_bo_present,
264 xe_bo_dma_unmap_pinned);
265}
266
267/**
268 * xe_bo_pinned_init() - Initialize pinned bo tracking
269 * @xe: The xe device.
270 *
271 * Initializes the lists and locks required for pinned bo
272 * tracking and registers a callback to dma-unmap
273 * any remaining pinned bos on pci device removal.
274 *
275 * Return: %0 on success, negative error code on error.
276 */
277int xe_bo_pinned_init(struct xe_device *xe)
278{
279 spin_lock_init(&xe->pinned.lock);
280 INIT_LIST_HEAD(&xe->pinned.early.kernel_bo_present);
281 INIT_LIST_HEAD(&xe->pinned.early.evicted);
282 INIT_LIST_HEAD(&xe->pinned.late.kernel_bo_present);
283 INIT_LIST_HEAD(&xe->pinned.late.evicted);
284 INIT_LIST_HEAD(&xe->pinned.late.external);
285
286 return devm_add_action_or_reset(xe->drm.dev, xe_bo_pinned_fini, xe);
238}287}
drivers/gpu/drm/xe/xe_bo_evict.h+5−2
@@ -9,7 +9,10 @@ · 8 unmodified lines
9struct xe_device;9struct xe_device;
10 10
11int xe_bo_evict_all(struct xe_device *xe);11int xe_bo_evict_all(struct xe_device *xe);
12int xe_bo_restore_kernel(struct xe_device *xe);12int xe_bo_restore_early(struct xe_device *xe);
13int xe_bo_restore_user(struct xe_device *xe);13int xe_bo_restore_late(struct xe_device *xe);
14 14
15void xe_bo_pci_dev_remove_all(struct xe_device *xe);
16
17int xe_bo_pinned_init(struct xe_device *xe);
15#endif18#endif
drivers/gpu/drm/xe/xe_bo_types.h+2−0
@@ -28,6 +28,8 @@ struct xe_vm; · 27 unmodified lines
28struct xe_bo {28struct xe_bo {
29 /** @ttm: TTM base buffer object */29 /** @ttm: TTM base buffer object */
30 struct ttm_buffer_object ttm;30 struct ttm_buffer_object ttm;
31 /** @backup_obj: The backup object when pinned and suspended (vram only) */
32 struct xe_bo *backup_obj;
31 /** @size: Size of this buffer object */33 /** @size: Size of this buffer object */
32 size_t size;34 size_t size;
33 /** @flags: flags for this buffer object */35 /** @flags: flags for this buffer object */
drivers/gpu/drm/xe/xe_configfs.c+250−0
@@ -0,0 +1,250 @@
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright © 2025 Intel Corporation
4 */
5
6#include <linux/configfs.h>
7#include <linux/init.h>
8#include <linux/module.h>
9#include <linux/pci.h>
10
11#include "xe_configfs.h"
12#include "xe_module.h"
13
14/**
15 * DOC: Xe Configfs
16 *
17 * Overview
18 * =========
19 *
20 * Configfs is a filesystem-based manager of kernel objects. XE KMD registers a
21 * configfs subsystem called ``'xe'`` that creates a directory in the mounted configfs directory
22 * The user can create devices under this directory and configure them as necessary
23 * See Documentation/filesystems/configfs.rst for more information about how configfs works.
24 *
25 * Create devices
26 * ===============
27 *
28 * In order to create a device, the user has to create a directory inside ``'xe'``::
29 *
30 * mkdir /sys/kernel/config/xe/0000:03:00.0/
31 *
32 * Every device created is populated by the driver with entries that can be
33 * used to configure it::
34 *
35 * /sys/kernel/config/xe/
36 * .. 0000:03:00.0/
37 * ... survivability_mode
38 *
39 * Configure Attributes
40 * ====================
41 *
42 * Survivability mode:
43 * -------------------
44 *
45 * Enable survivability mode on supported cards. This setting only takes
46 * effect when probing the device. Example to enable it::
47 *
48 * # echo 1 > /sys/kernel/config/xe/0000:03:00.0/survivability_mode
49 * # echo 0000:03:00.0 > /sys/bus/pci/drivers/xe/bind (Enters survivability mode if supported)
50 *
51 * Remove devices
52 * ==============
53 *
54 * The created device directories can be removed using ``rmdir``::
55 *
56 * rmdir /sys/kernel/config/xe/0000:03:00.0/
57 */
58
59struct xe_config_device {
60 struct config_group group;
61
62 bool survivability_mode;
63
64 /* protects attributes */
65 struct mutex lock;
66};
67
68static struct xe_config_device *to_xe_config_device(struct config_item *item)
69{
70 return container_of(to_config_group(item), struct xe_config_device, group);
71}
72
73static ssize_t survivability_mode_show(struct config_item *item, char *page)
74{
75 struct xe_config_device *dev = to_xe_config_device(item);
76
77 return sprintf(page, "%d\n", dev->survivability_mode);
78}
79
80static ssize_t survivability_mode_store(struct config_item *item, const char *page, size_t len)
81{
82 struct xe_config_device *dev = to_xe_config_device(item);
83 bool survivability_mode;
84 int ret;
85
86 ret = kstrtobool(page, &survivability_mode);
87 if (ret)
88 return ret;
89
90 mutex_lock(&dev->lock);
91 dev->survivability_mode = survivability_mode;
92 mutex_unlock(&dev->lock);
93
94 return len;
95}
96
97CONFIGFS_ATTR(, survivability_mode);
98
99static struct configfs_attribute *xe_config_device_attrs[] = {
100 &attr_survivability_mode,
101 NULL,
102};
103
104static void xe_config_device_release(struct config_item *item)
105{
106 struct xe_config_device *dev = to_xe_config_device(item);
107
108 mutex_destroy(&dev->lock);
109 kfree(dev);
110}
111
112static struct configfs_item_operations xe_config_device_ops = {
113 .release = xe_config_device_release,
114};
115
116static const struct config_item_type xe_config_device_type = {
117 .ct_item_ops = &xe_config_device_ops,
118 .ct_attrs = xe_config_device_attrs,
119 .ct_owner = THIS_MODULE,
120};
121
122static struct config_group *xe_config_make_device_group(struct config_group *group,
123 const char *name)
124{
125 unsigned int domain, bus, slot, function;
126 struct xe_config_device *dev;
127 struct pci_dev *pdev;
128 int ret;
129
130 ret = sscanf(name, "%04x:%02x:%02x.%x", &domain, &bus, &slot, &function);
131 if (ret != 4)
132 return ERR_PTR(-EINVAL);
133
134 pdev = pci_get_domain_bus_and_slot(domain, bus, PCI_DEVFN(slot, function));
135 if (!pdev)
136 return ERR_PTR(-EINVAL);
137
138 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
139 if (!dev)
140 return ERR_PTR(-ENOMEM);
141
142 config_group_init_type_name(&dev->group, name, &xe_config_device_type);
143
144 mutex_init(&dev->lock);
145
146 return &dev->group;
147}
148
149static struct configfs_group_operations xe_config_device_group_ops = {
150 .make_group = xe_config_make_device_group,
151};
152
153static const struct config_item_type xe_configfs_type = {
154 .ct_group_ops = &xe_config_device_group_ops,
155 .ct_owner = THIS_MODULE,
156};
157
158static struct configfs_subsystem xe_configfs = {
159 .su_group = {
160 .cg_item = {
161 .ci_namebuf = "xe",
162 .ci_type = &xe_configfs_type,
163 },
164 },
165};
166
167static struct xe_config_device *configfs_find_group(struct pci_dev *pdev)
168{
169 struct config_item *item;
170 char name[64];
171
172 snprintf(name, sizeof(name), "%04x:%02x:%02x.%x", pci_domain_nr(pdev->bus),
173 pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
174
175 mutex_lock(&xe_configfs.su_mutex);
176 item = config_group_find_item(&xe_configfs.su_group, name);
177 mutex_unlock(&xe_configfs.su_mutex);
178
179 if (!item)
180 return NULL;
181
182 return to_xe_config_device(item);
183}
184
185/**
186 * xe_configfs_get_survivability_mode - get configfs survivability mode attribute
187 * @pdev: pci device
188 *
189 * find the configfs group that belongs to the pci device and return
190 * the survivability mode attribute
191 *
192 * Return: survivability mode if config group is found, false otherwise
193 */
194bool xe_configfs_get_survivability_mode(struct pci_dev *pdev)
195{
196 struct xe_config_device *dev = configfs_find_group(pdev);
197 bool mode;
198
199 if (!dev)
200 return false;
201
202 mode = dev->survivability_mode;
203 config_item_put(&dev->group.cg_item);
204
205 return mode;
206}
207
208/**
209 * xe_configfs_clear_survivability_mode - clear configfs survivability mode attribute
210 * @pdev: pci device
211 *
212 * find the configfs group that belongs to the pci device and clear survivability
213 * mode attribute
214 */
215void xe_configfs_clear_survivability_mode(struct pci_dev *pdev)
216{
217 struct xe_config_device *dev = configfs_find_group(pdev);
218
219 if (!dev)
220 return;
221
222 mutex_lock(&dev->lock);
223 dev->survivability_mode = 0;
224 mutex_unlock(&dev->lock);
225
226 config_item_put(&dev->group.cg_item);
227}
228
229int __init xe_configfs_init(void)
230{
231 struct config_group *root = &xe_configfs.su_group;
232 int ret;
233
234 config_group_init(root);
235 mutex_init(&xe_configfs.su_mutex);
236 ret = configfs_register_subsystem(&xe_configfs);
237 if (ret) {
238 pr_err("Error %d while registering %s subsystem\n",
239 ret, root->cg_item.ci_namebuf);
240 return ret;
241 }
242
243 return 0;
244}
245
246void __exit xe_configfs_exit(void)
247{
248 configfs_unregister_subsystem(&xe_configfs);
249}
250
drivers/gpu/drm/xe/xe_configfs.h+24−0
@@ -0,0 +1,24 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright © 2025 Intel Corporation
4 */
5#ifndef _XE_CONFIGFS_H_
6#define _XE_CONFIGFS_H_
7
8#include <linux/types.h>
9
10struct pci_dev;
11
12#if IS_ENABLED(CONFIG_CONFIGFS_FS)
13int xe_configfs_init(void);
14void xe_configfs_exit(void);
15bool xe_configfs_get_survivability_mode(struct pci_dev *pdev);
16void xe_configfs_clear_survivability_mode(struct pci_dev *pdev);
17#else
18static inline int xe_configfs_init(void) { return 0; };
19static inline void xe_configfs_exit(void) {};
20static inline bool xe_configfs_get_survivability_mode(struct pci_dev *pdev) { return false; };
21static inline void xe_configfs_clear_survivability_mode(struct pci_dev *pdev) {};
22#endif
23
24#endif
drivers/gpu/drm/xe/xe_device.c+19−10
@@ -23,6 +23,7 @@ · 22 unmodified lines
23#include "regs/xe_gt_regs.h"23#include "regs/xe_gt_regs.h"
24#include "regs/xe_regs.h"24#include "regs/xe_regs.h"
25#include "xe_bo.h"25#include "xe_bo.h"
26#include "xe_bo_evict.h"
26#include "xe_debugfs.h"27#include "xe_debugfs.h"
27#include "xe_devcoredump.h"28#include "xe_devcoredump.h"
28#include "xe_dma_buf.h"29#include "xe_dma_buf.h"
@@ -467,10 +468,9 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, · 438 unmodified lines
467 xa_erase(&xe->usm.asid_to_vm, asid);468 xa_erase(&xe->usm.asid_to_vm, asid);
468 }469 }
469 470
470 spin_lock_init(&xe->pinned.lock);471 err = xe_bo_pinned_init(xe);
471 INIT_LIST_HEAD(&xe->pinned.kernel_bo_present);472 if (err)
472 INIT_LIST_HEAD(&xe->pinned.external_vram);473 goto err;
473 INIT_LIST_HEAD(&xe->pinned.evicted);
474 474
475 xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq",475 xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq",
476 WQ_MEM_RECLAIM);476 WQ_MEM_RECLAIM);
@@ -505,7 +505,15 @@ ALLOW_ERROR_INJECTION(xe_device_create, ERRNO); /* See xe_pci_probe() */ · 28 unmodified lines
505 505
506static bool xe_driver_flr_disabled(struct xe_device *xe)506static bool xe_driver_flr_disabled(struct xe_device *xe)
507{507{
508 return xe_mmio_read32(xe_root_tile_mmio(xe), GU_CNTL_PROTECTED) & DRIVERINT_FLR_DIS;508 if (IS_SRIOV_VF(xe))
509 return true;
510
511 if (xe_mmio_read32(xe_root_tile_mmio(xe), GU_CNTL_PROTECTED) & DRIVERINT_FLR_DIS) {
512 drm_info(&xe->drm, "Driver-FLR disabled by BIOS\n");
513 return true;
514 }
515
516 return false;
509}517}
510 518
511/*519/*
@@ -523,7 +531,7 @@ static bool xe_driver_flr_disabled(struct xe_device *xe) · 11 unmodified lines
523 */531 */
524static void __xe_driver_flr(struct xe_device *xe)532static void __xe_driver_flr(struct xe_device *xe)
525{533{
526 const unsigned int flr_timeout = 3 * MICRO; /* specs recommend a 3s wait */534 const unsigned int flr_timeout = 3 * USEC_PER_SEC; /* specs recommend a 3s wait */
527 struct xe_mmio *mmio = xe_root_tile_mmio(xe);535 struct xe_mmio *mmio = xe_root_tile_mmio(xe);
528 int ret;536 int ret;
529 537
@@ -569,10 +577,8 @@ static void __xe_driver_flr(struct xe_device *xe) · 39 unmodified lines
569 577
570static void xe_driver_flr(struct xe_device *xe)578static void xe_driver_flr(struct xe_device *xe)
571{579{
572 if (xe_driver_flr_disabled(xe)) {580 if (xe_driver_flr_disabled(xe))
573 drm_info_once(&xe->drm, "BIOS Disabled Driver-FLR\n");
574 return;581 return;
575 }
576 582
577 __xe_driver_flr(xe);583 __xe_driver_flr(xe);
578}584}
@@ -706,7 +712,7 @@ int xe_device_probe_early(struct xe_device *xe) · 127 unmodified lines
706 sriov_update_device_info(xe);712 sriov_update_device_info(xe);
707 713
708 err = xe_pcode_probe_early(xe);714 err = xe_pcode_probe_early(xe);
709 if (err) {715 if (err || xe_survivability_mode_is_requested(xe)) {
710 int save_err = err;716 int save_err = err;
711 717
712 /*718 /*
@@ -729,6 +735,7 @@ int xe_device_probe_early(struct xe_device *xe) · 16 unmodified lines
729 735
730 return 0;736 return 0;
731}737}
738ALLOW_ERROR_INJECTION(xe_device_probe_early, ERRNO); /* See xe_pci_probe() */
732 739
733static int probe_has_flat_ccs(struct xe_device *xe)740static int probe_has_flat_ccs(struct xe_device *xe)
734{741{
@@ -932,6 +939,8 @@ void xe_device_remove(struct xe_device *xe) · 197 unmodified lines
932 xe_display_unregister(xe);939 xe_display_unregister(xe);
933 940
934 drm_dev_unplug(&xe->drm);941 drm_dev_unplug(&xe->drm);
942
943 xe_bo_pci_dev_remove_all(xe);
935}944}
936 945
937void xe_device_shutdown(struct xe_device *xe)946void xe_device_shutdown(struct xe_device *xe)
drivers/gpu/drm/xe/xe_device_types.h+24−8
@@ -107,6 +107,9 @@ struct xe_vram_region { · 106 unmodified lines
107 resource_size_t actual_physical_size;107 resource_size_t actual_physical_size;
108 /** @mapping: pointer to VRAM mappable space */108 /** @mapping: pointer to VRAM mappable space */
109 void __iomem *mapping;109 void __iomem *mapping;
110 /** @ttm: VRAM TTM manager */
111 struct xe_ttm_vram_mgr ttm;
112#if IS_ENABLED(CONFIG_DRM_XE_DEVMEM_MIRROR)
110 /** @pagemap: Used to remap device memory as ZONE_DEVICE */113 /** @pagemap: Used to remap device memory as ZONE_DEVICE */
111 struct dev_pagemap pagemap;114 struct dev_pagemap pagemap;
112 /**115 /**
@@ -120,8 +123,7 @@ struct xe_vram_region { · 7 unmodified lines
120 * This is generated when remap device memory as ZONE_DEVICE123 * This is generated when remap device memory as ZONE_DEVICE
121 */124 */
122 resource_size_t hpa_base;125 resource_size_t hpa_base;
123 /** @ttm: VRAM TTM manager */126#endif
124 struct xe_ttm_vram_mgr ttm;
125};127};
126 128
127/**129/**
@@ -314,6 +316,8 @@ struct xe_device { · 186 unmodified lines
314 u8 has_atomic_enable_pte_bit:1;316 u8 has_atomic_enable_pte_bit:1;
315 /** @info.has_device_atomics_on_smem: Supports device atomics on SMEM */317 /** @info.has_device_atomics_on_smem: Supports device atomics on SMEM */
316 u8 has_device_atomics_on_smem:1;318 u8 has_device_atomics_on_smem:1;
319 /** @info.has_fan_control: Device supports fan control */
320 u8 has_fan_control:1;
317 /** @info.has_flat_ccs: Whether flat CCS metadata is used */321 /** @info.has_flat_ccs: Whether flat CCS metadata is used */
318 u8 has_flat_ccs:1;322 u8 has_flat_ccs:1;
319 /** @info.has_heci_cscfi: device has heci cscfi */323 /** @info.has_heci_cscfi: device has heci cscfi */
@@ -332,6 +336,8 @@ struct xe_device { · 12 unmodified lines
332 u8 has_usm:1;336 u8 has_usm:1;
333 /** @info.is_dgfx: is discrete device */337 /** @info.is_dgfx: is discrete device */
334 u8 is_dgfx:1;338 u8 is_dgfx:1;
339 /** @info.needs_scratch: needs scratch page for oob prefetch to work */
340 u8 needs_scratch:1;
335 /**341 /**
336 * @info.probe_display: Probe display hardware. If set to342 * @info.probe_display: Probe display hardware. If set to
337 * false, the driver will behave as if there is no display343 * false, the driver will behave as if there is no display
@@ -418,12 +424,22 @@ struct xe_device { · 80 unmodified lines
418 struct {424 struct {
419 /** @pinned.lock: protected pinned BO list state */425 /** @pinned.lock: protected pinned BO list state */
420 spinlock_t lock;426 spinlock_t lock;
421 /** @pinned.kernel_bo_present: pinned kernel BO that are present */427 /** @pinned.early: early pinned lists */
422 struct list_head kernel_bo_present;428 struct {
423 /** @pinned.evicted: pinned BO that have been evicted */429 /** @pinned.early.kernel_bo_present: pinned kernel BO that are present */
424 struct list_head evicted;430 struct list_head kernel_bo_present;
425 /** @pinned.external_vram: pinned external BO in vram*/431 /** @pinned.early.evicted: pinned BO that have been evicted */
426 struct list_head external_vram;432 struct list_head evicted;
433 } early;
434 /** @pinned.late: late pinned lists */
435 struct {
436 /** @pinned.late.kernel_bo_present: pinned kernel BO that are present */
437 struct list_head kernel_bo_present;
438 /** @pinned.late.evicted: pinned BO that have been evicted */
439 struct list_head evicted;
440 /** @pinned.external: pinned external and dma-buf. */
441 struct list_head external;
442 } late;
427 } pinned;443 } pinned;
428 444
429 /** @ufence_wq: user fence wait queue */445 /** @ufence_wq: user fence wait queue */
drivers/gpu/drm/xe/xe_dma_buf.c+1−4
@@ -145,10 +145,7 @@ static void xe_dma_buf_unmap(struct dma_buf_attachment *attach, · 144 unmodified lines
145 struct sg_table *sgt,145 struct sg_table *sgt,
146 enum dma_data_direction dir)146 enum dma_data_direction dir)
147{147{
148 struct dma_buf *dma_buf = attach->dmabuf;148 if (sg_page(sgt->sgl)) {
149 struct xe_bo *bo = gem_to_xe_bo(dma_buf->priv);
150
151 if (!xe_bo_is_vram(bo)) {
152 dma_unmap_sgtable(attach->dev, sgt, dir, 0);149 dma_unmap_sgtable(attach->dev, sgt, dir, 0);
153 sg_free_table(sgt);150 sg_free_table(sgt);
154 kfree(sgt);151 kfree(sgt);
drivers/gpu/drm/xe/xe_force_wake.c+0−6
@@ -49,9 +49,6 @@ void xe_force_wake_init_gt(struct xe_gt *gt, struct xe_force_wake *fw) · 48 unmodified lines
49 fw->gt = gt;49 fw->gt = gt;
50 spin_lock_init(&fw->lock);50 spin_lock_init(&fw->lock);
51 51
52 /* Assuming gen11+ so assert this assumption is correct */
53 xe_gt_assert(gt, GRAPHICS_VER(gt_to_xe(gt)) >= 11);
54
55 if (xe->info.graphics_verx100 >= 1270) {52 if (xe->info.graphics_verx100 >= 1270) {
56 init_domain(fw, XE_FW_DOMAIN_ID_GT,53 init_domain(fw, XE_FW_DOMAIN_ID_GT,
57 FORCEWAKE_GT,54 FORCEWAKE_GT,
@@ -67,9 +64,6 @@ void xe_force_wake_init_engines(struct xe_gt *gt, struct xe_force_wake *fw) · 9 unmodified lines
67{64{
68 int i, j;65 int i, j;
69 66
70 /* Assuming gen11+ so assert this assumption is correct */
71 xe_gt_assert(gt, GRAPHICS_VER(gt_to_xe(gt)) >= 11);
72
73 if (!xe_gt_is_media_type(gt))67 if (!xe_gt_is_media_type(gt))
74 init_domain(fw, XE_FW_DOMAIN_ID_RENDER,68 init_domain(fw, XE_FW_DOMAIN_ID_RENDER,
75 FORCEWAKE_RENDER,69 FORCEWAKE_RENDER,
drivers/gpu/drm/xe/xe_ggtt.c+1−1
@@ -365,7 +365,7 @@ int xe_ggtt_init(struct xe_ggtt *ggtt) · 364 unmodified lines
365 * scratch entries, rather keep the scratch page in system memory on365 * scratch entries, rather keep the scratch page in system memory on
366 * platforms where 64K pages are needed for VRAM.366 * platforms where 64K pages are needed for VRAM.
367 */367 */
368 flags = XE_BO_FLAG_PINNED;368 flags = 0;
369 if (ggtt->flags & XE_GGTT_FLAGS_64K)369 if (ggtt->flags & XE_GGTT_FLAGS_64K)
370 flags |= XE_BO_FLAG_SYSTEM;370 flags |= XE_BO_FLAG_SYSTEM;
371 else371 else
drivers/gpu/drm/xe/xe_gt.c+63−21
@@ -12,8 +12,10 @@ · 11 unmodified lines
12 12
13#include <generated/xe_wa_oob.h>13#include <generated/xe_wa_oob.h>
14 14
15#include "instructions/xe_alu_commands.h"
15#include "instructions/xe_gfxpipe_commands.h"16#include "instructions/xe_gfxpipe_commands.h"
16#include "instructions/xe_mi_commands.h"17#include "instructions/xe_mi_commands.h"
18#include "regs/xe_engine_regs.h"
17#include "regs/xe_gt_regs.h"19#include "regs/xe_gt_regs.h"
18#include "xe_assert.h"20#include "xe_assert.h"
19#include "xe_bb.h"21#include "xe_bb.h"
@@ -176,15 +178,6 @@ static int emit_nop_job(struct xe_gt *gt, struct xe_exec_queue *q) · 156 unmodified lines
176 return 0;178 return 0;
177}179}
178 180
179/*
180 * Convert back from encoded value to type-safe, only to be used when reg.mcr
181 * is true
182 */
183static struct xe_reg_mcr to_xe_reg_mcr(const struct xe_reg reg)
184{
185 return (const struct xe_reg_mcr){.__reg.raw = reg.raw };
186}
187
188static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q)181static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q)
189{182{
190 struct xe_reg_sr *sr = &q->hwe->reg_lrc;183 struct xe_reg_sr *sr = &q->hwe->reg_lrc;
@@ -194,6 +187,7 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q) · 3 unmodified lines
194 struct xe_bb *bb;187 struct xe_bb *bb;
195 struct dma_fence *fence;188 struct dma_fence *fence;
196 long timeout;189 long timeout;
190 int count_rmw = 0;
197 int count = 0;191 int count = 0;
198 192
199 if (q->hwe->class == XE_ENGINE_CLASS_RENDER)193 if (q->hwe->class == XE_ENGINE_CLASS_RENDER)
@@ -206,30 +200,32 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q) · 6 unmodified lines
206 if (IS_ERR(bb))200 if (IS_ERR(bb))
207 return PTR_ERR(bb);201 return PTR_ERR(bb);
208 202
209 xa_for_each(&sr->xa, idx, entry)203 /* count RMW registers as those will be handled separately */
210 ++count;204 xa_for_each(&sr->xa, idx, entry) {
205 if (entry->reg.masked || entry->clr_bits == ~0)
206 ++count;
207 else
208 ++count_rmw;
209 }
211 210
212 if (count) {211 if (count || count_rmw)
213 xe_gt_dbg(gt, "LRC WA %s save-restore batch\n", sr->name);212 xe_gt_dbg(gt, "LRC WA %s save-restore batch\n", sr->name);
214 213
214 if (count) {
215 /* emit single LRI with all non RMW regs */
216
215 bb->cs[bb->len++] = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(count);217 bb->cs[bb->len++] = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(count);
216 218
217 xa_for_each(&sr->xa, idx, entry) {219 xa_for_each(&sr->xa, idx, entry) {
218 struct xe_reg reg = entry->reg;220 struct xe_reg reg = entry->reg;
219 struct xe_reg_mcr reg_mcr = to_xe_reg_mcr(reg);
220 u32 val;221 u32 val;
221 222
222 /*
223 * Skip reading the register if it's not really needed
224 */
225 if (reg.masked)223 if (reg.masked)
226 val = entry->clr_bits << 16;224 val = entry->clr_bits << 16;
227 else if (entry->clr_bits + 1)225 else if (entry->clr_bits == ~0)
228 val = (reg.mcr ?
229 xe_gt_mcr_unicast_read_any(gt, reg_mcr) :
230 xe_mmio_read32(&gt->mmio, reg)) & (~entry->clr_bits);
231 else
232 val = 0;226 val = 0;
227 else
228 continue;
233 229
234 val |= entry->set_bits;230 val |= entry->set_bits;
235 231
@@ -239,6 +235,52 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q) · 3 unmodified lines
239 }235 }
240 }236 }
241 237
238 if (count_rmw) {
239 /* emit MI_MATH for each RMW reg */
240
241 xa_for_each(&sr->xa, idx, entry) {
242 if (entry->reg.masked || entry->clr_bits == ~0)
243 continue;
244
245 bb->cs[bb->len++] = MI_LOAD_REGISTER_REG | MI_LRR_DST_CS_MMIO;
246 bb->cs[bb->len++] = entry->reg.addr;
247 bb->cs[bb->len++] = CS_GPR_REG(0, 0).addr;
248
249 bb->cs[bb->len++] = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(2) |
250 MI_LRI_LRM_CS_MMIO;
251 bb->cs[bb->len++] = CS_GPR_REG(0, 1).addr;
252 bb->cs[bb->len++] = entry->clr_bits;
253 bb->cs[bb->len++] = CS_GPR_REG(0, 2).addr;
254 bb->cs[bb->len++] = entry->set_bits;
255
256 bb->cs[bb->len++] = MI_MATH(8);
257 bb->cs[bb->len++] = CS_ALU_INSTR_LOAD(SRCA, REG0);
258 bb->cs[bb->len++] = CS_ALU_INSTR_LOADINV(SRCB, REG1);
259 bb->cs[bb->len++] = CS_ALU_INSTR_AND;
260 bb->cs[bb->len++] = CS_ALU_INSTR_STORE(REG0, ACCU);
261 bb->cs[bb->len++] = CS_ALU_INSTR_LOAD(SRCA, REG0);
262 bb->cs[bb->len++] = CS_ALU_INSTR_LOAD(SRCB, REG2);
263 bb->cs[bb->len++] = CS_ALU_INSTR_OR;
264 bb->cs[bb->len++] = CS_ALU_INSTR_STORE(REG0, ACCU);
265
266 bb->cs[bb->len++] = MI_LOAD_REGISTER_REG | MI_LRR_SRC_CS_MMIO;
267 bb->cs[bb->len++] = CS_GPR_REG(0, 0).addr;
268 bb->cs[bb->len++] = entry->reg.addr;
269
270 xe_gt_dbg(gt, "REG[%#x] = ~%#x|%#x\n",
271 entry->reg.addr, entry->clr_bits, entry->set_bits);
272 }
273
274 /* reset used GPR */
275 bb->cs[bb->len++] = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(3) | MI_LRI_LRM_CS_MMIO;
276 bb->cs[bb->len++] = CS_GPR_REG(0, 0).addr;
277 bb->cs[bb->len++] = 0;
278 bb->cs[bb->len++] = CS_GPR_REG(0, 1).addr;
279 bb->cs[bb->len++] = 0;
280 bb->cs[bb->len++] = CS_GPR_REG(0, 2).addr;
281 bb->cs[bb->len++] = 0;
282 }
283
242 xe_lrc_emit_hwe_state_instructions(q, bb);284 xe_lrc_emit_hwe_state_instructions(q, bb);
243 285
244 job = xe_bb_create_job(q, bb);286 job = xe_bb_create_job(q, bb);
drivers/gpu/drm/xe/xe_gt_debugfs.c+22−8
@@ -299,20 +299,20 @@ static int hwconfig(struct xe_gt *gt, struct drm_printer *p) · 298 unmodified lines
299 return 0;299 return 0;
300}300}
301 301
302static const struct drm_info_list debugfs_list[] = {302/*
303 {"hw_engines", .show = xe_gt_debugfs_simple_show, .data = hw_engines},303 * only for GT debugfs files which can be safely used on the VF as well:
304 * - without access to the GT privileged registers
305 * - without access to the PF specific data
306 */
307static const struct drm_info_list vf_safe_debugfs_list[] = {
304 {"force_reset", .show = xe_gt_debugfs_simple_show, .data = force_reset},308 {"force_reset", .show = xe_gt_debugfs_simple_show, .data = force_reset},
305 {"force_reset_sync", .show = xe_gt_debugfs_simple_show, .data = force_reset_sync},309 {"force_reset_sync", .show = xe_gt_debugfs_simple_show, .data = force_reset_sync},
306 {"sa_info", .show = xe_gt_debugfs_simple_show, .data = sa_info},310 {"sa_info", .show = xe_gt_debugfs_simple_show, .data = sa_info},
307 {"topology", .show = xe_gt_debugfs_simple_show, .data = topology},311 {"topology", .show = xe_gt_debugfs_simple_show, .data = topology},
308 {"steering", .show = xe_gt_debugfs_simple_show, .data = steering},
309 {"ggtt", .show = xe_gt_debugfs_simple_show, .data = ggtt},312 {"ggtt", .show = xe_gt_debugfs_simple_show, .data = ggtt},
310 {"powergate_info", .show = xe_gt_debugfs_simple_show, .data = powergate_info},
311 {"register-save-restore", .show = xe_gt_debugfs_simple_show, .data = register_save_restore},313 {"register-save-restore", .show = xe_gt_debugfs_simple_show, .data = register_save_restore},
312 {"workarounds", .show = xe_gt_debugfs_simple_show, .data = workarounds},314 {"workarounds", .show = xe_gt_debugfs_simple_show, .data = workarounds},
313 {"tunings", .show = xe_gt_debugfs_simple_show, .data = tunings},315 {"tunings", .show = xe_gt_debugfs_simple_show, .data = tunings},
314 {"pat", .show = xe_gt_debugfs_simple_show, .data = pat},
315 {"mocs", .show = xe_gt_debugfs_simple_show, .data = mocs},
316 {"default_lrc_rcs", .show = xe_gt_debugfs_simple_show, .data = rcs_default_lrc},316 {"default_lrc_rcs", .show = xe_gt_debugfs_simple_show, .data = rcs_default_lrc},
317 {"default_lrc_ccs", .show = xe_gt_debugfs_simple_show, .data = ccs_default_lrc},317 {"default_lrc_ccs", .show = xe_gt_debugfs_simple_show, .data = ccs_default_lrc},
318 {"default_lrc_bcs", .show = xe_gt_debugfs_simple_show, .data = bcs_default_lrc},318 {"default_lrc_bcs", .show = xe_gt_debugfs_simple_show, .data = bcs_default_lrc},
@@ -322,6 +322,15 @@ static const struct drm_info_list debugfs_list[] = { · 3 unmodified lines
322 {"hwconfig", .show = xe_gt_debugfs_simple_show, .data = hwconfig},322 {"hwconfig", .show = xe_gt_debugfs_simple_show, .data = hwconfig},
323};323};
324 324
325/* everything else should be added here */
326static const struct drm_info_list pf_only_debugfs_list[] = {
327 {"hw_engines", .show = xe_gt_debugfs_simple_show, .data = hw_engines},
328 {"mocs", .show = xe_gt_debugfs_simple_show, .data = mocs},
329 {"pat", .show = xe_gt_debugfs_simple_show, .data = pat},
330 {"powergate_info", .show = xe_gt_debugfs_simple_show, .data = powergate_info},
331 {"steering", .show = xe_gt_debugfs_simple_show, .data = steering},
332};
333
325void xe_gt_debugfs_register(struct xe_gt *gt)334void xe_gt_debugfs_register(struct xe_gt *gt)
326{335{
327 struct xe_device *xe = gt_to_xe(gt);336 struct xe_device *xe = gt_to_xe(gt);
@@ -345,10 +354,15 @@ void xe_gt_debugfs_register(struct xe_gt *gt) · 17 unmodified lines
345 */354 */
346 root->d_inode->i_private = gt;355 root->d_inode->i_private = gt;
347 356
348 drm_debugfs_create_files(debugfs_list,357 drm_debugfs_create_files(vf_safe_debugfs_list,
349 ARRAY_SIZE(debugfs_list),358 ARRAY_SIZE(vf_safe_debugfs_list),
350 root, minor);359 root, minor);
351 360
361 if (!IS_SRIOV_VF(xe))
362 drm_debugfs_create_files(pf_only_debugfs_list,
363 ARRAY_SIZE(pf_only_debugfs_list),
364 root, minor);
365
352 xe_uc_debugfs_register(&gt->uc, root);366 xe_uc_debugfs_register(&gt->uc, root);
353 367
354 if (IS_SRIOV_PF(xe))368 if (IS_SRIOV_PF(xe))
drivers/gpu/drm/xe/xe_gt_mcr.c+2−1
@@ -345,7 +345,8 @@ fallback: · 344 unmodified lines
345 * Some older platforms don't have tables or don't have complete tables.345 * Some older platforms don't have tables or don't have complete tables.
346 * Newer platforms should always have the required info.346 * Newer platforms should always have the required info.
347 */347 */
348 if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 2000)348 if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 2000 &&
349 !gt_to_xe(gt)->info.force_execlist)
349 xe_gt_err(gt, "Slice/Subslice counts missing from hwconfig table; using typical fallback values\n");350 xe_gt_err(gt, "Slice/Subslice counts missing from hwconfig table; using typical fallback values\n");
350 351
351 if (gt_to_xe(gt)->info.platform == XE_PVC)352 if (gt_to_xe(gt)->info.platform == XE_PVC)
drivers/gpu/drm/xe/xe_gt_pagefault.c+10−3
@@ -240,7 +240,7 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf) · 239 unmodified lines
240 atomic = access_is_atomic(pf->access_type);240 atomic = access_is_atomic(pf->access_type);
241 241
242 if (xe_vma_is_cpu_addr_mirror(vma))242 if (xe_vma_is_cpu_addr_mirror(vma))
243 err = xe_svm_handle_pagefault(vm, vma, gt_to_tile(gt),243 err = xe_svm_handle_pagefault(vm, vma, gt,
244 pf->page_addr, atomic);244 pf->page_addr, atomic);
245 else245 else
246 err = handle_vma_pagefault(gt, vma, atomic);246 err = handle_vma_pagefault(gt, vma, atomic);
@@ -435,9 +435,16 @@ static int xe_alloc_pf_queue(struct xe_gt *gt, struct pf_queue *pf_queue) · 188 unmodified lines
435 num_eus = bitmap_weight(gt->fuse_topo.eu_mask_per_dss,435 num_eus = bitmap_weight(gt->fuse_topo.eu_mask_per_dss,
436 XE_MAX_EU_FUSE_BITS) * num_dss;436 XE_MAX_EU_FUSE_BITS) * num_dss;
437 437
438 /* user can issue separate page faults per EU and per CS */438 /*
439 * user can issue separate page faults per EU and per CS
440 *
441 * XXX: Multiplier required as compute UMD are getting PF queue errors
442 * without it. Follow on why this multiplier is required.
443 */
444#define PF_MULTIPLIER 8
439 pf_queue->num_dw =445 pf_queue->num_dw =
440 (num_eus + XE_NUM_HW_ENGINES) * PF_MSG_LEN_DW;446 (num_eus + XE_NUM_HW_ENGINES) * PF_MSG_LEN_DW * PF_MULTIPLIER;
447#undef PF_MULTIPLIER
441 448
442 pf_queue->gt = gt;449 pf_queue->gt = gt;
443 pf_queue->data = devm_kcalloc(xe->drm.dev, pf_queue->num_dw,450 pf_queue->data = devm_kcalloc(xe->drm.dev, pf_queue->num_dw,
drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c+14−6
@@ -1444,15 +1444,23 @@ static int pf_provision_vf_lmem(struct xe_gt *gt, unsigned int vfid, u64 size) · 1443 unmodified lines
1444 return 0;1444 return 0;
1445 1445
1446 xe_gt_assert(gt, pf_get_lmem_alignment(gt) == SZ_2M);1446 xe_gt_assert(gt, pf_get_lmem_alignment(gt) == SZ_2M);
1447 bo = xe_bo_create_pin_map(xe, tile, NULL,1447 bo = xe_bo_create_locked(xe, tile, NULL,
1448 ALIGN(size, PAGE_SIZE),1448 ALIGN(size, PAGE_SIZE),
1449 ttm_bo_type_kernel,1449 ttm_bo_type_kernel,
1450 XE_BO_FLAG_VRAM_IF_DGFX(tile) |1450 XE_BO_FLAG_VRAM_IF_DGFX(tile) |
1451 XE_BO_FLAG_NEEDS_2M |1451 XE_BO_FLAG_NEEDS_2M |
1452 XE_BO_FLAG_PINNED);1452 XE_BO_FLAG_PINNED |
1453 XE_BO_FLAG_PINNED_LATE_RESTORE);
1453 if (IS_ERR(bo))1454 if (IS_ERR(bo))
1454 return PTR_ERR(bo);1455 return PTR_ERR(bo);
1455 1456
1457 err = xe_bo_pin(bo);
1458 xe_bo_unlock(bo);
1459 if (unlikely(err)) {
1460 xe_bo_put(bo);
1461 return err;
1462 }
1463
1456 config->lmem_obj = bo;1464 config->lmem_obj = bo;
1457 1465
1458 if (xe_device_has_lmtt(xe)) {1466 if (xe_device_has_lmtt(xe)) {
drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c+49−17
@@ -51,26 +51,17 @@ static unsigned int extract_vfid(struct dentry *d) · 50 unmodified lines
51 * /sys/kernel/debug/dri/0/51 * /sys/kernel/debug/dri/0/
52 * ├── gt052 * ├── gt0
53 * │   ├── pf53 * │   ├── pf
54 * │   │   ├── ggtt_available
55 * │   │   ├── ggtt_provisioned
56 * │   │   ├── contexts_provisioned54 * │   │   ├── contexts_provisioned
57 * │   │   ├── doorbells_provisioned55 * │   │   ├── doorbells_provisioned
58 * │   │   ├── runtime_registers56 * │   │   ├── runtime_registers
59 * │   │   ├── negotiated_versions57 * │   │   ├── negotiated_versions
60 * │   │   ├── adverse_events58 * │   │   ├── adverse_events
59 * ├── gt1
60 * │   ├── pf
61 * │   │   ├── ...
61 */62 */
62 63
63static const struct drm_info_list pf_info[] = {64static const struct drm_info_list pf_info[] = {
64 {
65 "ggtt_available",
66 .show = xe_gt_debugfs_simple_show,
67 .data = xe_gt_sriov_pf_config_print_available_ggtt,
68 },
69 {
70 "ggtt_provisioned",
71 .show = xe_gt_debugfs_simple_show,
72 .data = xe_gt_sriov_pf_config_print_ggtt,
73 },
74 {65 {
75 "contexts_provisioned",66 "contexts_provisioned",
76 .show = xe_gt_debugfs_simple_show,67 .show = xe_gt_debugfs_simple_show,
@@ -81,11 +72,6 @@ static const struct drm_info_list pf_info[] = { · 4 unmodified lines
81 .show = xe_gt_debugfs_simple_show,72 .show = xe_gt_debugfs_simple_show,
82 .data = xe_gt_sriov_pf_config_print_dbs,73 .data = xe_gt_sriov_pf_config_print_dbs,
83 },74 },
84 {
85 "lmem_provisioned",
86 .show = xe_gt_debugfs_simple_show,
87 .data = xe_gt_sriov_pf_config_print_lmem,
88 },
89 {75 {
90 "runtime_registers",76 "runtime_registers",
91 .show = xe_gt_debugfs_simple_show,77 .show = xe_gt_debugfs_simple_show,
@@ -103,6 +89,42 @@ static const struct drm_info_list pf_info[] = { · 11 unmodified lines
103 },89 },
104};90};
105 91
92/*
93 * /sys/kernel/debug/dri/0/
94 * ├── gt0
95 * │   ├── pf
96 * │   │   ├── ggtt_available
97 * │   │   ├── ggtt_provisioned
98 */
99
100static const struct drm_info_list pf_ggtt_info[] = {
101 {
102 "ggtt_available",
103 .show = xe_gt_debugfs_simple_show,
104 .data = xe_gt_sriov_pf_config_print_available_ggtt,
105 },
106 {
107 "ggtt_provisioned",
108 .show = xe_gt_debugfs_simple_show,
109 .data = xe_gt_sriov_pf_config_print_ggtt,
110 },
111};
112
113/*
114 * /sys/kernel/debug/dri/0/
115 * ├── gt0
116 * │   ├── pf
117 * │   │   ├── lmem_provisioned
118 */
119
120static const struct drm_info_list pf_lmem_info[] = {
121 {
122 "lmem_provisioned",
123 .show = xe_gt_debugfs_simple_show,
124 .data = xe_gt_sriov_pf_config_print_lmem,
125 },
126};
127
106/*128/*
107 * /sys/kernel/debug/dri/0/129 * /sys/kernel/debug/dri/0/
108 * ├── gt0130 * ├── gt0
@@ -532,6 +554,16 @@ void xe_gt_sriov_pf_debugfs_register(struct xe_gt *gt, struct dentry *root) · 423 unmodified lines
532 pfdentry->d_inode->i_private = gt;554 pfdentry->d_inode->i_private = gt;
533 555
534 drm_debugfs_create_files(pf_info, ARRAY_SIZE(pf_info), pfdentry, minor);556 drm_debugfs_create_files(pf_info, ARRAY_SIZE(pf_info), pfdentry, minor);
557 if (!xe_gt_is_media_type(gt)) {
558 drm_debugfs_create_files(pf_ggtt_info,
559 ARRAY_SIZE(pf_ggtt_info),
560 pfdentry, minor);
561 if (IS_DGFX(gt_to_xe(gt)))
562 drm_debugfs_create_files(pf_lmem_info,
563 ARRAY_SIZE(pf_lmem_info),
564 pfdentry, minor);
565 }
566
535 pf_add_policy_attrs(gt, pfdentry);567 pf_add_policy_attrs(gt, pfdentry);
536 pf_add_config_attrs(gt, pfdentry, PFID);568 pf_add_config_attrs(gt, pfdentry, PFID);
537 569
drivers/gpu/drm/xe/xe_gt_sriov_pf_service.c+0−6
@@ -112,7 +112,6 @@ static const struct xe_reg tgl_runtime_regs[] = { · 111 unmodified lines
112 XELP_GT_SLICE_ENABLE, /* _MMIO(0x9138) */112 XELP_GT_SLICE_ENABLE, /* _MMIO(0x9138) */
113 XELP_GT_GEOMETRY_DSS_ENABLE, /* _MMIO(0x913c) */113 XELP_GT_GEOMETRY_DSS_ENABLE, /* _MMIO(0x913c) */
114 GT_VEBOX_VDBOX_DISABLE, /* _MMIO(0x9140) */114 GT_VEBOX_VDBOX_DISABLE, /* _MMIO(0x9140) */
115 CTC_MODE, /* _MMIO(0xa26c) */
116 HUC_KERNEL_LOAD_INFO, /* _MMIO(0xc1dc) */115 HUC_KERNEL_LOAD_INFO, /* _MMIO(0xc1dc) */
117};116};
118 117
@@ -124,7 +123,6 @@ static const struct xe_reg ats_m_runtime_regs[] = { · 5 unmodified lines
124 XELP_GT_GEOMETRY_DSS_ENABLE, /* _MMIO(0x913c) */123 XELP_GT_GEOMETRY_DSS_ENABLE, /* _MMIO(0x913c) */
125 GT_VEBOX_VDBOX_DISABLE, /* _MMIO(0x9140) */124 GT_VEBOX_VDBOX_DISABLE, /* _MMIO(0x9140) */
126 XEHP_GT_COMPUTE_DSS_ENABLE, /* _MMIO(0x9144) */125 XEHP_GT_COMPUTE_DSS_ENABLE, /* _MMIO(0x9144) */
127 CTC_MODE, /* _MMIO(0xa26c) */
128 HUC_KERNEL_LOAD_INFO, /* _MMIO(0xc1dc) */126 HUC_KERNEL_LOAD_INFO, /* _MMIO(0xc1dc) */
129};127};
130 128
@@ -136,7 +134,6 @@ static const struct xe_reg pvc_runtime_regs[] = { · 5 unmodified lines
136 GT_VEBOX_VDBOX_DISABLE, /* _MMIO(0x9140) */134 GT_VEBOX_VDBOX_DISABLE, /* _MMIO(0x9140) */
137 XEHP_GT_COMPUTE_DSS_ENABLE, /* _MMIO(0x9144) */135 XEHP_GT_COMPUTE_DSS_ENABLE, /* _MMIO(0x9144) */
138 XEHPC_GT_COMPUTE_DSS_ENABLE_EXT,/* _MMIO(0x9148) */136 XEHPC_GT_COMPUTE_DSS_ENABLE_EXT,/* _MMIO(0x9148) */
139 CTC_MODE, /* _MMIO(0xA26C) */
140 HUC_KERNEL_LOAD_INFO, /* _MMIO(0xc1dc) */137 HUC_KERNEL_LOAD_INFO, /* _MMIO(0xc1dc) */
141};138};
142 139
@@ -150,7 +147,6 @@ static const struct xe_reg ver_1270_runtime_regs[] = { · 7 unmodified lines
150 GT_VEBOX_VDBOX_DISABLE, /* _MMIO(0x9140) */147 GT_VEBOX_VDBOX_DISABLE, /* _MMIO(0x9140) */
151 XEHP_GT_COMPUTE_DSS_ENABLE, /* _MMIO(0x9144) */148 XEHP_GT_COMPUTE_DSS_ENABLE, /* _MMIO(0x9144) */
152 XEHPC_GT_COMPUTE_DSS_ENABLE_EXT,/* _MMIO(0x9148) */149 XEHPC_GT_COMPUTE_DSS_ENABLE_EXT,/* _MMIO(0x9148) */
153 CTC_MODE, /* _MMIO(0xa26c) */
154 HUC_KERNEL_LOAD_INFO, /* _MMIO(0xc1dc) */150 HUC_KERNEL_LOAD_INFO, /* _MMIO(0xc1dc) */
155};151};
156 152
@@ -167,7 +163,6 @@ static const struct xe_reg ver_2000_runtime_regs[] = { · 10 unmodified lines
167 XE2_GT_COMPUTE_DSS_2, /* _MMIO(0x914c) */163 XE2_GT_COMPUTE_DSS_2, /* _MMIO(0x914c) */
168 XE2_GT_GEOMETRY_DSS_1, /* _MMIO(0x9150) */164 XE2_GT_GEOMETRY_DSS_1, /* _MMIO(0x9150) */
169 XE2_GT_GEOMETRY_DSS_2, /* _MMIO(0x9154) */165 XE2_GT_GEOMETRY_DSS_2, /* _MMIO(0x9154) */
170 CTC_MODE, /* _MMIO(0xa26c) */
171 HUC_KERNEL_LOAD_INFO, /* _MMIO(0xc1dc) */166 HUC_KERNEL_LOAD_INFO, /* _MMIO(0xc1dc) */
172};167};
173 168
@@ -185,7 +180,6 @@ static const struct xe_reg ver_3000_runtime_regs[] = { · 11 unmodified lines
185 XE2_GT_COMPUTE_DSS_2, /* _MMIO(0x914c) */180 XE2_GT_COMPUTE_DSS_2, /* _MMIO(0x914c) */
186 XE2_GT_GEOMETRY_DSS_1, /* _MMIO(0x9150) */181 XE2_GT_GEOMETRY_DSS_1, /* _MMIO(0x9150) */
187 XE2_GT_GEOMETRY_DSS_2, /* _MMIO(0x9154) */182 XE2_GT_GEOMETRY_DSS_2, /* _MMIO(0x9154) */
188 CTC_MODE, /* _MMIO(0xa26c) */
189 HUC_KERNEL_LOAD_INFO, /* _MMIO(0xc1dc) */183 HUC_KERNEL_LOAD_INFO, /* _MMIO(0xc1dc) */
190};184};
191 185
drivers/gpu/drm/xe/xe_gt_stats.c+1−0
@@ -27,6 +27,7 @@ void xe_gt_stats_incr(struct xe_gt *gt, const enum xe_gt_stats_id id, int incr) · 26 unmodified lines
27}27}
28 28
29static const char *const stat_description[__XE_GT_STATS_NUM_IDS] = {29static const char *const stat_description[__XE_GT_STATS_NUM_IDS] = {
30 "svm_pagefault_count",
30 "tlb_inval_count",31 "tlb_inval_count",
31 "vma_pagefault_count",32 "vma_pagefault_count",
32 "vma_pagefault_kb",33 "vma_pagefault_kb",
drivers/gpu/drm/xe/xe_gt_stats_types.h+1−0
@@ -7,6 +7,7 @@ · 6 unmodified lines
7#define _XE_GT_STATS_TYPES_H_7#define _XE_GT_STATS_TYPES_H_
8 8
9enum xe_gt_stats_id {9enum xe_gt_stats_id {
10 XE_GT_STATS_ID_SVM_PAGEFAULT_COUNT,
10 XE_GT_STATS_ID_TLB_INVAL,11 XE_GT_STATS_ID_TLB_INVAL,
11 XE_GT_STATS_ID_VMA_PAGEFAULT_COUNT,12 XE_GT_STATS_ID_VMA_PAGEFAULT_COUNT,
12 XE_GT_STATS_ID_VMA_PAGEFAULT_KB,13 XE_GT_STATS_ID_VMA_PAGEFAULT_KB,
drivers/gpu/drm/xe/xe_guc.c+2−1
@@ -483,7 +483,8 @@ static int guc_g2g_alloc(struct xe_guc *guc) · 482 unmodified lines
483 XE_BO_FLAG_VRAM_IF_DGFX(tile) |483 XE_BO_FLAG_VRAM_IF_DGFX(tile) |
484 XE_BO_FLAG_GGTT |484 XE_BO_FLAG_GGTT |
485 XE_BO_FLAG_GGTT_ALL |485 XE_BO_FLAG_GGTT_ALL |
486 XE_BO_FLAG_GGTT_INVALIDATE);486 XE_BO_FLAG_GGTT_INVALIDATE |
487 XE_BO_FLAG_PINNED_NORESTORE);
487 if (IS_ERR(bo))488 if (IS_ERR(bo))
488 return PTR_ERR(bo);489 return PTR_ERR(bo);
489 490
drivers/gpu/drm/xe/xe_guc_ads.c+54−33
@@ -376,6 +376,11 @@ static void guc_waklv_init(struct xe_guc_ads *ads) · 375 unmodified lines
376 GUC_WORKAROUND_KLV_ID_BACK_TO_BACK_RCS_ENGINE_RESET,376 GUC_WORKAROUND_KLV_ID_BACK_TO_BACK_RCS_ENGINE_RESET,
377 &offset, &remain);377 &offset, &remain);
378 378
379 if (GUC_FIRMWARE_VER(&gt->uc.guc) >= MAKE_GUC_VER(70, 44, 0) && XE_WA(gt, 16026508708))
380 guc_waklv_enable_simple(ads,
381 GUC_WA_KLV_RESET_BB_STACK_PTR_ON_VF_SWITCH,
382 &offset, &remain);
383
379 size = guc_ads_waklv_size(ads) - remain;384 size = guc_ads_waklv_size(ads) - remain;
380 if (!size)385 if (!size)
381 return;386 return;
@@ -414,7 +419,8 @@ int xe_guc_ads_init(struct xe_guc_ads *ads) · 32 unmodified lines
414 bo = xe_managed_bo_create_pin_map(xe, tile, guc_ads_size(ads) + MAX_GOLDEN_LRC_SIZE,419 bo = xe_managed_bo_create_pin_map(xe, tile, guc_ads_size(ads) + MAX_GOLDEN_LRC_SIZE,
415 XE_BO_FLAG_SYSTEM |420 XE_BO_FLAG_SYSTEM |
416 XE_BO_FLAG_GGTT |421 XE_BO_FLAG_GGTT |
417 XE_BO_FLAG_GGTT_INVALIDATE);422 XE_BO_FLAG_GGTT_INVALIDATE |
423 XE_BO_FLAG_PINNED_NORESTORE);
418 if (IS_ERR(bo))424 if (IS_ERR(bo))
419 return PTR_ERR(bo);425 return PTR_ERR(bo);
420 426
@@ -490,24 +496,52 @@ static void fill_engine_enable_masks(struct xe_gt *gt, · 69 unmodified lines
490 engine_enable_mask(gt, XE_ENGINE_CLASS_OTHER));496 engine_enable_mask(gt, XE_ENGINE_CLASS_OTHER));
491}497}
492 498
493static void guc_prep_golden_lrc_null(struct xe_guc_ads *ads)499/*
500 * Write the offsets corresponding to the golden LRCs. The actual data is
501 * populated later by guc_golden_lrc_populate()
502 */
503static void guc_golden_lrc_init(struct xe_guc_ads *ads)
494{504{
495 struct xe_device *xe = ads_to_xe(ads);505 struct xe_device *xe = ads_to_xe(ads);
506 struct xe_gt *gt = ads_to_gt(ads);
496 struct iosys_map info_map = IOSYS_MAP_INIT_OFFSET(ads_to_map(ads),507 struct iosys_map info_map = IOSYS_MAP_INIT_OFFSET(ads_to_map(ads),
497 offsetof(struct __guc_ads_blob, system_info));508 offsetof(struct __guc_ads_blob, system_info));
498 u8 guc_class;509 size_t alloc_size, real_size;
510 u32 addr_ggtt, offset;
511 int class;
512
513 offset = guc_ads_golden_lrc_offset(ads);
514 addr_ggtt = xe_bo_ggtt_addr(ads->bo) + offset;
515
516 for (class = 0; class < XE_ENGINE_CLASS_MAX; ++class) {
517 u8 guc_class;
518
519 guc_class = xe_engine_class_to_guc_class(class);
499 520
500 for (guc_class = 0; guc_class <= GUC_MAX_ENGINE_CLASSES; ++guc_class) {
501 if (!info_map_read(xe, &info_map,521 if (!info_map_read(xe, &info_map,
502 engine_enabled_masks[guc_class]))522 engine_enabled_masks[guc_class]))
503 continue;523 continue;
504 524
525 real_size = xe_gt_lrc_size(gt, class);
526 alloc_size = PAGE_ALIGN(real_size);
527
528 /*
529 * This interface is slightly confusing. We need to pass the
530 * base address of the full golden context and the size of just
531 * the engine state, which is the section of the context image
532 * that starts after the execlists LRC registers. This is
533 * required to allow the GuC to restore just the engine state
534 * when a watchdog reset occurs.
535 * We calculate the engine state size by removing the size of
536 * what comes before it in the context image (which is identical
537 * on all engines).
538 */
505 ads_blob_write(ads, ads.eng_state_size[guc_class],539 ads_blob_write(ads, ads.eng_state_size[guc_class],
506 guc_ads_golden_lrc_size(ads) -540 real_size - xe_lrc_skip_size(xe));
507 xe_lrc_skip_size(xe));
508 ads_blob_write(ads, ads.golden_context_lrca[guc_class],541 ads_blob_write(ads, ads.golden_context_lrca[guc_class],
509 xe_bo_ggtt_addr(ads->bo) +542 addr_ggtt);
510 guc_ads_golden_lrc_offset(ads));543
544 addr_ggtt += alloc_size;
511 }545 }
512}546}
513 547
@@ -682,8 +716,8 @@ static int guc_capture_prep_lists(struct xe_guc_ads *ads) · 168 unmodified lines
682 }716 }
683 717
684 if (ads->capture_size != PAGE_ALIGN(total_size))718 if (ads->capture_size != PAGE_ALIGN(total_size))
685 xe_gt_dbg(gt, "ADS capture alloc size changed from %d to %d\n",719 xe_gt_dbg(gt, "Updated ADS capture size %d (was %d)\n",
686 ads->capture_size, PAGE_ALIGN(total_size));720 PAGE_ALIGN(total_size), ads->capture_size);
687 return PAGE_ALIGN(total_size);721 return PAGE_ALIGN(total_size);
688}722}
689 723
@@ -857,7 +891,7 @@ void xe_guc_ads_populate_minimal(struct xe_guc_ads *ads) · 167 unmodified lines
857 891
858 xe_map_memset(ads_to_xe(ads), ads_to_map(ads), 0, 0, ads->bo->size);892 xe_map_memset(ads_to_xe(ads), ads_to_map(ads), 0, 0, ads->bo->size);
859 guc_policies_init(ads);893 guc_policies_init(ads);
860 guc_prep_golden_lrc_null(ads);894 guc_golden_lrc_init(ads);
861 guc_mapping_table_init_invalid(gt, &info_map);895 guc_mapping_table_init_invalid(gt, &info_map);
862 guc_doorbell_init(ads);896 guc_doorbell_init(ads);
863 897
@@ -883,7 +917,7 @@ void xe_guc_ads_populate(struct xe_guc_ads *ads) · 19 unmodified lines
883 guc_policies_init(ads);917 guc_policies_init(ads);
884 fill_engine_enable_masks(gt, &info_map);918 fill_engine_enable_masks(gt, &info_map);
885 guc_mmio_reg_state_init(ads);919 guc_mmio_reg_state_init(ads);
886 guc_prep_golden_lrc_null(ads);920 guc_golden_lrc_init(ads);
887 guc_mapping_table_init(gt, &info_map);921 guc_mapping_table_init(gt, &info_map);
888 guc_capture_prep_lists(ads);922 guc_capture_prep_lists(ads);
889 guc_doorbell_init(ads);923 guc_doorbell_init(ads);
@@ -903,18 +937,22 @@ void xe_guc_ads_populate(struct xe_guc_ads *ads) · 13 unmodified lines
903 guc_ads_private_data_offset(ads));937 guc_ads_private_data_offset(ads));
904}938}
905 939
906static void guc_populate_golden_lrc(struct xe_guc_ads *ads)940/*
941 * After the golden LRC's are recorded for each engine class by the first
942 * submission, copy them to the ADS, as initialized earlier by
943 * guc_golden_lrc_init().
944 */
945static void guc_golden_lrc_populate(struct xe_guc_ads *ads)
907{946{
908 struct xe_device *xe = ads_to_xe(ads);947 struct xe_device *xe = ads_to_xe(ads);
909 struct xe_gt *gt = ads_to_gt(ads);948 struct xe_gt *gt = ads_to_gt(ads);
910 struct iosys_map info_map = IOSYS_MAP_INIT_OFFSET(ads_to_map(ads),949 struct iosys_map info_map = IOSYS_MAP_INIT_OFFSET(ads_to_map(ads),
911 offsetof(struct __guc_ads_blob, system_info));950 offsetof(struct __guc_ads_blob, system_info));
912 size_t total_size = 0, alloc_size, real_size;951 size_t total_size = 0, alloc_size, real_size;
913 u32 addr_ggtt, offset;952 u32 offset;
914 int class;953 int class;
915 954
916 offset = guc_ads_golden_lrc_offset(ads);955 offset = guc_ads_golden_lrc_offset(ads);
917 addr_ggtt = xe_bo_ggtt_addr(ads->bo) + offset;
918 956
919 for (class = 0; class < XE_ENGINE_CLASS_MAX; ++class) {957 for (class = 0; class < XE_ENGINE_CLASS_MAX; ++class) {
920 u8 guc_class;958 u8 guc_class;
@@ -931,26 +969,9 @@ static void guc_populate_golden_lrc(struct xe_guc_ads *ads) · 10 unmodified lines
931 alloc_size = PAGE_ALIGN(real_size);969 alloc_size = PAGE_ALIGN(real_size);
932 total_size += alloc_size;970 total_size += alloc_size;
933 971
934 /*
935 * This interface is slightly confusing. We need to pass the
936 * base address of the full golden context and the size of just
937 * the engine state, which is the section of the context image
938 * that starts after the execlists LRC registers. This is
939 * required to allow the GuC to restore just the engine state
940 * when a watchdog reset occurs.
941 * We calculate the engine state size by removing the size of
942 * what comes before it in the context image (which is identical
943 * on all engines).
944 */
945 ads_blob_write(ads, ads.eng_state_size[guc_class],
946 real_size - xe_lrc_skip_size(xe));
947 ads_blob_write(ads, ads.golden_context_lrca[guc_class],
948 addr_ggtt);
949
950 xe_map_memcpy_to(xe, ads_to_map(ads), offset,972 xe_map_memcpy_to(xe, ads_to_map(ads), offset,
951 gt->default_lrc[class], real_size);973 gt->default_lrc[class], real_size);
952 974
953 addr_ggtt += alloc_size;
954 offset += alloc_size;975 offset += alloc_size;
955 }976 }
956 977
@@ -959,7 +980,7 @@ static void guc_populate_golden_lrc(struct xe_guc_ads *ads) · 2 unmodified lines
959 980
960void xe_guc_ads_populate_post_load(struct xe_guc_ads *ads)981void xe_guc_ads_populate_post_load(struct xe_guc_ads *ads)
961{982{
962 guc_populate_golden_lrc(ads);983 guc_golden_lrc_populate(ads);
963}984}
964 985
965static int guc_ads_action_update_policies(struct xe_guc_ads *ads, u32 policy_offset)986static int guc_ads_action_update_policies(struct xe_guc_ads *ads, u32 policy_offset)
drivers/gpu/drm/xe/xe_guc_ct.c+3−2
@@ -238,7 +238,8 @@ int xe_guc_ct_init(struct xe_guc_ct *ct) · 237 unmodified lines
238 bo = xe_managed_bo_create_pin_map(xe, tile, guc_ct_size(),238 bo = xe_managed_bo_create_pin_map(xe, tile, guc_ct_size(),
239 XE_BO_FLAG_SYSTEM |239 XE_BO_FLAG_SYSTEM |
240 XE_BO_FLAG_GGTT |240 XE_BO_FLAG_GGTT |
241 XE_BO_FLAG_GGTT_INVALIDATE);241 XE_BO_FLAG_GGTT_INVALIDATE |
242 XE_BO_FLAG_PINNED_NORESTORE);
242 if (IS_ERR(bo))243 if (IS_ERR(bo))
243 return PTR_ERR(bo);244 return PTR_ERR(bo);
244 245
@@ -1828,10 +1829,10 @@ static void ct_dead_print(struct xe_dead_ct *dead) · 1583 unmodified lines
1828 return;1829 return;
1829 }1830 }
1830 1831
1831 drm_printf(&lp, "CTB is dead - reason=0x%X\n", dead->reason);
1832 1832
1833 /* Can't generate a genuine core dump at this point, so just do the good bits */1833 /* Can't generate a genuine core dump at this point, so just do the good bits */
1834 drm_puts(&lp, "**** Xe Device Coredump ****\n");1834 drm_puts(&lp, "**** Xe Device Coredump ****\n");
1835 drm_printf(&lp, "Reason: CTB is dead - 0x%X\n", dead->reason);
1835 xe_device_snapshot_print(xe, &lp);1836 xe_device_snapshot_print(xe, &lp);
1836 1837
1837 drm_printf(&lp, "**** GT #%d ****\n", gt->info.id);1838 drm_printf(&lp, "**** GT #%d ****\n", gt->info.id);
drivers/gpu/drm/xe/xe_guc_debugfs.c+83−65
@@ -17,101 +17,119 @@ · 16 unmodified lines
17#include "xe_macros.h"17#include "xe_macros.h"
18#include "xe_pm.h"18#include "xe_pm.h"
19 19
20static struct xe_guc *node_to_guc(struct drm_info_node *node)20/*
21{21 * guc_debugfs_show - A show callback for struct drm_info_list
22 return node->info_ent->data;22 * @m: the &seq_file
23}23 * @data: data used by the drm debugfs helpers
24 24 *
25static int guc_info(struct seq_file *m, void *data)25 * This callback can be used in struct drm_info_list to describe debugfs
26 * files that are &xe_guc specific in similar way how we handle &xe_gt
27 * specific files using &xe_gt_debugfs_simple_show.
28 *
29 * It is assumed that those debugfs files will be created on directory entry
30 * which grandparent struct dentry d_inode->i_private points to &xe_gt.
31 *
32 * /sys/kernel/debug/dri/0/
33 * ├── gt0 # dent->d_parent->d_parent (d_inode->i_private == gt)
34 * │   ├── uc # dent->d_parent
35 * │   │   ├── guc_info # dent
36 * │   │   ├── guc_...
37 *
38 * This function assumes that &m->private will be set to the &struct
39 * drm_info_node corresponding to the instance of the info on a given &struct
40 * drm_minor (see struct drm_info_list.show for details).
41 *
42 * This function also assumes that struct drm_info_list.data will point to the
43 * function code that will actually print a file content::
44 *
45 * int (*print)(struct xe_guc *, struct drm_printer *)
46 *
47 * Example::
48 *
49 * int foo(struct xe_guc *guc, struct drm_printer *p)
50 * {
51 * drm_printf(p, "enabled %d\n", guc->submission_state.enabled);
52 * return 0;
53 * }
54 *
55 * static const struct drm_info_list bar[] = {
56 * { name = "foo", .show = guc_debugfs_show, .data = foo },
57 * };
58 *
59 * parent = debugfs_create_dir("uc", gtdir);
60 * drm_debugfs_create_files(bar, ARRAY_SIZE(bar), parent, minor);
61 *
62 * Return: 0 on success or a negative error code on failure.
63 */
64static int guc_debugfs_show(struct seq_file *m, void *data)
26{65{
27 struct xe_guc *guc = node_to_guc(m->private);
28 struct xe_device *xe = guc_to_xe(guc);
29 struct drm_printer p = drm_seq_file_printer(m);66 struct drm_printer p = drm_seq_file_printer(m);
67 struct drm_info_node *node = m->private;
68 struct dentry *parent = node->dent->d_parent;
69 struct dentry *grandparent = parent->d_parent;
70 struct xe_gt *gt = grandparent->d_inode->i_private;
71 struct xe_device *xe = gt_to_xe(gt);
72 int (*print)(struct xe_guc *, struct drm_printer *) = node->info_ent->data;
73 int ret;
30 74
31 xe_pm_runtime_get(xe);75 xe_pm_runtime_get(xe);
32 xe_guc_print_info(guc, &p);76 ret = print(&gt->uc.guc, &p);
33 xe_pm_runtime_put(xe);77 xe_pm_runtime_put(xe);
34 78
35 return 0;79 return ret;
36}80}
37 81
38static int guc_log(struct seq_file *m, void *data)82static int guc_log(struct xe_guc *guc, struct drm_printer *p)
39{83{
40 struct xe_guc *guc = node_to_guc(m->private);84 xe_guc_log_print(&guc->log, p);
41 struct xe_device *xe = guc_to_xe(guc);
42 struct drm_printer p = drm_seq_file_printer(m);
43
44 xe_pm_runtime_get(xe);
45 xe_guc_log_print(&guc->log, &p);
46 xe_pm_runtime_put(xe);
47
48 return 0;85 return 0;
49}86}
50 87
51static int guc_log_dmesg(struct seq_file *m, void *data)88static int guc_log_dmesg(struct xe_guc *guc, struct drm_printer *p)
52{89{
53 struct xe_guc *guc = node_to_guc(m->private);
54 struct xe_device *xe = guc_to_xe(guc);
55
56 xe_pm_runtime_get(xe);
57 xe_guc_log_print_dmesg(&guc->log);90 xe_guc_log_print_dmesg(&guc->log);
58 xe_pm_runtime_put(xe);
59
60 return 0;91 return 0;
61}92}
62 93
63static int guc_ctb(struct seq_file *m, void *data)94static int guc_ctb(struct xe_guc *guc, struct drm_printer *p)
64{95{
65 struct xe_guc *guc = node_to_guc(m->private);96 xe_guc_ct_print(&guc->ct, p, true);
66 struct xe_device *xe = guc_to_xe(guc);
67 struct drm_printer p = drm_seq_file_printer(m);
68
69 xe_pm_runtime_get(xe);
70 xe_guc_ct_print(&guc->ct, &p, true);
71 xe_pm_runtime_put(xe);
72
73 return 0;97 return 0;
74}98}
75 99
76static int guc_pc(struct seq_file *m, void *data)100static int guc_pc(struct xe_guc *guc, struct drm_printer *p)
77{101{
78 struct xe_guc *guc = node_to_guc(m->private);102 xe_guc_pc_print(&guc->pc, p);
79 struct xe_device *xe = guc_to_xe(guc);
80 struct drm_printer p = drm_seq_file_printer(m);
81
82 xe_pm_runtime_get(xe);
83 xe_guc_pc_print(&guc->pc, &p);
84 xe_pm_runtime_put(xe);
85
86 return 0;103 return 0;
87}104}
88 105
89static const struct drm_info_list debugfs_list[] = {106/*
90 {"guc_info", guc_info, 0},107 * only for GuC debugfs files which can be safely used on the VF as well:
91 {"guc_log", guc_log, 0},108 * - without access to the GuC privileged registers
92 {"guc_log_dmesg", guc_log_dmesg, 0},109 * - without access to the PF specific GuC objects
93 {"guc_ctb", guc_ctb, 0},110 */
94 {"guc_pc", guc_pc, 0},111static const struct drm_info_list vf_safe_debugfs_list[] = {
112 { "guc_info", .show = guc_debugfs_show, .data = xe_guc_print_info },
113 { "guc_ctb", .show = guc_debugfs_show, .data = guc_ctb },
114};
115
116/* everything else should be added here */
117static const struct drm_info_list pf_only_debugfs_list[] = {
118 { "guc_log", .show = guc_debugfs_show, .data = guc_log },
119 { "guc_log_dmesg", .show = guc_debugfs_show, .data = guc_log_dmesg },
120 { "guc_pc", .show = guc_debugfs_show, .data = guc_pc },
95};121};
96 122
97void xe_guc_debugfs_register(struct xe_guc *guc, struct dentry *parent)123void xe_guc_debugfs_register(struct xe_guc *guc, struct dentry *parent)
98{124{
99 struct drm_minor *minor = guc_to_xe(guc)->drm.primary;125 struct drm_minor *minor = guc_to_xe(guc)->drm.primary;
100 struct drm_info_list *local;
101 int i;
102 126
103#define DEBUGFS_SIZE (ARRAY_SIZE(debugfs_list) * sizeof(struct drm_info_list))127 drm_debugfs_create_files(vf_safe_debugfs_list,
104 local = drmm_kmalloc(&guc_to_xe(guc)->drm, DEBUGFS_SIZE, GFP_KERNEL);128 ARRAY_SIZE(vf_safe_debugfs_list),
105 if (!local)
106 return;
107
108 memcpy(local, debugfs_list, DEBUGFS_SIZE);
109#undef DEBUGFS_SIZE
110
111 for (i = 0; i < ARRAY_SIZE(debugfs_list); ++i)
112 local[i].data = guc;
113
114 drm_debugfs_create_files(local,
115 ARRAY_SIZE(debugfs_list),
116 parent, minor);129 parent, minor);
130
131 if (!IS_SRIOV_VF(guc_to_xe(guc)))
132 drm_debugfs_create_files(pf_only_debugfs_list,
133 ARRAY_SIZE(pf_only_debugfs_list),
134 parent, minor);
117}135}
drivers/gpu/drm/xe/xe_guc_engine_activity.c+172−28
@@ -17,36 +17,61 @@ · 16 unmodified lines
17#include "xe_hw_engine.h"17#include "xe_hw_engine.h"
18#include "xe_map.h"18#include "xe_map.h"
19#include "xe_mmio.h"19#include "xe_mmio.h"
20#include "xe_sriov_pf_helpers.h"
20#include "xe_trace_guc.h"21#include "xe_trace_guc.h"
21 22
22#define TOTAL_QUANTA 0x800023#define TOTAL_QUANTA 0x8000
23 24
24static struct iosys_map engine_activity_map(struct xe_guc *guc, struct xe_hw_engine *hwe)25static struct iosys_map engine_activity_map(struct xe_guc *guc, struct xe_hw_engine *hwe,
26 unsigned int index)
25{27{
26 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;28 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;
27 struct engine_activity_buffer *buffer = &engine_activity->device_buffer;29 struct engine_activity_buffer *buffer;
28 u16 guc_class = xe_engine_class_to_guc_class(hwe->class);30 u16 guc_class = xe_engine_class_to_guc_class(hwe->class);
29 size_t offset;31 size_t offset;
30 32
31 offset = offsetof(struct guc_engine_activity_data,33 if (engine_activity->num_functions) {
34 buffer = &engine_activity->function_buffer;
35 offset = sizeof(struct guc_engine_activity_data) * index;
36 } else {
37 buffer = &engine_activity->device_buffer;
38 offset = 0;
39 }
40
41 offset += offsetof(struct guc_engine_activity_data,
32 engine_activity[guc_class][hwe->logical_instance]);42 engine_activity[guc_class][hwe->logical_instance]);
33 43
34 return IOSYS_MAP_INIT_OFFSET(&buffer->activity_bo->vmap, offset);44 return IOSYS_MAP_INIT_OFFSET(&buffer->activity_bo->vmap, offset);
35}45}
36 46
37static struct iosys_map engine_metadata_map(struct xe_guc *guc)47static struct iosys_map engine_metadata_map(struct xe_guc *guc,
48 unsigned int index)
38{49{
39 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;50 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;
40 struct engine_activity_buffer *buffer = &engine_activity->device_buffer;51 struct engine_activity_buffer *buffer;
52 size_t offset;
41 53
42 return buffer->metadata_bo->vmap;54 if (engine_activity->num_functions) {
55 buffer = &engine_activity->function_buffer;
56 offset = sizeof(struct guc_engine_activity_metadata) * index;
57 } else {
58 buffer = &engine_activity->device_buffer;
59 offset = 0;
60 }
61
62 return IOSYS_MAP_INIT_OFFSET(&buffer->metadata_bo->vmap, offset);
43}63}
44 64
45static int allocate_engine_activity_group(struct xe_guc *guc)65static int allocate_engine_activity_group(struct xe_guc *guc)
46{66{
47 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;67 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;
48 struct xe_device *xe = guc_to_xe(guc);68 struct xe_device *xe = guc_to_xe(guc);
49 u32 num_activity_group = 1; /* Will be modified for VF */69 u32 num_activity_group;
70
71 /*
72 * An additional activity group is allocated for PF
73 */
74 num_activity_group = IS_SRIOV_PF(xe) ? xe_sriov_pf_get_totalvfs(xe) + 1 : 1;
50 75
51 engine_activity->eag = drmm_kcalloc(&xe->drm, num_activity_group,76 engine_activity->eag = drmm_kcalloc(&xe->drm, num_activity_group,
52 sizeof(struct engine_activity_group), GFP_KERNEL);77 sizeof(struct engine_activity_group), GFP_KERNEL);
@@ -60,10 +85,11 @@ static int allocate_engine_activity_group(struct xe_guc *guc) · 7 unmodified lines
60}85}
61 86
62static int allocate_engine_activity_buffers(struct xe_guc *guc,87static int allocate_engine_activity_buffers(struct xe_guc *guc,
63 struct engine_activity_buffer *buffer)88 struct engine_activity_buffer *buffer,
89 int count)
64{90{
65 u32 metadata_size = sizeof(struct guc_engine_activity_metadata);91 u32 metadata_size = sizeof(struct guc_engine_activity_metadata) * count;
66 u32 size = sizeof(struct guc_engine_activity_data);92 u32 size = sizeof(struct guc_engine_activity_data) * count;
67 struct xe_gt *gt = guc_to_gt(guc);93 struct xe_gt *gt = guc_to_gt(guc);
68 struct xe_tile *tile = gt_to_tile(gt);94 struct xe_tile *tile = gt_to_tile(gt);
69 struct xe_bo *bo, *metadata_bo;95 struct xe_bo *bo, *metadata_bo;
@@ -118,10 +144,11 @@ static bool is_engine_activity_supported(struct xe_guc *guc) · 48 unmodified lines
118 return true;144 return true;
119}145}
120 146
121static struct engine_activity *hw_engine_to_engine_activity(struct xe_hw_engine *hwe)147static struct engine_activity *hw_engine_to_engine_activity(struct xe_hw_engine *hwe,
148 unsigned int index)
122{149{
123 struct xe_guc *guc = &hwe->gt->uc.guc;150 struct xe_guc *guc = &hwe->gt->uc.guc;
124 struct engine_activity_group *eag = &guc->engine_activity.eag[0];151 struct engine_activity_group *eag = &guc->engine_activity.eag[index];
125 u16 guc_class = xe_engine_class_to_guc_class(hwe->class);152 u16 guc_class = xe_engine_class_to_guc_class(hwe->class);
126 153
127 return &eag->engine[guc_class][hwe->logical_instance];154 return &eag->engine[guc_class][hwe->logical_instance];
@@ -138,9 +165,10 @@ static u64 cpu_ns_to_guc_tsc_tick(ktime_t ns, u32 freq) · 10 unmodified lines
138#define read_metadata_record(xe_, map_, field_) \165#define read_metadata_record(xe_, map_, field_) \
139 xe_map_rd_field(xe_, map_, 0, struct guc_engine_activity_metadata, field_)166 xe_map_rd_field(xe_, map_, 0, struct guc_engine_activity_metadata, field_)
140 167
141static u64 get_engine_active_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe)168static u64 get_engine_active_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe,
169 unsigned int index)
142{170{
143 struct engine_activity *ea = hw_engine_to_engine_activity(hwe);171 struct engine_activity *ea = hw_engine_to_engine_activity(hwe, index);
144 struct guc_engine_activity *cached_activity = &ea->activity;172 struct guc_engine_activity *cached_activity = &ea->activity;
145 struct guc_engine_activity_metadata *cached_metadata = &ea->metadata;173 struct guc_engine_activity_metadata *cached_metadata = &ea->metadata;
146 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;174 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;
@@ -151,8 +179,8 @@ static u64 get_engine_active_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe) · 4 unmodified lines
151 u64 active_ticks, gpm_ts;179 u64 active_ticks, gpm_ts;
152 u16 change_num;180 u16 change_num;
153 181
154 activity_map = engine_activity_map(guc, hwe);182 activity_map = engine_activity_map(guc, hwe, index);
155 metadata_map = engine_metadata_map(guc);183 metadata_map = engine_metadata_map(guc, index);
156 global_change_num = read_metadata_record(xe, &metadata_map, global_change_num);184 global_change_num = read_metadata_record(xe, &metadata_map, global_change_num);
157 185
158 /* GuC has not initialized activity data yet, return 0 */186 /* GuC has not initialized activity data yet, return 0 */
@@ -194,9 +222,9 @@ update: · 35 unmodified lines
194 return ea->total + ea->active;222 return ea->total + ea->active;
195}223}
196 224
197static u64 get_engine_total_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe)225static u64 get_engine_total_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe, unsigned int index)
198{226{
199 struct engine_activity *ea = hw_engine_to_engine_activity(hwe);227 struct engine_activity *ea = hw_engine_to_engine_activity(hwe, index);
200 struct guc_engine_activity_metadata *cached_metadata = &ea->metadata;228 struct guc_engine_activity_metadata *cached_metadata = &ea->metadata;
201 struct guc_engine_activity *cached_activity = &ea->activity;229 struct guc_engine_activity *cached_activity = &ea->activity;
202 struct iosys_map activity_map, metadata_map;230 struct iosys_map activity_map, metadata_map;
@@ -205,8 +233,8 @@ static u64 get_engine_total_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe) · 2 unmodified lines
205 u64 numerator;233 u64 numerator;
206 u16 quanta_ratio;234 u16 quanta_ratio;
207 235
208 activity_map = engine_activity_map(guc, hwe);236 activity_map = engine_activity_map(guc, hwe, index);
209 metadata_map = engine_metadata_map(guc);237 metadata_map = engine_metadata_map(guc, index);
210 238
211 if (!cached_metadata->guc_tsc_frequency_hz)239 if (!cached_metadata->guc_tsc_frequency_hz)
212 cached_metadata->guc_tsc_frequency_hz = read_metadata_record(xe, &metadata_map,240 cached_metadata->guc_tsc_frequency_hz = read_metadata_record(xe, &metadata_map,
@@ -245,10 +273,35 @@ static int enable_engine_activity_stats(struct xe_guc *guc) · 32 unmodified lines
245 return xe_guc_ct_send_block(&guc->ct, action, ARRAY_SIZE(action));273 return xe_guc_ct_send_block(&guc->ct, action, ARRAY_SIZE(action));
246}274}
247 275
248static void engine_activity_set_cpu_ts(struct xe_guc *guc)276static int enable_function_engine_activity_stats(struct xe_guc *guc, bool enable)
249{277{
250 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;278 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;
251 struct engine_activity_group *eag = &engine_activity->eag[0];279 u32 metadata_ggtt_addr = 0, ggtt_addr = 0, num_functions = 0;
280 struct engine_activity_buffer *buffer = &engine_activity->function_buffer;
281 u32 action[6];
282 int len = 0;
283
284 if (enable) {
285 metadata_ggtt_addr = xe_bo_ggtt_addr(buffer->metadata_bo);
286 ggtt_addr = xe_bo_ggtt_addr(buffer->activity_bo);
287 num_functions = engine_activity->num_functions;
288 }
289
290 action[len++] = XE_GUC_ACTION_SET_FUNCTION_ENGINE_ACTIVITY_BUFFER;
291 action[len++] = num_functions;
292 action[len++] = metadata_ggtt_addr;
293 action[len++] = 0;
294 action[len++] = ggtt_addr;
295 action[len++] = 0;
296
297 /* Blocking here to ensure the buffers are ready before reading them */
298 return xe_guc_ct_send_block(&guc->ct, action, ARRAY_SIZE(action));
299}
300
301static void engine_activity_set_cpu_ts(struct xe_guc *guc, unsigned int index)
302{
303 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;
304 struct engine_activity_group *eag = &engine_activity->eag[index];
252 int i, j;305 int i, j;
253 306
254 for (i = 0; i < GUC_MAX_ENGINE_CLASSES; i++)307 for (i = 0; i < GUC_MAX_ENGINE_CLASSES; i++)
@@ -265,34 +318,106 @@ static u32 gpm_timestamp_shift(struct xe_gt *gt) · 10 unmodified lines
265 return 3 - REG_FIELD_GET(RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK, reg);318 return 3 - REG_FIELD_GET(RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK, reg);
266}319}
267 320
321static bool is_function_valid(struct xe_guc *guc, unsigned int fn_id)
322{
323 struct xe_device *xe = guc_to_xe(guc);
324 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;
325
326 if (!IS_SRIOV_PF(xe) && fn_id)
327 return false;
328
329 if (engine_activity->num_functions && fn_id >= engine_activity->num_functions)
330 return false;
331
332 return true;
333}
334
335static int engine_activity_disable_function_stats(struct xe_guc *guc)
336{
337 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;
338 struct engine_activity_buffer *buffer = &engine_activity->function_buffer;
339 int ret;
340
341 if (!engine_activity->num_functions)
342 return 0;
343
344 ret = enable_function_engine_activity_stats(guc, false);
345 if (ret)
346 return ret;
347
348 free_engine_activity_buffers(buffer);
349 engine_activity->num_functions = 0;
350
351 return 0;
352}
353
354static int engine_activity_enable_function_stats(struct xe_guc *guc, int num_vfs)
355{
356 struct xe_guc_engine_activity *engine_activity = &guc->engine_activity;
357 struct engine_activity_buffer *buffer = &engine_activity->function_buffer;
358 int ret, i;
359
360 if (!num_vfs)
361 return 0;
362
363 /* This includes 1 PF and num_vfs */
364 engine_activity->num_functions = num_vfs + 1;
365
366 ret = allocate_engine_activity_buffers(guc, buffer, engine_activity->num_functions);
367 if (ret)
368 return ret;
369
370 ret = enable_function_engine_activity_stats(guc, true);
371 if (ret) {
372 free_engine_activity_buffers(buffer);
373 engine_activity->num_functions = 0;
374 return ret;
375 }
376
377 for (i = 0; i < engine_activity->num_functions; i++)
378 engine_activity_set_cpu_ts(guc, i + 1);
379
380 return 0;
381}
382
268/**383/**
269 * xe_guc_engine_activity_active_ticks - Get engine active ticks384 * xe_guc_engine_activity_active_ticks - Get engine active ticks
270 * @guc: The GuC object385 * @guc: The GuC object
271 * @hwe: The hw_engine object386 * @hwe: The hw_engine object
387 * @fn_id: function id to report on
272 *388 *
273 * Return: accumulated ticks @hwe was active since engine activity stats were enabled.389 * Return: accumulated ticks @hwe was active since engine activity stats were enabled.
274 */390 */
275u64 xe_guc_engine_activity_active_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe)391u64 xe_guc_engine_activity_active_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe,
392 unsigned int fn_id)
276{393{
277 if (!xe_guc_engine_activity_supported(guc))394 if (!xe_guc_engine_activity_supported(guc))
278 return 0;395 return 0;
279 396
280 return get_engine_active_ticks(guc, hwe);397 if (!is_function_valid(guc, fn_id))
398 return 0;
399
400 return get_engine_active_ticks(guc, hwe, fn_id);
281}401}
282 402
283/**403/**
284 * xe_guc_engine_activity_total_ticks - Get engine total ticks404 * xe_guc_engine_activity_total_ticks - Get engine total ticks
285 * @guc: The GuC object405 * @guc: The GuC object
286 * @hwe: The hw_engine object406 * @hwe: The hw_engine object
407 * @fn_id: function id to report on
287 *408 *
288 * Return: accumulated quanta of ticks allocated for the engine409 * Return: accumulated quanta of ticks allocated for the engine
289 */410 */
290u64 xe_guc_engine_activity_total_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe)411u64 xe_guc_engine_activity_total_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe,
412 unsigned int fn_id)
291{413{
292 if (!xe_guc_engine_activity_supported(guc))414 if (!xe_guc_engine_activity_supported(guc))
293 return 0;415 return 0;
294 416
295 return get_engine_total_ticks(guc, hwe);417 if (!is_function_valid(guc, fn_id))
418 return 0;
419
420 return get_engine_total_ticks(guc, hwe, fn_id);
296}421}
297 422
298/**423/**
@@ -310,6 +435,25 @@ bool xe_guc_engine_activity_supported(struct xe_guc *guc) · 11 unmodified lines
310 return engine_activity->supported;435 return engine_activity->supported;
311}436}
312 437
438/**
439 * xe_guc_engine_activity_function_stats - Enable/Disable per-function engine activity stats
440 * @guc: The GuC object
441 * @num_vfs: number of vfs
442 * @enable: true to enable, false otherwise
443 *
444 * Return: 0 on success, negative error code otherwise
445 */
446int xe_guc_engine_activity_function_stats(struct xe_guc *guc, int num_vfs, bool enable)
447{
448 if (!xe_guc_engine_activity_supported(guc))
449 return 0;
450
451 if (enable)
452 return engine_activity_enable_function_stats(guc, num_vfs);
453
454 return engine_activity_disable_function_stats(guc);
455}
456
313/**457/**
314 * xe_guc_engine_activity_enable_stats - Enable engine activity stats458 * xe_guc_engine_activity_enable_stats - Enable engine activity stats
315 * @guc: The GuC object459 * @guc: The GuC object
@@ -327,7 +471,7 @@ void xe_guc_engine_activity_enable_stats(struct xe_guc *guc) · 11 unmodified lines
327 if (ret)471 if (ret)
328 xe_gt_err(guc_to_gt(guc), "failed to enable activity stats%d\n", ret);472 xe_gt_err(guc_to_gt(guc), "failed to enable activity stats%d\n", ret);
329 else473 else
330 engine_activity_set_cpu_ts(guc);474 engine_activity_set_cpu_ts(guc, 0);
331}475}
332 476
333static void engine_activity_fini(void *arg)477static void engine_activity_fini(void *arg)
@@ -360,7 +504,7 @@ int xe_guc_engine_activity_init(struct xe_guc *guc) · 26 unmodified lines
360 return ret;504 return ret;
361 }505 }
362 506
363 ret = allocate_engine_activity_buffers(guc, &engine_activity->device_buffer);507 ret = allocate_engine_activity_buffers(guc, &engine_activity->device_buffer, 1);
364 if (ret) {508 if (ret) {
365 xe_gt_err(gt, "failed to allocate engine activity buffers (%pe)\n", ERR_PTR(ret));509 xe_gt_err(gt, "failed to allocate engine activity buffers (%pe)\n", ERR_PTR(ret));
366 return ret;510 return ret;
drivers/gpu/drm/xe/xe_guc_engine_activity.h+5−2
@@ -14,6 +14,9 @@ struct xe_guc; · 13 unmodified lines
14int xe_guc_engine_activity_init(struct xe_guc *guc);14int xe_guc_engine_activity_init(struct xe_guc *guc);
15bool xe_guc_engine_activity_supported(struct xe_guc *guc);15bool xe_guc_engine_activity_supported(struct xe_guc *guc);
16void xe_guc_engine_activity_enable_stats(struct xe_guc *guc);16void xe_guc_engine_activity_enable_stats(struct xe_guc *guc);
17u64 xe_guc_engine_activity_active_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe);17int xe_guc_engine_activity_function_stats(struct xe_guc *guc, int num_vfs, bool enable);
18u64 xe_guc_engine_activity_total_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe);18u64 xe_guc_engine_activity_active_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe,
19 unsigned int fn_id);
20u64 xe_guc_engine_activity_total_ticks(struct xe_guc *guc, struct xe_hw_engine *hwe,
21 unsigned int fn_id);
19#endif22#endif
drivers/gpu/drm/xe/xe_guc_engine_activity_types.h+11−1
@@ -79,14 +79,24 @@ struct xe_guc_engine_activity { · 78 unmodified lines
79 /** @num_activity_group: number of activity groups */79 /** @num_activity_group: number of activity groups */
80 u32 num_activity_group;80 u32 num_activity_group;
81 81
82 /** @num_functions: number of functions */
83 u32 num_functions;
84
82 /** @supported: indicates support for engine activity stats */85 /** @supported: indicates support for engine activity stats */
83 bool supported;86 bool supported;
84 87
85 /** @eag: holds the device level engine activity data */88 /**
89 * @eag: holds the device level engine activity data in native mode.
90 * In SRIOV mode, points to an array with entries which holds the engine
91 * activity data for PF and VF's
92 */
86 struct engine_activity_group *eag;93 struct engine_activity_group *eag;
87 94
88 /** @device_buffer: buffer object for global engine activity */95 /** @device_buffer: buffer object for global engine activity */
89 struct engine_activity_buffer device_buffer;96 struct engine_activity_buffer device_buffer;
97
98 /** @function_buffer: buffer object for per-function engine activity */
99 struct engine_activity_buffer function_buffer;
90};100};
91#endif101#endif
92 102
drivers/gpu/drm/xe/xe_guc_log.c+2−1
@@ -260,7 +260,8 @@ int xe_guc_log_init(struct xe_guc_log *log) · 259 unmodified lines
260 bo = xe_managed_bo_create_pin_map(xe, tile, guc_log_size(),260 bo = xe_managed_bo_create_pin_map(xe, tile, guc_log_size(),
261 XE_BO_FLAG_SYSTEM |261 XE_BO_FLAG_SYSTEM |
262 XE_BO_FLAG_GGTT |262 XE_BO_FLAG_GGTT |
263 XE_BO_FLAG_GGTT_INVALIDATE);263 XE_BO_FLAG_GGTT_INVALIDATE |
264 XE_BO_FLAG_PINNED_NORESTORE);
264 if (IS_ERR(bo))265 if (IS_ERR(bo))
265 return PTR_ERR(bo);266 return PTR_ERR(bo);
266 267
drivers/gpu/drm/xe/xe_guc_pc.c+17−1
@@ -461,6 +461,21 @@ static u32 get_cur_freq(struct xe_gt *gt) · 460 unmodified lines
461 return decode_freq(freq);461 return decode_freq(freq);
462}462}
463 463
464/**
465 * xe_guc_pc_get_cur_freq_fw - With fw held, get requested frequency
466 * @pc: The GuC PC
467 *
468 * Returns: the requested frequency for that GT instance
469 */
470u32 xe_guc_pc_get_cur_freq_fw(struct xe_guc_pc *pc)
471{
472 struct xe_gt *gt = pc_to_gt(pc);
473
474 xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT);
475
476 return get_cur_freq(gt);
477}
478
464/**479/**
465 * xe_guc_pc_get_cur_freq - Get Current requested frequency480 * xe_guc_pc_get_cur_freq - Get Current requested frequency
466 * @pc: The GuC PC481 * @pc: The GuC PC
@@ -1170,7 +1185,8 @@ int xe_guc_pc_init(struct xe_guc_pc *pc) · 703 unmodified lines
1170 bo = xe_managed_bo_create_pin_map(xe, tile, size,1185 bo = xe_managed_bo_create_pin_map(xe, tile, size,
1171 XE_BO_FLAG_VRAM_IF_DGFX(tile) |1186 XE_BO_FLAG_VRAM_IF_DGFX(tile) |
1172 XE_BO_FLAG_GGTT |1187 XE_BO_FLAG_GGTT |
1173 XE_BO_FLAG_GGTT_INVALIDATE);1188 XE_BO_FLAG_GGTT_INVALIDATE |
1189 XE_BO_FLAG_PINNED_NORESTORE);
1174 if (IS_ERR(bo))1190 if (IS_ERR(bo))
1175 return PTR_ERR(bo);1191 return PTR_ERR(bo);
1176 1192
drivers/gpu/drm/xe/xe_guc_pc.h+1−0
@@ -22,6 +22,7 @@ void xe_guc_pc_print(struct xe_guc_pc *pc, struct drm_printer *p); · 21 unmodified lines
22 22
23u32 xe_guc_pc_get_act_freq(struct xe_guc_pc *pc);23u32 xe_guc_pc_get_act_freq(struct xe_guc_pc *pc);
24int xe_guc_pc_get_cur_freq(struct xe_guc_pc *pc, u32 *freq);24int xe_guc_pc_get_cur_freq(struct xe_guc_pc *pc, u32 *freq);
25u32 xe_guc_pc_get_cur_freq_fw(struct xe_guc_pc *pc);
25u32 xe_guc_pc_get_rp0_freq(struct xe_guc_pc *pc);26u32 xe_guc_pc_get_rp0_freq(struct xe_guc_pc *pc);
26u32 xe_guc_pc_get_rpa_freq(struct xe_guc_pc *pc);27u32 xe_guc_pc_get_rpa_freq(struct xe_guc_pc *pc);
27u32 xe_guc_pc_get_rpe_freq(struct xe_guc_pc *pc);28u32 xe_guc_pc_get_rpe_freq(struct xe_guc_pc *pc);
drivers/gpu/drm/xe/xe_guc_submit.c+9−0
@@ -300,6 +300,8 @@ int xe_guc_submit_init(struct xe_guc *guc, unsigned int num_ids) · 299 unmodified lines
300 300
301 primelockdep(guc);301 primelockdep(guc);
302 302
303 guc->submission_state.initialized = true;
304
303 return drmm_add_action_or_reset(&xe->drm, guc_submit_fini, guc);305 return drmm_add_action_or_reset(&xe->drm, guc_submit_fini, guc);
304}306}
305 307
@@ -834,6 +836,13 @@ void xe_guc_submit_wedge(struct xe_guc *guc) · 528 unmodified lines
834 836
835 xe_gt_assert(guc_to_gt(guc), guc_to_xe(guc)->wedged.mode);837 xe_gt_assert(guc_to_gt(guc), guc_to_xe(guc)->wedged.mode);
836 838
839 /*
840 * If device is being wedged even before submission_state is
841 * initialized, there's nothing to do here.
842 */
843 if (!guc->submission_state.initialized)
844 return;
845
837 err = devm_add_action_or_reset(guc_to_xe(guc)->drm.dev,846 err = devm_add_action_or_reset(guc_to_xe(guc)->drm.dev,
838 guc_submit_wedged_fini, guc);847 guc_submit_wedged_fini, guc);
839 if (err) {848 if (err) {
drivers/gpu/drm/xe/xe_guc_types.h+5−0
@@ -89,6 +89,11 @@ struct xe_guc { · 88 unmodified lines
89 struct mutex lock;89 struct mutex lock;
90 /** @submission_state.enabled: submission is enabled */90 /** @submission_state.enabled: submission is enabled */
91 bool enabled;91 bool enabled;
92 /**
93 * @submission_state.initialized: mark when submission state is
94 * even initialized - before that not even the lock is valid
95 */
96 bool initialized;
92 /** @submission_state.fini_wq: submit fini wait queue */97 /** @submission_state.fini_wq: submit fini wait queue */
93 wait_queue_head_t fini_wq;98 wait_queue_head_t fini_wq;
94 } submission_state;99 } submission_state;
drivers/gpu/drm/xe/xe_hmm.c+0−24
@@ -19,29 +19,6 @@ static u64 xe_npages_in_range(unsigned long start, unsigned long end) · 18 unmodified lines
19 return (end - start) >> PAGE_SHIFT;19 return (end - start) >> PAGE_SHIFT;
20}20}
21 21
22/**
23 * xe_mark_range_accessed() - mark a range is accessed, so core mm
24 * have such information for memory eviction or write back to
25 * hard disk
26 * @range: the range to mark
27 * @write: if write to this range, we mark pages in this range
28 * as dirty
29 */
30static void xe_mark_range_accessed(struct hmm_range *range, bool write)
31{
32 struct page *page;
33 u64 i, npages;
34
35 npages = xe_npages_in_range(range->start, range->end);
36 for (i = 0; i < npages; i++) {
37 page = hmm_pfn_to_page(range->hmm_pfns[i]);
38 if (write)
39 set_page_dirty_lock(page);
40
41 mark_page_accessed(page);
42 }
43}
44
45static int xe_alloc_sg(struct xe_device *xe, struct sg_table *st,22static int xe_alloc_sg(struct xe_device *xe, struct sg_table *st,
46 struct hmm_range *range, struct rw_semaphore *notifier_sem)23 struct hmm_range *range, struct rw_semaphore *notifier_sem)
47{24{
@@ -331,7 +308,6 @@ int xe_hmm_userptr_populate_range(struct xe_userptr_vma *uvma, · 283 unmodified lines
331 if (ret)308 if (ret)
332 goto out_unlock;309 goto out_unlock;
333 310
334 xe_mark_range_accessed(&hmm_range, write);
335 userptr->sg = &userptr->sgt;311 userptr->sg = &userptr->sgt;
336 xe_hmm_userptr_set_mapped(uvma);312 xe_hmm_userptr_set_mapped(uvma);
337 userptr->notifier_seq = hmm_range.notifier_seq;313 userptr->notifier_seq = hmm_range.notifier_seq;
drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c+1−0
@@ -605,6 +605,7 @@ err_object: · 604 unmodified lines
605 kobject_put(kobj);605 kobject_put(kobj);
606 return err;606 return err;
607}607}
608ALLOW_ERROR_INJECTION(xe_add_hw_engine_class_defaults, ERRNO); /* See xe_pci_probe() */
608 609
609 610
610static void hw_engine_class_sysfs_fini(void *arg)611static void hw_engine_class_sysfs_fini(void *arg)
drivers/gpu/drm/xe/xe_hwmon.c+124−1
@@ -5,6 +5,7 @@ · 4 unmodified lines
5 5
6#include <linux/hwmon-sysfs.h>6#include <linux/hwmon-sysfs.h>
7#include <linux/hwmon.h>7#include <linux/hwmon.h>
8#include <linux/jiffies.h>
8#include <linux/types.h>9#include <linux/types.h>
9#include <linux/units.h>10#include <linux/units.h>
10 11
@@ -27,6 +28,7 @@ enum xe_hwmon_reg { · 16 unmodified lines
27 REG_PKG_POWER_SKU_UNIT,28 REG_PKG_POWER_SKU_UNIT,
28 REG_GT_PERF_STATUS,29 REG_GT_PERF_STATUS,
29 REG_PKG_ENERGY_STATUS,30 REG_PKG_ENERGY_STATUS,
31 REG_FAN_SPEED,
30};32};
31 33
32enum xe_hwmon_reg_operation {34enum xe_hwmon_reg_operation {
@@ -42,6 +44,13 @@ enum xe_hwmon_channel { · 9 unmodified lines
42 CHANNEL_MAX,44 CHANNEL_MAX,
43};45};
44 46
47enum xe_fan_channel {
48 FAN_1,
49 FAN_2,
50 FAN_3,
51 FAN_MAX,
52};
53
45/*54/*
46 * SF_* - scale factors for particular quantities according to hwmon spec.55 * SF_* - scale factors for particular quantities according to hwmon spec.
47 */56 */
@@ -61,6 +70,16 @@ struct xe_hwmon_energy_info { · 13 unmodified lines
61 long accum_energy;70 long accum_energy;
62};71};
63 72
73/**
74 * struct xe_hwmon_fan_info - to cache previous fan reading
75 */
76struct xe_hwmon_fan_info {
77 /** @reg_val_prev: previous fan reg val */
78 u32 reg_val_prev;
79 /** @time_prev: previous timestamp */
80 u64 time_prev;
81};
82
64/**83/**
65 * struct xe_hwmon - xe hwmon data structure84 * struct xe_hwmon - xe hwmon data structure
66 */85 */
@@ -79,6 +98,8 @@ struct xe_hwmon { · 12 unmodified lines
79 int scl_shift_time;98 int scl_shift_time;
80 /** @ei: Energy info for energyN_input */99 /** @ei: Energy info for energyN_input */
81 struct xe_hwmon_energy_info ei[CHANNEL_MAX];100 struct xe_hwmon_energy_info ei[CHANNEL_MAX];
101 /** @fi: Fan info for fanN_input */
102 struct xe_hwmon_fan_info fi[FAN_MAX];
82};103};
83 104
84static struct xe_reg xe_hwmon_get_reg(struct xe_hwmon *hwmon, enum xe_hwmon_reg hwmon_reg,105static struct xe_reg xe_hwmon_get_reg(struct xe_hwmon *hwmon, enum xe_hwmon_reg hwmon_reg,
@@ -144,6 +165,14 @@ static struct xe_reg xe_hwmon_get_reg(struct xe_hwmon *hwmon, enum xe_hwmon_reg · 59 unmodified lines
144 return PCU_CR_PACKAGE_ENERGY_STATUS;165 return PCU_CR_PACKAGE_ENERGY_STATUS;
145 }166 }
146 break;167 break;
168 case REG_FAN_SPEED:
169 if (channel == FAN_1)
170 return BMG_FAN_1_SPEED;
171 else if (channel == FAN_2)
172 return BMG_FAN_2_SPEED;
173 else if (channel == FAN_3)
174 return BMG_FAN_3_SPEED;
175 break;
147 default:176 default:
148 drm_warn(&xe->drm, "Unknown xe hwmon reg id: %d\n", hwmon_reg);177 drm_warn(&xe->drm, "Unknown xe hwmon reg id: %d\n", hwmon_reg);
149 break;178 break;
@@ -454,6 +483,7 @@ static const struct hwmon_channel_info * const hwmon_info[] = { · 304 unmodified lines
454 HWMON_CHANNEL_INFO(curr, HWMON_C_LABEL, HWMON_C_CRIT | HWMON_C_LABEL),483 HWMON_CHANNEL_INFO(curr, HWMON_C_LABEL, HWMON_C_CRIT | HWMON_C_LABEL),
455 HWMON_CHANNEL_INFO(in, HWMON_I_INPUT | HWMON_I_LABEL, HWMON_I_INPUT | HWMON_I_LABEL),484 HWMON_CHANNEL_INFO(in, HWMON_I_INPUT | HWMON_I_LABEL, HWMON_I_INPUT | HWMON_I_LABEL),
456 HWMON_CHANNEL_INFO(energy, HWMON_E_INPUT | HWMON_E_LABEL, HWMON_E_INPUT | HWMON_E_LABEL),485 HWMON_CHANNEL_INFO(energy, HWMON_E_INPUT | HWMON_E_LABEL, HWMON_E_INPUT | HWMON_E_LABEL),
486 HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT, HWMON_F_INPUT, HWMON_F_INPUT),
457 NULL487 NULL
458};488};
459 489
@@ -480,6 +510,19 @@ static int xe_hwmon_pcode_write_i1(const struct xe_hwmon *hwmon, u32 uval) · 20 unmodified lines
480 (uval & POWER_SETUP_I1_DATA_MASK));510 (uval & POWER_SETUP_I1_DATA_MASK));
481}511}
482 512
513static int xe_hwmon_pcode_read_fan_control(const struct xe_hwmon *hwmon, u32 subcmd, u32 *uval)
514{
515 struct xe_tile *root_tile = xe_device_get_root_tile(hwmon->xe);
516
517 /* Platforms that don't return correct value */
518 if (hwmon->xe->info.platform == XE_DG2 && subcmd == FSC_READ_NUM_FANS) {
519 *uval = 2;
520 return 0;
521 }
522
523 return xe_pcode_read(root_tile, PCODE_MBOX(FAN_SPEED_CONTROL, subcmd, 0), uval, NULL);
524}
525
483static int xe_hwmon_power_curr_crit_read(struct xe_hwmon *hwmon, int channel,526static int xe_hwmon_power_curr_crit_read(struct xe_hwmon *hwmon, int channel,
484 long *value, u32 scale_factor)527 long *value, u32 scale_factor)
485{528{
@@ -705,6 +748,75 @@ xe_hwmon_energy_read(struct xe_hwmon *hwmon, u32 attr, int channel, long *val) · 219 unmodified lines
705 }748 }
706}749}
707 750
751static umode_t
752xe_hwmon_fan_is_visible(struct xe_hwmon *hwmon, u32 attr, int channel)
753{
754 u32 uval;
755
756 if (!hwmon->xe->info.has_fan_control)
757 return 0;
758
759 switch (attr) {
760 case hwmon_fan_input:
761 if (xe_hwmon_pcode_read_fan_control(hwmon, FSC_READ_NUM_FANS, &uval))
762 return 0;
763
764 return channel < uval ? 0444 : 0;
765 default:
766 return 0;
767 }
768}
769
770static int
771xe_hwmon_fan_input_read(struct xe_hwmon *hwmon, int channel, long *val)
772{
773 struct xe_mmio *mmio = xe_root_tile_mmio(hwmon->xe);
774 struct xe_hwmon_fan_info *fi = &hwmon->fi[channel];
775 u64 rotations, time_now, time;
776 u32 reg_val;
777 int ret = 0;
778
779 mutex_lock(&hwmon->hwmon_lock);
780
781 reg_val = xe_mmio_read32(mmio, xe_hwmon_get_reg(hwmon, REG_FAN_SPEED, channel));
782 time_now = get_jiffies_64();
783
784 /*
785 * HW register value is accumulated count of pulses from PWM fan with the scale
786 * of 2 pulses per rotation.
787 */
788 rotations = (reg_val - fi->reg_val_prev) / 2;
789
790 time = jiffies_delta_to_msecs(time_now - fi->time_prev);
791 if (unlikely(!time)) {
792 ret = -EAGAIN;
793 goto unlock;
794 }
795
796 /*
797 * Calculate fan speed in RPM by time averaging two subsequent readings in minutes.
798 * RPM = number of rotations * msecs per minute / time in msecs
799 */
800 *val = DIV_ROUND_UP_ULL(rotations * (MSEC_PER_SEC * 60), time);
801
802 fi->reg_val_prev = reg_val;
803 fi->time_prev = time_now;
804unlock:
805 mutex_unlock(&hwmon->hwmon_lock);
806 return ret;
807}
808
809static int
810xe_hwmon_fan_read(struct xe_hwmon *hwmon, u32 attr, int channel, long *val)
811{
812 switch (attr) {
813 case hwmon_fan_input:
814 return xe_hwmon_fan_input_read(hwmon, channel, val);
815 default:
816 return -EOPNOTSUPP;
817 }
818}
819
708static umode_t820static umode_t
709xe_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type,821xe_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type,
710 u32 attr, int channel)822 u32 attr, int channel)
@@ -730,6 +842,9 @@ xe_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type, · 19 unmodified lines
730 case hwmon_energy:842 case hwmon_energy:
731 ret = xe_hwmon_energy_is_visible(hwmon, attr, channel);843 ret = xe_hwmon_energy_is_visible(hwmon, attr, channel);
732 break;844 break;
845 case hwmon_fan:
846 ret = xe_hwmon_fan_is_visible(hwmon, attr, channel);
847 break;
733 default:848 default:
734 ret = 0;849 ret = 0;
735 break;850 break;
@@ -765,6 +880,9 @@ xe_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, · 29 unmodified lines
765 case hwmon_energy:880 case hwmon_energy:
766 ret = xe_hwmon_energy_read(hwmon, attr, channel, val);881 ret = xe_hwmon_energy_read(hwmon, attr, channel, val);
767 break;882 break;
883 case hwmon_fan:
884 ret = xe_hwmon_fan_read(hwmon, attr, channel, val);
885 break;
768 default:886 default:
769 ret = -EOPNOTSUPP;887 ret = -EOPNOTSUPP;
770 break;888 break;
@@ -842,7 +960,7 @@ static void · 71 unmodified lines
842xe_hwmon_get_preregistration_info(struct xe_hwmon *hwmon)960xe_hwmon_get_preregistration_info(struct xe_hwmon *hwmon)
843{961{
844 struct xe_mmio *mmio = xe_root_tile_mmio(hwmon->xe);962 struct xe_mmio *mmio = xe_root_tile_mmio(hwmon->xe);
845 long energy;963 long energy, fan_speed;
846 u64 val_sku_unit = 0;964 u64 val_sku_unit = 0;
847 int channel;965 int channel;
848 struct xe_reg pkg_power_sku_unit;966 struct xe_reg pkg_power_sku_unit;
@@ -866,6 +984,11 @@ xe_hwmon_get_preregistration_info(struct xe_hwmon *hwmon) · 17 unmodified lines
866 for (channel = 0; channel < CHANNEL_MAX; channel++)984 for (channel = 0; channel < CHANNEL_MAX; channel++)
867 if (xe_hwmon_is_visible(hwmon, hwmon_energy, hwmon_energy_input, channel))985 if (xe_hwmon_is_visible(hwmon, hwmon_energy, hwmon_energy_input, channel))
868 xe_hwmon_energy_get(hwmon, channel, &energy);986 xe_hwmon_energy_get(hwmon, channel, &energy);
987
988 /* Initialize 'struct xe_hwmon_fan_info' with initial fan register reading. */
989 for (channel = 0; channel < FAN_MAX; channel++)
990 if (xe_hwmon_is_visible(hwmon, hwmon_fan, hwmon_fan_input, channel))
991 xe_hwmon_fan_input_read(hwmon, channel, &fan_speed);
869}992}
870 993
871static void xe_hwmon_mutex_destroy(void *arg)994static void xe_hwmon_mutex_destroy(void *arg)
drivers/gpu/drm/xe/xe_lmtt.c+1−1
@@ -71,7 +71,7 @@ static struct xe_lmtt_pt *lmtt_pt_alloc(struct xe_lmtt *lmtt, unsigned int level · 70 unmodified lines
71 lmtt->ops->lmtt_pte_num(level)),71 lmtt->ops->lmtt_pte_num(level)),
72 ttm_bo_type_kernel,72 ttm_bo_type_kernel,
73 XE_BO_FLAG_VRAM_IF_DGFX(lmtt_to_tile(lmtt)) |73 XE_BO_FLAG_VRAM_IF_DGFX(lmtt_to_tile(lmtt)) |
74 XE_BO_FLAG_NEEDS_64K | XE_BO_FLAG_PINNED);74 XE_BO_FLAG_NEEDS_64K);
75 if (IS_ERR(bo)) {75 if (IS_ERR(bo)) {
76 err = PTR_ERR(bo);76 err = PTR_ERR(bo);
77 goto out_free_pt;77 goto out_free_pt;
drivers/gpu/drm/xe/xe_lrc.c+18−10
@@ -37,6 +37,7 @@ · 36 unmodified lines
37#define LRC_ENGINE_CLASS GENMASK_ULL(63, 61)37#define LRC_ENGINE_CLASS GENMASK_ULL(63, 61)
38#define LRC_ENGINE_INSTANCE GENMASK_ULL(53, 48)38#define LRC_ENGINE_INSTANCE GENMASK_ULL(53, 48)
39 39
40#define LRC_PPHWSP_SIZE SZ_4K
40#define LRC_INDIRECT_RING_STATE_SIZE SZ_4K41#define LRC_INDIRECT_RING_STATE_SIZE SZ_4K
41 42
42static struct xe_device *43static struct xe_device *
@@ -50,19 +51,22 @@ size_t xe_gt_lrc_size(struct xe_gt *gt, enum xe_engine_class class) · 7 unmodified lines
50 struct xe_device *xe = gt_to_xe(gt);51 struct xe_device *xe = gt_to_xe(gt);
51 size_t size;52 size_t size;
52 53
54 /* Per-process HW status page (PPHWSP) */
55 size = LRC_PPHWSP_SIZE;
56
57 /* Engine context image */
53 switch (class) {58 switch (class) {
54 case XE_ENGINE_CLASS_RENDER:59 case XE_ENGINE_CLASS_RENDER:
55 if (GRAPHICS_VER(xe) >= 20)60 if (GRAPHICS_VER(xe) >= 20)
56 size = 4 * SZ_4K;61 size += 3 * SZ_4K;
57 else62 else
58 size = 14 * SZ_4K;63 size += 13 * SZ_4K;
59 break;64 break;
60 case XE_ENGINE_CLASS_COMPUTE:65 case XE_ENGINE_CLASS_COMPUTE:
61 /* 14 pages since graphics_ver == 11 */
62 if (GRAPHICS_VER(xe) >= 20)66 if (GRAPHICS_VER(xe) >= 20)
63 size = 3 * SZ_4K;67 size += 2 * SZ_4K;
64 else68 else
65 size = 14 * SZ_4K;69 size += 13 * SZ_4K;
66 break;70 break;
67 default:71 default:
68 WARN(1, "Unknown engine class: %d", class);72 WARN(1, "Unknown engine class: %d", class);
@@ -71,7 +75,7 @@ size_t xe_gt_lrc_size(struct xe_gt *gt, enum xe_engine_class class) · 2 unmodified lines
71 case XE_ENGINE_CLASS_VIDEO_DECODE:75 case XE_ENGINE_CLASS_VIDEO_DECODE:
72 case XE_ENGINE_CLASS_VIDEO_ENHANCE:76 case XE_ENGINE_CLASS_VIDEO_ENHANCE:
73 case XE_ENGINE_CLASS_OTHER:77 case XE_ENGINE_CLASS_OTHER:
74 size = 2 * SZ_4K;78 size += 1 * SZ_4K;
75 }79 }
76 80
77 /* Add indirect ring state page */81 /* Add indirect ring state page */
@@ -650,7 +654,6 @@ u32 xe_lrc_pphwsp_offset(struct xe_lrc *lrc) · 572 unmodified lines
650#define LRC_START_SEQNO_PPHWSP_OFFSET (LRC_SEQNO_PPHWSP_OFFSET + 8)654#define LRC_START_SEQNO_PPHWSP_OFFSET (LRC_SEQNO_PPHWSP_OFFSET + 8)
651#define LRC_CTX_JOB_TIMESTAMP_OFFSET (LRC_START_SEQNO_PPHWSP_OFFSET + 8)655#define LRC_CTX_JOB_TIMESTAMP_OFFSET (LRC_START_SEQNO_PPHWSP_OFFSET + 8)
652#define LRC_PARALLEL_PPHWSP_OFFSET 2048656#define LRC_PARALLEL_PPHWSP_OFFSET 2048
653#define LRC_PPHWSP_SIZE SZ_4K
654 657
655u32 xe_lrc_regs_offset(struct xe_lrc *lrc)658u32 xe_lrc_regs_offset(struct xe_lrc *lrc)
656{659{
@@ -893,6 +896,7 @@ static int xe_lrc_init(struct xe_lrc *lrc, struct xe_hw_engine *hwe, · 236 unmodified lines
893 void *init_data = NULL;896 void *init_data = NULL;
894 u32 arb_enable;897 u32 arb_enable;
895 u32 lrc_size;898 u32 lrc_size;
899 u32 bo_flags;
896 int err;900 int err;
897 901
898 kref_init(&lrc->refcount);902 kref_init(&lrc->refcount);
@@ -901,15 +905,18 @@ static int xe_lrc_init(struct xe_lrc *lrc, struct xe_hw_engine *hwe, · 2 unmodified lines
901 if (xe_gt_has_indirect_ring_state(gt))905 if (xe_gt_has_indirect_ring_state(gt))
902 lrc->flags |= XE_LRC_FLAG_INDIRECT_RING_STATE;906 lrc->flags |= XE_LRC_FLAG_INDIRECT_RING_STATE;
903 907
908 bo_flags = XE_BO_FLAG_VRAM_IF_DGFX(tile) | XE_BO_FLAG_GGTT |
909 XE_BO_FLAG_GGTT_INVALIDATE;
910 if (vm && vm->xef) /* userspace */
911 bo_flags |= XE_BO_FLAG_PINNED_LATE_RESTORE;
912
904 /*913 /*
905 * FIXME: Perma-pinning LRC as we don't yet support moving GGTT address914 * FIXME: Perma-pinning LRC as we don't yet support moving GGTT address
906 * via VM bind calls.915 * via VM bind calls.
907 */916 */
908 lrc->bo = xe_bo_create_pin_map(xe, tile, vm, lrc_size,917 lrc->bo = xe_bo_create_pin_map(xe, tile, vm, lrc_size,
909 ttm_bo_type_kernel,918 ttm_bo_type_kernel,
910 XE_BO_FLAG_VRAM_IF_DGFX(tile) |919 bo_flags);
911 XE_BO_FLAG_GGTT |
912 XE_BO_FLAG_GGTT_INVALIDATE);
913 if (IS_ERR(lrc->bo))920 if (IS_ERR(lrc->bo))
914 return PTR_ERR(lrc->bo);921 return PTR_ERR(lrc->bo);
915 922
@@ -1445,6 +1452,7 @@ static int dump_gfxpipe_command(struct drm_printer *p, · 529 unmodified lines
1445 MATCH3D(3DSTATE_CLIP_MESH);1452 MATCH3D(3DSTATE_CLIP_MESH);
1446 MATCH3D(3DSTATE_SBE_MESH);1453 MATCH3D(3DSTATE_SBE_MESH);
1447 MATCH3D(3DSTATE_CPSIZE_CONTROL_BUFFER);1454 MATCH3D(3DSTATE_CPSIZE_CONTROL_BUFFER);
1455 MATCH3D(3DSTATE_COARSE_PIXEL);
1448 1456
1449 MATCH3D(3DSTATE_DRAWING_RECTANGLE);1457 MATCH3D(3DSTATE_DRAWING_RECTANGLE);
1450 MATCH3D(3DSTATE_CHROMA_KEY);1458 MATCH3D(3DSTATE_CHROMA_KEY);
drivers/gpu/drm/xe/xe_memirq.c+1−1
@@ -86,7 +86,7 @@ static const char *guc_name(struct xe_guc *guc) · 85 unmodified lines
86 * This object needs to be 4KiB aligned.86 * This object needs to be 4KiB aligned.
87 *87 *
88 * - _`Interrupt Source Report Page`: this is the equivalent of the88 * - _`Interrupt Source Report Page`: this is the equivalent of the
89 * GEN11_GT_INTR_DWx registers, with each bit in those registers being89 * GT_INTR_DWx registers, with each bit in those registers being
90 * mapped to a byte here. The offsets are the same, just bytes instead90 * mapped to a byte here. The offsets are the same, just bytes instead
91 * of bits. This object needs to be cacheline aligned.91 * of bits. This object needs to be cacheline aligned.
92 *92 *
drivers/gpu/drm/xe/xe_migrate.c+15−9
@@ -97,7 +97,7 @@ struct xe_exec_queue *xe_tile_migrate_exec_queue(struct xe_tile *tile) · 96 unmodified lines
97 return tile->migrate->q;97 return tile->migrate->q;
98}98}
99 99
100static void xe_migrate_fini(struct drm_device *dev, void *arg)100static void xe_migrate_fini(void *arg)
101{101{
102 struct xe_migrate *m = arg;102 struct xe_migrate *m = arg;
103 103
@@ -209,7 +209,6 @@ static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m, · 105 unmodified lines
209 num_entries * XE_PAGE_SIZE,209 num_entries * XE_PAGE_SIZE,
210 ttm_bo_type_kernel,210 ttm_bo_type_kernel,
211 XE_BO_FLAG_VRAM_IF_DGFX(tile) |211 XE_BO_FLAG_VRAM_IF_DGFX(tile) |
212 XE_BO_FLAG_PINNED |
213 XE_BO_FLAG_PAGETABLE);212 XE_BO_FLAG_PAGETABLE);
214 if (IS_ERR(bo))213 if (IS_ERR(bo))
215 return PTR_ERR(bo);214 return PTR_ERR(bo);
@@ -401,7 +400,7 @@ struct xe_migrate *xe_migrate_init(struct xe_tile *tile) · 185 unmodified lines
401 struct xe_vm *vm;400 struct xe_vm *vm;
402 int err;401 int err;
403 402
404 m = drmm_kzalloc(&xe->drm, sizeof(*m), GFP_KERNEL);403 m = devm_kzalloc(xe->drm.dev, sizeof(*m), GFP_KERNEL);
405 if (!m)404 if (!m)
406 return ERR_PTR(-ENOMEM);405 return ERR_PTR(-ENOMEM);
407 406
@@ -455,7 +454,7 @@ struct xe_migrate *xe_migrate_init(struct xe_tile *tile) · 47 unmodified lines
455 might_lock(&m->job_mutex);454 might_lock(&m->job_mutex);
456 fs_reclaim_release(GFP_KERNEL);455 fs_reclaim_release(GFP_KERNEL);
457 456
458 err = drmm_add_action_or_reset(&xe->drm, xe_migrate_fini, m);457 err = devm_add_action_or_reset(xe->drm.dev, xe_migrate_fini, m);
459 if (err)458 if (err)
460 return ERR_PTR(err);459 return ERR_PTR(err);
461 460
@@ -779,10 +778,12 @@ struct dma_fence *xe_migrate_copy(struct xe_migrate *m, · 317 unmodified lines
779 bool dst_is_pltt = dst->mem_type == XE_PL_TT;778 bool dst_is_pltt = dst->mem_type == XE_PL_TT;
780 bool src_is_vram = mem_type_is_vram(src->mem_type);779 bool src_is_vram = mem_type_is_vram(src->mem_type);
781 bool dst_is_vram = mem_type_is_vram(dst->mem_type);780 bool dst_is_vram = mem_type_is_vram(dst->mem_type);
781 bool type_device = src_bo->ttm.type == ttm_bo_type_device;
782 bool needs_ccs_emit = type_device && xe_migrate_needs_ccs_emit(xe);
782 bool copy_ccs = xe_device_has_flat_ccs(xe) &&783 bool copy_ccs = xe_device_has_flat_ccs(xe) &&
783 xe_bo_needs_ccs_pages(src_bo) && xe_bo_needs_ccs_pages(dst_bo);784 xe_bo_needs_ccs_pages(src_bo) && xe_bo_needs_ccs_pages(dst_bo);
784 bool copy_system_ccs = copy_ccs && (!src_is_vram || !dst_is_vram);785 bool copy_system_ccs = copy_ccs && (!src_is_vram || !dst_is_vram);
785 bool use_comp_pat = xe_device_has_flat_ccs(xe) &&786 bool use_comp_pat = type_device && xe_device_has_flat_ccs(xe) &&
786 GRAPHICS_VER(xe) >= 20 && src_is_vram && !dst_is_vram;787 GRAPHICS_VER(xe) >= 20 && src_is_vram && !dst_is_vram;
787 788
788 /* Copying CCS between two different BOs is not supported yet. */789 /* Copying CCS between two different BOs is not supported yet. */
@@ -839,6 +840,7 @@ struct dma_fence *xe_migrate_copy(struct xe_migrate *m, · 50 unmodified lines
839 avail_pts, avail_pts);840 avail_pts, avail_pts);
840 841
841 if (copy_system_ccs) {842 if (copy_system_ccs) {
843 xe_assert(xe, type_device);
842 ccs_size = xe_device_ccs_bytes(xe, src_L0);844 ccs_size = xe_device_ccs_bytes(xe, src_L0);
843 batch_size += pte_update_size(m, 0, NULL, &ccs_it, &ccs_size,845 batch_size += pte_update_size(m, 0, NULL, &ccs_it, &ccs_size,
844 &ccs_ofs, &ccs_pt, 0,846 &ccs_ofs, &ccs_pt, 0,
@@ -849,7 +851,7 @@ struct dma_fence *xe_migrate_copy(struct xe_migrate *m, · 4 unmodified lines
849 851
850 /* Add copy commands size here */852 /* Add copy commands size here */
851 batch_size += ((copy_only_ccs) ? 0 : EMIT_COPY_DW) +853 batch_size += ((copy_only_ccs) ? 0 : EMIT_COPY_DW) +
852 ((xe_migrate_needs_ccs_emit(xe) ? EMIT_COPY_CCS_DW : 0));854 ((needs_ccs_emit ? EMIT_COPY_CCS_DW : 0));
853 855
854 bb = xe_bb_new(gt, batch_size, usm);856 bb = xe_bb_new(gt, batch_size, usm);
855 if (IS_ERR(bb)) {857 if (IS_ERR(bb)) {
@@ -878,7 +880,7 @@ struct dma_fence *xe_migrate_copy(struct xe_migrate *m, · 22 unmodified lines
878 if (!copy_only_ccs)880 if (!copy_only_ccs)
879 emit_copy(gt, bb, src_L0_ofs, dst_L0_ofs, src_L0, XE_PAGE_SIZE);881 emit_copy(gt, bb, src_L0_ofs, dst_L0_ofs, src_L0, XE_PAGE_SIZE);
880 882
881 if (xe_migrate_needs_ccs_emit(xe))883 if (needs_ccs_emit)
882 flush_flags = xe_migrate_ccs_copy(m, bb, src_L0_ofs,884 flush_flags = xe_migrate_ccs_copy(m, bb, src_L0_ofs,
883 IS_DGFX(xe) ? src_is_vram : src_is_pltt,885 IS_DGFX(xe) ? src_is_vram : src_is_pltt,
884 dst_L0_ofs,886 dst_L0_ofs,
@@ -1544,6 +1546,7 @@ void xe_migrate_wait(struct xe_migrate *m) · 659 unmodified lines
1544 dma_fence_wait(m->fence, false);1546 dma_fence_wait(m->fence, false);
1545}1547}
1546 1548
1549#if IS_ENABLED(CONFIG_DRM_XE_DEVMEM_MIRROR)
1547static u32 pte_update_cmd_size(u64 size)1550static u32 pte_update_cmd_size(u64 size)
1548{1551{
1549 u32 num_dword;1552 u32 num_dword;
@@ -1608,6 +1611,7 @@ static struct dma_fence *xe_migrate_vram(struct xe_migrate *m, · 58 unmodified lines
1608{1611{
1609 struct xe_gt *gt = m->tile->primary_gt;1612 struct xe_gt *gt = m->tile->primary_gt;
1610 struct xe_device *xe = gt_to_xe(gt);1613 struct xe_device *xe = gt_to_xe(gt);
1614 bool use_usm_batch = xe->info.has_usm;
1611 struct dma_fence *fence = NULL;1615 struct dma_fence *fence = NULL;
1612 u32 batch_size = 2;1616 u32 batch_size = 2;
1613 u64 src_L0_ofs, dst_L0_ofs;1617 u64 src_L0_ofs, dst_L0_ofs;
@@ -1624,7 +1628,7 @@ static struct dma_fence *xe_migrate_vram(struct xe_migrate *m, · 10 unmodified lines
1624 batch_size += pte_update_cmd_size(round_update_size);1628 batch_size += pte_update_cmd_size(round_update_size);
1625 batch_size += EMIT_COPY_DW;1629 batch_size += EMIT_COPY_DW;
1626 1630
1627 bb = xe_bb_new(gt, batch_size, true);1631 bb = xe_bb_new(gt, batch_size, use_usm_batch);
1628 if (IS_ERR(bb)) {1632 if (IS_ERR(bb)) {
1629 err = PTR_ERR(bb);1633 err = PTR_ERR(bb);
1630 return ERR_PTR(err);1634 return ERR_PTR(err);
@@ -1649,7 +1653,7 @@ static struct dma_fence *xe_migrate_vram(struct xe_migrate *m, · 18 unmodified lines
1649 XE_PAGE_SIZE);1653 XE_PAGE_SIZE);
1650 1654
1651 job = xe_bb_create_migration_job(m->q, bb,1655 job = xe_bb_create_migration_job(m->q, bb,
1652 xe_migrate_batch_base(m, true),1656 xe_migrate_batch_base(m, use_usm_batch),
1653 update_idx);1657 update_idx);
1654 if (IS_ERR(job)) {1658 if (IS_ERR(job)) {
1655 err = PTR_ERR(job);1659 err = PTR_ERR(job);
@@ -1719,6 +1723,8 @@ struct dma_fence *xe_migrate_from_vram(struct xe_migrate *m, · 63 unmodified lines
1719 XE_MIGRATE_COPY_TO_SRAM);1723 XE_MIGRATE_COPY_TO_SRAM);
1720}1724}
1721 1725
1726#endif
1727
1722#if IS_ENABLED(CONFIG_DRM_XE_KUNIT_TEST)1728#if IS_ENABLED(CONFIG_DRM_XE_KUNIT_TEST)
1723#include "tests/xe_migrate.c"1729#include "tests/xe_migrate.c"
1724#endif1730#endif
drivers/gpu/drm/xe/xe_mmio.c+7−4
@@ -138,6 +138,7 @@ int xe_mmio_probe_early(struct xe_device *xe) · 137 unmodified lines
138 138
139 return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe);139 return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe);
140}140}
141ALLOW_ERROR_INJECTION(xe_mmio_probe_early, ERRNO); /* See xe_pci_probe() */
141 142
142/**143/**
143 * xe_mmio_init() - Initialize an MMIO instance144 * xe_mmio_init() - Initialize an MMIO instance
@@ -204,8 +205,9 @@ void xe_mmio_write32(struct xe_mmio *mmio, struct xe_reg reg, u32 val) · 60 unmodified lines
204 205
205 trace_xe_reg_rw(mmio, true, addr, val, sizeof(val));206 trace_xe_reg_rw(mmio, true, addr, val, sizeof(val));
206 207
207 if (!reg.vf && mmio->sriov_vf_gt)208 if (!reg.vf && IS_SRIOV_VF(mmio->tile->xe))
208 xe_gt_sriov_vf_write32(mmio->sriov_vf_gt, reg, val);209 xe_gt_sriov_vf_write32(mmio->sriov_vf_gt ?:
210 mmio->tile->primary_gt, reg, val);
209 else211 else
210 writel(val, mmio->regs + addr);212 writel(val, mmio->regs + addr);
211}213}
@@ -218,8 +220,9 @@ u32 xe_mmio_read32(struct xe_mmio *mmio, struct xe_reg reg) · 6 unmodified lines
218 /* Wa_15015404425 */220 /* Wa_15015404425 */
219 mmio_flush_pending_writes(mmio);221 mmio_flush_pending_writes(mmio);
220 222
221 if (!reg.vf && mmio->sriov_vf_gt)223 if (!reg.vf && IS_SRIOV_VF(mmio->tile->xe))
222 val = xe_gt_sriov_vf_read32(mmio->sriov_vf_gt, reg);224 val = xe_gt_sriov_vf_read32(mmio->sriov_vf_gt ?:
225 mmio->tile->primary_gt, reg);
223 else226 else
224 val = readl(mmio->regs + addr);227 val = readl(mmio->regs + addr);
225 228
drivers/gpu/drm/xe/xe_module.c+7−2
@@ -11,6 +11,7 @@ · 10 unmodified lines
11#include <drm/drm_module.h>11#include <drm/drm_module.h>
12 12
13#include "xe_drv.h"13#include "xe_drv.h"
14#include "xe_configfs.h"
14#include "xe_hw_fence.h"15#include "xe_hw_fence.h"
15#include "xe_pci.h"16#include "xe_pci.h"
16#include "xe_pm.h"17#include "xe_pm.h"
@@ -38,8 +39,8 @@ MODULE_PARM_DESC(force_execlist, "Force Execlist submission"); · 21 unmodified lines
38module_param_named(probe_display, xe_modparam.probe_display, bool, 0444);39module_param_named(probe_display, xe_modparam.probe_display, bool, 0444);
39MODULE_PARM_DESC(probe_display, "Probe display HW, otherwise it's left untouched (default: true)");40MODULE_PARM_DESC(probe_display, "Probe display HW, otherwise it's left untouched (default: true)");
40 41
41module_param_named(vram_bar_size, xe_modparam.force_vram_bar_size, uint, 0600);42module_param_named(vram_bar_size, xe_modparam.force_vram_bar_size, int, 0600);
42MODULE_PARM_DESC(vram_bar_size, "Set the vram bar size(in MiB)");43MODULE_PARM_DESC(vram_bar_size, "Set the vram bar size (in MiB) - <0=disable-resize, 0=max-needed-size[default], >0=force-size");
43 44
44module_param_named(guc_log_level, xe_modparam.guc_log_level, int, 0600);45module_param_named(guc_log_level, xe_modparam.guc_log_level, int, 0600);
45MODULE_PARM_DESC(guc_log_level, "GuC firmware logging level (0=disable, 1..5=enable with verbosity min..max)");46MODULE_PARM_DESC(guc_log_level, "GuC firmware logging level (0=disable, 1..5=enable with verbosity min..max)");
@@ -88,6 +89,10 @@ static const struct init_funcs init_funcs[] = { · 42 unmodified lines
88 {89 {
89 .init = xe_check_nomodeset,90 .init = xe_check_nomodeset,
90 },91 },
92 {
93 .init = xe_configfs_init,
94 .exit = xe_configfs_exit,
95 },
91 {96 {
92 .init = xe_hw_fence_module_init,97 .init = xe_hw_fence_module_init,
93 .exit = xe_hw_fence_module_exit,98 .exit = xe_hw_fence_module_exit,
drivers/gpu/drm/xe/xe_oa.c+1−0
@@ -2221,6 +2221,7 @@ addr_err: · 2220 unmodified lines
2221 kfree(oa_regs);2221 kfree(oa_regs);
2222 return ERR_PTR(err);2222 return ERR_PTR(err);
2223}2223}
2224ALLOW_ERROR_INJECTION(xe_oa_alloc_regs, ERRNO);
2224 2225
2225static ssize_t show_dynamic_id(struct kobject *kobj,2226static ssize_t show_dynamic_id(struct kobject *kobj,
2226 struct kobj_attribute *attr,2227 struct kobj_attribute *attr,
drivers/gpu/drm/xe/xe_pci.c+19−10
@@ -62,11 +62,13 @@ struct xe_device_desc { · 61 unmodified lines
62 u8 is_dgfx:1;62 u8 is_dgfx:1;
63 63
64 u8 has_display:1;64 u8 has_display:1;
65 u8 has_fan_control:1;
65 u8 has_heci_gscfi:1;66 u8 has_heci_gscfi:1;
66 u8 has_heci_cscfi:1;67 u8 has_heci_cscfi:1;
67 u8 has_llc:1;68 u8 has_llc:1;
68 u8 has_pxp:1;69 u8 has_pxp:1;
69 u8 has_sriov:1;70 u8 has_sriov:1;
71 u8 needs_scratch:1;
70 u8 skip_guc_pc:1;72 u8 skip_guc_pc:1;
71 u8 skip_mtcfg:1;73 u8 skip_mtcfg:1;
72 u8 skip_pcode:1;74 u8 skip_pcode:1;
@@ -302,6 +304,7 @@ static const struct xe_device_desc dg2_desc = { · 229 unmodified lines
302 304
303 DG2_FEATURES,305 DG2_FEATURES,
304 .has_display = true,306 .has_display = true,
307 .has_fan_control = true,
305};308};
306 309
307static const __maybe_unused struct xe_device_desc pvc_desc = {310static const __maybe_unused struct xe_device_desc pvc_desc = {
@@ -329,6 +332,7 @@ static const struct xe_device_desc lnl_desc = { · 21 unmodified lines
329 .dma_mask_size = 46,332 .dma_mask_size = 46,
330 .has_display = true,333 .has_display = true,
331 .has_pxp = true,334 .has_pxp = true,
335 .needs_scratch = true,
332};336};
333 337
334static const struct xe_device_desc bmg_desc = {338static const struct xe_device_desc bmg_desc = {
@@ -336,7 +340,9 @@ static const struct xe_device_desc bmg_desc = { · 1 unmodified line
336 PLATFORM(BATTLEMAGE),340 PLATFORM(BATTLEMAGE),
337 .dma_mask_size = 46,341 .dma_mask_size = 46,
338 .has_display = true,342 .has_display = true,
343 .has_fan_control = true,
339 .has_heci_cscfi = 1,344 .has_heci_cscfi = 1,
345 .needs_scratch = true,
340};346};
341 347
342static const struct xe_device_desc ptl_desc = {348static const struct xe_device_desc ptl_desc = {
@@ -345,6 +351,7 @@ static const struct xe_device_desc ptl_desc = { · 2 unmodified lines
345 .has_display = true,351 .has_display = true,
346 .has_sriov = true,352 .has_sriov = true,
347 .require_force_probe = true,353 .require_force_probe = true,
354 .needs_scratch = true,
348};355};
349 356
350#undef PLATFORM357#undef PLATFORM
@@ -575,6 +582,7 @@ static int xe_info_init_early(struct xe_device *xe, · 224 unmodified lines
575 582
576 xe->info.dma_mask_size = desc->dma_mask_size;583 xe->info.dma_mask_size = desc->dma_mask_size;
577 xe->info.is_dgfx = desc->is_dgfx;584 xe->info.is_dgfx = desc->is_dgfx;
585 xe->info.has_fan_control = desc->has_fan_control;
578 xe->info.has_heci_gscfi = desc->has_heci_gscfi;586 xe->info.has_heci_gscfi = desc->has_heci_gscfi;
579 xe->info.has_heci_cscfi = desc->has_heci_cscfi;587 xe->info.has_heci_cscfi = desc->has_heci_cscfi;
580 xe->info.has_llc = desc->has_llc;588 xe->info.has_llc = desc->has_llc;
@@ -583,6 +591,7 @@ static int xe_info_init_early(struct xe_device *xe, · 2 unmodified lines
583 xe->info.skip_guc_pc = desc->skip_guc_pc;591 xe->info.skip_guc_pc = desc->skip_guc_pc;
584 xe->info.skip_mtcfg = desc->skip_mtcfg;592 xe->info.skip_mtcfg = desc->skip_mtcfg;
585 xe->info.skip_pcode = desc->skip_pcode;593 xe->info.skip_pcode = desc->skip_pcode;
594 xe->info.needs_scratch = desc->needs_scratch;
586 595
587 xe->info.probe_display = IS_ENABLED(CONFIG_DRM_XE_DISPLAY) &&596 xe->info.probe_display = IS_ENABLED(CONFIG_DRM_XE_DISPLAY) &&
588 xe_modparam.probe_display &&597 xe_modparam.probe_display &&
@@ -803,18 +812,17 @@ static int xe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 214 unmodified lines
803 return err;812 return err;
804 813
805 err = xe_device_probe_early(xe);814 err = xe_device_probe_early(xe);
806 if (err) {815 /*
807 /*816 * In Boot Survivability mode, no drm card is exposed and driver
808 * In Boot Survivability mode, no drm card is exposed and driver817 * is loaded with bare minimum to allow for firmware to be
809 * is loaded with bare minimum to allow for firmware to be818 * flashed through mei. Return success, if survivability mode
810 * flashed through mei. If early probe failed, but it managed to819 * is enabled due to pcode failure or configfs being set
811 * enable survivability mode, return success.820 */
812 */821 if (xe_survivability_mode_is_enabled(xe))
813 if (xe_survivability_mode_is_enabled(xe))822 return 0;
814 return 0;
815 823
824 if (err)
816 return err;825 return err;
817 }
818 826
819 err = xe_info_init(xe, desc);827 err = xe_info_init(xe, desc);
820 if (err)828 if (err)
@@ -920,6 +928,7 @@ static int xe_pci_suspend(struct device *dev) · 99 unmodified lines
920 928
921 pci_save_state(pdev);929 pci_save_state(pdev);
922 pci_disable_device(pdev);930 pci_disable_device(pdev);
931 pci_set_power_state(pdev, PCI_D3cold);
923 932
924 return 0;933 return 0;
925}934}
drivers/gpu/drm/xe/xe_pci_sriov.c+20−0
@@ -7,6 +7,7 @@ · 6 unmodified lines
7#include "xe_device.h"7#include "xe_device.h"
8#include "xe_gt_sriov_pf_config.h"8#include "xe_gt_sriov_pf_config.h"
9#include "xe_gt_sriov_pf_control.h"9#include "xe_gt_sriov_pf_control.h"
10#include "xe_guc_engine_activity.h"
10#include "xe_pci_sriov.h"11#include "xe_pci_sriov.h"
11#include "xe_pm.h"12#include "xe_pm.h"
12#include "xe_sriov.h"13#include "xe_sriov.h"
@@ -111,6 +112,20 @@ static void pf_link_vfs(struct xe_device *xe, int num_vfs) · 98 unmodified lines
111 }112 }
112}113}
113 114
115static void pf_engine_activity_stats(struct xe_device *xe, unsigned int num_vfs, bool enable)
116{
117 struct xe_gt *gt;
118 unsigned int id;
119 int ret = 0;
120
121 for_each_gt(gt, xe, id) {
122 ret = xe_guc_engine_activity_function_stats(&gt->uc.guc, num_vfs, enable);
123 if (ret)
124 xe_sriov_info(xe, "Failed to %s engine activity function stats (%pe)\n",
125 str_enable_disable(enable), ERR_PTR(ret));
126 }
127}
128
114static int pf_enable_vfs(struct xe_device *xe, int num_vfs)129static int pf_enable_vfs(struct xe_device *xe, int num_vfs)
115{130{
116 struct pci_dev *pdev = to_pci_dev(xe->drm.dev);131 struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
@@ -145,6 +160,9 @@ static int pf_enable_vfs(struct xe_device *xe, int num_vfs) · 28 unmodified lines
145 160
146 xe_sriov_info(xe, "Enabled %u of %u VF%s\n",161 xe_sriov_info(xe, "Enabled %u of %u VF%s\n",
147 num_vfs, total_vfs, str_plural(total_vfs));162 num_vfs, total_vfs, str_plural(total_vfs));
163
164 pf_engine_activity_stats(xe, num_vfs, true);
165
148 return num_vfs;166 return num_vfs;
149 167
150failed:168failed:
@@ -168,6 +186,8 @@ static int pf_disable_vfs(struct xe_device *xe) · 17 unmodified lines
168 if (!num_vfs)186 if (!num_vfs)
169 return 0;187 return 0;
170 188
189 pf_engine_activity_stats(xe, num_vfs, false);
190
171 pci_disable_sriov(pdev);191 pci_disable_sriov(pdev);
172 192
173 pf_reset_vfs(xe, num_vfs);193 pf_reset_vfs(xe, num_vfs);
drivers/gpu/drm/xe/xe_pcode.c+2−0
@@ -7,6 +7,7 @@ · 6 unmodified lines
7 7
8#include <linux/delay.h>8#include <linux/delay.h>
9#include <linux/errno.h>9#include <linux/errno.h>
10#include <linux/error-injection.h>
10 11
11#include <drm/drm_managed.h>12#include <drm/drm_managed.h>
12 13
@@ -323,3 +324,4 @@ int xe_pcode_probe_early(struct xe_device *xe) · 310 unmodified lines
323{324{
324 return xe_pcode_ready(xe, false);325 return xe_pcode_ready(xe, false);
325}326}
327ALLOW_ERROR_INJECTION(xe_pcode_probe_early, ERRNO); /* See xe_pci_probe */
drivers/gpu/drm/xe/xe_pcode_api.h+3−0
@@ -49,6 +49,9 @@ · 48 unmodified lines
49/* Domain IDs (param2) */49/* Domain IDs (param2) */
50#define PCODE_MBOX_DOMAIN_HBM 0x250#define PCODE_MBOX_DOMAIN_HBM 0x2
51 51
52#define FAN_SPEED_CONTROL 0x7D
53#define FSC_READ_NUM_FANS 0x4
54
52#define PCODE_SCRATCH(x) XE_REG(0x138320 + ((x) * 4))55#define PCODE_SCRATCH(x) XE_REG(0x138320 + ((x) * 4))
53/* PCODE_SCRATCH0 */56/* PCODE_SCRATCH0 */
54#define AUXINFO_REG_OFFSET REG_GENMASK(17, 15)57#define AUXINFO_REG_OFFSET REG_GENMASK(17, 15)
drivers/gpu/drm/xe/xe_pm.c+4−4
@@ -188,7 +188,7 @@ int xe_pm_resume(struct xe_device *xe) · 187 unmodified lines
188 * This only restores pinned memory which is the memory required for the188 * This only restores pinned memory which is the memory required for the
189 * GT(s) to resume.189 * GT(s) to resume.
190 */190 */
191 err = xe_bo_restore_kernel(xe);191 err = xe_bo_restore_early(xe);
192 if (err)192 if (err)
193 goto err;193 goto err;
194 194
@@ -199,7 +199,7 @@ int xe_pm_resume(struct xe_device *xe) · 4 unmodified lines
199 199
200 xe_display_pm_resume(xe);200 xe_display_pm_resume(xe);
201 201
202 err = xe_bo_restore_user(xe);202 err = xe_bo_restore_late(xe);
203 if (err)203 if (err)
204 goto err;204 goto err;
205 205
@@ -484,7 +484,7 @@ int xe_pm_runtime_resume(struct xe_device *xe) · 278 unmodified lines
484 * This only restores pinned memory which is the memory484 * This only restores pinned memory which is the memory
485 * required for the GT(s) to resume.485 * required for the GT(s) to resume.
486 */486 */
487 err = xe_bo_restore_kernel(xe);487 err = xe_bo_restore_early(xe);
488 if (err)488 if (err)
489 goto out;489 goto out;
490 }490 }
@@ -497,7 +497,7 @@ int xe_pm_runtime_resume(struct xe_device *xe) · 6 unmodified lines
497 xe_display_pm_runtime_resume(xe);497 xe_display_pm_runtime_resume(xe);
498 498
499 if (xe->d3cold.allowed) {499 if (xe->d3cold.allowed) {
500 err = xe_bo_restore_user(xe);500 err = xe_bo_restore_late(xe);
501 if (err)501 if (err)
502 goto out;502 goto out;
503 }503 }
drivers/gpu/drm/xe/xe_pmu.c+67−10
@@ -10,9 +10,11 @@ · 9 unmodified lines
10#include "xe_force_wake.h"10#include "xe_force_wake.h"
11#include "xe_gt_idle.h"11#include "xe_gt_idle.h"
12#include "xe_guc_engine_activity.h"12#include "xe_guc_engine_activity.h"
13#include "xe_guc_pc.h"
13#include "xe_hw_engine.h"14#include "xe_hw_engine.h"
14#include "xe_pm.h"15#include "xe_pm.h"
15#include "xe_pmu.h"16#include "xe_pmu.h"
17#include "xe_sriov_pf_helpers.h"
16 18
17/**19/**
18 * DOC: Xe PMU (Performance Monitoring Unit)20 * DOC: Xe PMU (Performance Monitoring Unit)
@@ -32,9 +34,10 @@ · 13 unmodified lines
32 * gt[60:63] Selects gt for the event34 * gt[60:63] Selects gt for the event
33 * engine_class[20:27] Selects engine-class for event35 * engine_class[20:27] Selects engine-class for event
34 * engine_instance[12:19] Selects the engine-instance for the event36 * engine_instance[12:19] Selects the engine-instance for the event
37 * function[44:59] Selects the function of the event (SRIOV enabled)
35 *38 *
36 * For engine specific events (engine-*), gt, engine_class and engine_instance parameters must be39 * For engine specific events (engine-*), gt, engine_class and engine_instance parameters must be
37 * set as populated by DRM_XE_DEVICE_QUERY_ENGINES.40 * set as populated by DRM_XE_DEVICE_QUERY_ENGINES and function if SRIOV is enabled.
38 *41 *
39 * For gt specific events (gt-*) gt parameter must be passed. All other parameters will be 0.42 * For gt specific events (gt-*) gt parameter must be passed. All other parameters will be 0.
40 *43 *
@@ -49,6 +52,7 @@ · 8 unmodified lines
49 */52 */
50 53
51#define XE_PMU_EVENT_GT_MASK GENMASK_ULL(63, 60)54#define XE_PMU_EVENT_GT_MASK GENMASK_ULL(63, 60)
55#define XE_PMU_EVENT_FUNCTION_MASK GENMASK_ULL(59, 44)
52#define XE_PMU_EVENT_ENGINE_CLASS_MASK GENMASK_ULL(27, 20)56#define XE_PMU_EVENT_ENGINE_CLASS_MASK GENMASK_ULL(27, 20)
53#define XE_PMU_EVENT_ENGINE_INSTANCE_MASK GENMASK_ULL(19, 12)57#define XE_PMU_EVENT_ENGINE_INSTANCE_MASK GENMASK_ULL(19, 12)
54#define XE_PMU_EVENT_ID_MASK GENMASK_ULL(11, 0)58#define XE_PMU_EVENT_ID_MASK GENMASK_ULL(11, 0)
@@ -58,6 +62,11 @@ static unsigned int config_to_event_id(u64 config) · 3 unmodified lines
58 return FIELD_GET(XE_PMU_EVENT_ID_MASK, config);62 return FIELD_GET(XE_PMU_EVENT_ID_MASK, config);
59}63}
60 64
65static unsigned int config_to_function_id(u64 config)
66{
67 return FIELD_GET(XE_PMU_EVENT_FUNCTION_MASK, config);
68}
69
61static unsigned int config_to_engine_class(u64 config)70static unsigned int config_to_engine_class(u64 config)
62{71{
63 return FIELD_GET(XE_PMU_EVENT_ENGINE_CLASS_MASK, config);72 return FIELD_GET(XE_PMU_EVENT_ENGINE_CLASS_MASK, config);
@@ -76,6 +85,8 @@ static unsigned int config_to_gt_id(u64 config) · 12 unmodified lines
76#define XE_PMU_EVENT_GT_C6_RESIDENCY 0x0185#define XE_PMU_EVENT_GT_C6_RESIDENCY 0x01
77#define XE_PMU_EVENT_ENGINE_ACTIVE_TICKS 0x0286#define XE_PMU_EVENT_ENGINE_ACTIVE_TICKS 0x02
78#define XE_PMU_EVENT_ENGINE_TOTAL_TICKS 0x0387#define XE_PMU_EVENT_ENGINE_TOTAL_TICKS 0x03
88#define XE_PMU_EVENT_GT_ACTUAL_FREQUENCY 0x04
89#define XE_PMU_EVENT_GT_REQUESTED_FREQUENCY 0x05
79 90
80static struct xe_gt *event_to_gt(struct perf_event *event)91static struct xe_gt *event_to_gt(struct perf_event *event)
81{92{
@@ -111,6 +122,14 @@ static bool is_engine_event(u64 config) · 29 unmodified lines
111 event_id == XE_PMU_EVENT_ENGINE_ACTIVE_TICKS);122 event_id == XE_PMU_EVENT_ENGINE_ACTIVE_TICKS);
112}123}
113 124
125static bool is_gt_frequency_event(struct perf_event *event)
126{
127 u32 id = config_to_event_id(event->attr.config);
128
129 return id == XE_PMU_EVENT_GT_ACTUAL_FREQUENCY ||
130 id == XE_PMU_EVENT_GT_REQUESTED_FREQUENCY;
131}
132
114static bool event_gt_forcewake(struct perf_event *event)133static bool event_gt_forcewake(struct perf_event *event)
115{134{
116 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base);135 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base);
@@ -118,7 +137,7 @@ static bool event_gt_forcewake(struct perf_event *event) · 1 unmodified line
118 struct xe_gt *gt;137 struct xe_gt *gt;
119 unsigned int *fw_ref;138 unsigned int *fw_ref;
120 139
121 if (!is_engine_event(config))140 if (!is_engine_event(config) && !is_gt_frequency_event(event))
122 return true;141 return true;
123 142
124 gt = xe_device_get_gt(xe, config_to_gt_id(config));143 gt = xe_device_get_gt(xe, config_to_gt_id(config));
@@ -151,7 +170,7 @@ static bool event_supported(struct xe_pmu *pmu, unsigned int gt, · 26 unmodified lines
151static bool event_param_valid(struct perf_event *event)170static bool event_param_valid(struct perf_event *event)
152{171{
153 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base);172 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base);
154 unsigned int engine_class, engine_instance;173 unsigned int engine_class, engine_instance, function_id;
155 u64 config = event->attr.config;174 u64 config = event->attr.config;
156 struct xe_gt *gt;175 struct xe_gt *gt;
157 176
@@ -161,16 +180,28 @@ static bool event_param_valid(struct perf_event *event) · 3 unmodified lines
161 180
162 engine_class = config_to_engine_class(config);181 engine_class = config_to_engine_class(config);
163 engine_instance = config_to_engine_instance(config);182 engine_instance = config_to_engine_instance(config);
183 function_id = config_to_function_id(config);
164 184
165 switch (config_to_event_id(config)) {185 switch (config_to_event_id(config)) {
166 case XE_PMU_EVENT_GT_C6_RESIDENCY:186 case XE_PMU_EVENT_GT_C6_RESIDENCY:
167 if (engine_class || engine_instance)187 case XE_PMU_EVENT_GT_ACTUAL_FREQUENCY:
188 case XE_PMU_EVENT_GT_REQUESTED_FREQUENCY:
189 if (engine_class || engine_instance || function_id)
168 return false;190 return false;
169 break;191 break;
170 case XE_PMU_EVENT_ENGINE_ACTIVE_TICKS:192 case XE_PMU_EVENT_ENGINE_ACTIVE_TICKS:
171 case XE_PMU_EVENT_ENGINE_TOTAL_TICKS:193 case XE_PMU_EVENT_ENGINE_TOTAL_TICKS:
172 if (!event_to_hwe(event))194 if (!event_to_hwe(event))
173 return false;195 return false;
196
197 /* PF(0) and total vfs when SRIOV is enabled */
198 if (IS_SRIOV_PF(xe)) {
199 if (function_id > xe_sriov_pf_get_totalvfs(xe))
200 return false;
201 } else if (function_id) {
202 return false;
203 }
204
174 break;205 break;
175 }206 }
176 207
@@ -242,13 +273,17 @@ static int xe_pmu_event_init(struct perf_event *event) · 65 unmodified lines
242static u64 read_engine_events(struct xe_gt *gt, struct perf_event *event)273static u64 read_engine_events(struct xe_gt *gt, struct perf_event *event)
243{274{
244 struct xe_hw_engine *hwe;275 struct xe_hw_engine *hwe;
245 u64 val = 0;276 unsigned int function_id;
277 u64 config, val = 0;
278
279 config = event->attr.config;
280 function_id = config_to_function_id(config);
246 281
247 hwe = event_to_hwe(event);282 hwe = event_to_hwe(event);
248 if (config_to_event_id(event->attr.config) == XE_PMU_EVENT_ENGINE_ACTIVE_TICKS)283 if (config_to_event_id(config) == XE_PMU_EVENT_ENGINE_ACTIVE_TICKS)
249 val = xe_guc_engine_activity_active_ticks(&gt->uc.guc, hwe);284 val = xe_guc_engine_activity_active_ticks(&gt->uc.guc, hwe, function_id);
250 else285 else
251 val = xe_guc_engine_activity_total_ticks(&gt->uc.guc, hwe);286 val = xe_guc_engine_activity_total_ticks(&gt->uc.guc, hwe, function_id);
252 287
253 return val;288 return val;
254}289}
@@ -266,6 +301,10 @@ static u64 __xe_pmu_event_read(struct perf_event *event) · 11 unmodified lines
266 case XE_PMU_EVENT_ENGINE_ACTIVE_TICKS:301 case XE_PMU_EVENT_ENGINE_ACTIVE_TICKS:
267 case XE_PMU_EVENT_ENGINE_TOTAL_TICKS:302 case XE_PMU_EVENT_ENGINE_TOTAL_TICKS:
268 return read_engine_events(gt, event);303 return read_engine_events(gt, event);
304 case XE_PMU_EVENT_GT_ACTUAL_FREQUENCY:
305 return xe_guc_pc_get_act_freq(&gt->uc.guc.pc);
306 case XE_PMU_EVENT_GT_REQUESTED_FREQUENCY:
307 return xe_guc_pc_get_cur_freq_fw(&gt->uc.guc.pc);
269 }308 }
270 309
271 return 0;310 return 0;
@@ -281,7 +320,14 @@ static void xe_pmu_event_update(struct perf_event *event) · 9 unmodified lines
281 new = __xe_pmu_event_read(event);320 new = __xe_pmu_event_read(event);
282 } while (!local64_try_cmpxchg(&hwc->prev_count, &prev, new));321 } while (!local64_try_cmpxchg(&hwc->prev_count, &prev, new));
283 322
284 local64_add(new - prev, &event->count);323 /*
324 * GT frequency is not a monotonically increasing counter, so add the
325 * instantaneous value instead.
326 */
327 if (is_gt_frequency_event(event))
328 local64_add(new, &event->count);
329 else
330 local64_add(new - prev, &event->count);
285}331}
286 332
287static void xe_pmu_event_read(struct perf_event *event)333static void xe_pmu_event_read(struct perf_event *event)
@@ -351,6 +397,7 @@ static void xe_pmu_event_del(struct perf_event *event, int flags) · 63 unmodified lines
351}397}
352 398
353PMU_FORMAT_ATTR(gt, "config:60-63");399PMU_FORMAT_ATTR(gt, "config:60-63");
400PMU_FORMAT_ATTR(function, "config:44-59");
354PMU_FORMAT_ATTR(engine_class, "config:20-27");401PMU_FORMAT_ATTR(engine_class, "config:20-27");
355PMU_FORMAT_ATTR(engine_instance, "config:12-19");402PMU_FORMAT_ATTR(engine_instance, "config:12-19");
356PMU_FORMAT_ATTR(event, "config:0-11");403PMU_FORMAT_ATTR(event, "config:0-11");
@@ -359,6 +406,7 @@ static struct attribute *pmu_format_attrs[] = { · 2 unmodified lines
359 &format_attr_event.attr,406 &format_attr_event.attr,
360 &format_attr_engine_class.attr,407 &format_attr_engine_class.attr,
361 &format_attr_engine_instance.attr,408 &format_attr_engine_instance.attr,
409 &format_attr_function.attr,
362 &format_attr_gt.attr,410 &format_attr_gt.attr,
363 NULL,411 NULL,
364};412};
@@ -419,6 +467,10 @@ static ssize_t event_attr_show(struct device *dev, · 54 unmodified lines
419XE_EVENT_ATTR_SIMPLE(gt-c6-residency, gt_c6_residency, XE_PMU_EVENT_GT_C6_RESIDENCY, "ms");467XE_EVENT_ATTR_SIMPLE(gt-c6-residency, gt_c6_residency, XE_PMU_EVENT_GT_C6_RESIDENCY, "ms");
420XE_EVENT_ATTR_NOUNIT(engine-active-ticks, engine_active_ticks, XE_PMU_EVENT_ENGINE_ACTIVE_TICKS);468XE_EVENT_ATTR_NOUNIT(engine-active-ticks, engine_active_ticks, XE_PMU_EVENT_ENGINE_ACTIVE_TICKS);
421XE_EVENT_ATTR_NOUNIT(engine-total-ticks, engine_total_ticks, XE_PMU_EVENT_ENGINE_TOTAL_TICKS);469XE_EVENT_ATTR_NOUNIT(engine-total-ticks, engine_total_ticks, XE_PMU_EVENT_ENGINE_TOTAL_TICKS);
470XE_EVENT_ATTR_SIMPLE(gt-actual-frequency, gt_actual_frequency,
471 XE_PMU_EVENT_GT_ACTUAL_FREQUENCY, "MHz");
472XE_EVENT_ATTR_SIMPLE(gt-requested-frequency, gt_requested_frequency,
473 XE_PMU_EVENT_GT_REQUESTED_FREQUENCY, "MHz");
422 474
423static struct attribute *pmu_empty_event_attrs[] = {475static struct attribute *pmu_empty_event_attrs[] = {
424 /* Empty - all events are added as groups with .attr_update() */476 /* Empty - all events are added as groups with .attr_update() */
@@ -434,6 +486,8 @@ static const struct attribute_group *pmu_events_attr_update[] = { · 9 unmodified lines
434 &pmu_group_gt_c6_residency,486 &pmu_group_gt_c6_residency,
435 &pmu_group_engine_active_ticks,487 &pmu_group_engine_active_ticks,
436 &pmu_group_engine_total_ticks,488 &pmu_group_engine_total_ticks,
489 &pmu_group_gt_actual_frequency,
490 &pmu_group_gt_requested_frequency,
437 NULL,491 NULL,
438};492};
439 493
@@ -442,8 +496,11 @@ static void set_supported_events(struct xe_pmu *pmu) · 2 unmodified lines
442 struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);496 struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);
443 struct xe_gt *gt = xe_device_get_gt(xe, 0);497 struct xe_gt *gt = xe_device_get_gt(xe, 0);
444 498
445 if (!xe->info.skip_guc_pc)499 if (!xe->info.skip_guc_pc) {
446 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_GT_C6_RESIDENCY);500 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_GT_C6_RESIDENCY);
501 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_GT_ACTUAL_FREQUENCY);
502 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_GT_REQUESTED_FREQUENCY);
503 }
447 504
448 if (xe_guc_engine_activity_supported(&gt->uc.guc)) {505 if (xe_guc_engine_activity_supported(&gt->uc.guc)) {
449 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_ENGINE_ACTIVE_TICKS);506 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_ENGINE_ACTIVE_TICKS);
drivers/gpu/drm/xe/xe_pt.c+140−98
@@ -103,6 +103,7 @@ struct xe_pt *xe_pt_create(struct xe_vm *vm, struct xe_tile *tile, · 102 unmodified lines
103{103{
104 struct xe_pt *pt;104 struct xe_pt *pt;
105 struct xe_bo *bo;105 struct xe_bo *bo;
106 u32 bo_flags;
106 int err;107 int err;
107 108
108 if (level) {109 if (level) {
@@ -115,14 +116,16 @@ struct xe_pt *xe_pt_create(struct xe_vm *vm, struct xe_tile *tile, · 6 unmodified lines
115 if (!pt)116 if (!pt)
116 return ERR_PTR(-ENOMEM);117 return ERR_PTR(-ENOMEM);
117 118
119 bo_flags = XE_BO_FLAG_VRAM_IF_DGFX(tile) |
120 XE_BO_FLAG_IGNORE_MIN_PAGE_SIZE |
121 XE_BO_FLAG_NO_RESV_EVICT | XE_BO_FLAG_PAGETABLE;
122 if (vm->xef) /* userspace */
123 bo_flags |= XE_BO_FLAG_PINNED_LATE_RESTORE;
124
118 pt->level = level;125 pt->level = level;
119 bo = xe_bo_create_pin_map(vm->xe, tile, vm, SZ_4K,126 bo = xe_bo_create_pin_map(vm->xe, tile, vm, SZ_4K,
120 ttm_bo_type_kernel,127 ttm_bo_type_kernel,
121 XE_BO_FLAG_VRAM_IF_DGFX(tile) |128 bo_flags);
122 XE_BO_FLAG_IGNORE_MIN_PAGE_SIZE |
123 XE_BO_FLAG_PINNED |
124 XE_BO_FLAG_NO_RESV_EVICT |
125 XE_BO_FLAG_PAGETABLE);
126 if (IS_ERR(bo)) {129 if (IS_ERR(bo)) {
127 err = PTR_ERR(bo);130 err = PTR_ERR(bo);
128 goto err_kfree;131 goto err_kfree;
@@ -269,8 +272,11 @@ struct xe_pt_update { · 140 unmodified lines
269 bool preexisting;272 bool preexisting;
270};273};
271 274
275/**
276 * struct xe_pt_stage_bind_walk - Walk state for the stage_bind walk.
277 */
272struct xe_pt_stage_bind_walk {278struct xe_pt_stage_bind_walk {
273 /** base: The base class. */279 /** @base: The base class. */
274 struct xe_pt_walk base;280 struct xe_pt_walk base;
275 281
276 /* Input parameters for the walk */282 /* Input parameters for the walk */
@@ -278,15 +284,19 @@ struct xe_pt_stage_bind_walk { · 1 unmodified line
278 struct xe_vm *vm;284 struct xe_vm *vm;
279 /** @tile: The tile we're building for. */285 /** @tile: The tile we're building for. */
280 struct xe_tile *tile;286 struct xe_tile *tile;
281 /** @default_pte: PTE flag only template. No address is associated */287 /** @default_vram_pte: PTE flag only template for VRAM. No address is associated */
282 u64 default_pte;288 u64 default_vram_pte;
289 /** @default_system_pte: PTE flag only template for System. No address is associated */
290 u64 default_system_pte;
283 /** @dma_offset: DMA offset to add to the PTE. */291 /** @dma_offset: DMA offset to add to the PTE. */
284 u64 dma_offset;292 u64 dma_offset;
285 /**293 /**
286 * @needs_64k: This address range enforces 64K alignment and294 * @needs_64K: This address range enforces 64K alignment and
287 * granularity.295 * granularity on VRAM.
288 */296 */
289 bool needs_64K;297 bool needs_64K;
298 /** @clear_pt: clear page table entries during the bind walk */
299 bool clear_pt;
290 /**300 /**
291 * @vma: VMA being mapped301 * @vma: VMA being mapped
292 */302 */
@@ -299,6 +309,7 @@ struct xe_pt_stage_bind_walk { · 6 unmodified lines
299 u64 va_curs_start;309 u64 va_curs_start;
300 310
301 /* Output */311 /* Output */
312 /** @wupd: Walk output data for page-table updates. */
302 struct xe_walk_update {313 struct xe_walk_update {
303 /** @wupd.entries: Caller provided storage. */314 /** @wupd.entries: Caller provided storage. */
304 struct xe_vm_pgtable_update *entries;315 struct xe_vm_pgtable_update *entries;
@@ -316,7 +327,7 @@ struct xe_pt_stage_bind_walk { · 11 unmodified lines
316 u64 l0_end_addr;327 u64 l0_end_addr;
317 /** @addr_64K: The start address of the current 64K chunk. */328 /** @addr_64K: The start address of the current 64K chunk. */
318 u64 addr_64K;329 u64 addr_64K;
319 /** @found_64: Whether @add_64K actually points to a 64K chunk. */330 /** @found_64K: Whether @add_64K actually points to a 64K chunk. */
320 bool found_64K;331 bool found_64K;
321};332};
322 333
@@ -436,6 +447,10 @@ static bool xe_pt_hugepte_possible(u64 addr, u64 next, unsigned int level, · 113 unmodified lines
436 if (xe_vma_is_null(xe_walk->vma))447 if (xe_vma_is_null(xe_walk->vma))
437 return true;448 return true;
438 449
450 /* if we are clearing page table, no dma addresses*/
451 if (xe_walk->clear_pt)
452 return true;
453
439 /* Is the DMA address huge PTE size aligned? */454 /* Is the DMA address huge PTE size aligned? */
440 size = next - addr;455 size = next - addr;
441 dma = addr - xe_walk->va_curs_start + xe_res_dma(xe_walk->curs);456 dma = addr - xe_walk->va_curs_start + xe_res_dma(xe_walk->curs);
@@ -515,24 +530,35 @@ xe_pt_stage_bind_entry(struct xe_ptw *parent, pgoff_t offset, · 73 unmodified lines
515 if (level == 0 || xe_pt_hugepte_possible(addr, next, level, xe_walk)) {530 if (level == 0 || xe_pt_hugepte_possible(addr, next, level, xe_walk)) {
516 struct xe_res_cursor *curs = xe_walk->curs;531 struct xe_res_cursor *curs = xe_walk->curs;
517 bool is_null = xe_vma_is_null(xe_walk->vma);532 bool is_null = xe_vma_is_null(xe_walk->vma);
533 bool is_vram = is_null ? false : xe_res_is_vram(curs);
518 534
519 XE_WARN_ON(xe_walk->va_curs_start != addr);535 XE_WARN_ON(xe_walk->va_curs_start != addr);
520 536
521 pte = vm->pt_ops->pte_encode_vma(is_null ? 0 :537 if (xe_walk->clear_pt) {
522 xe_res_dma(curs) + xe_walk->dma_offset,538 pte = 0;
523 xe_walk->vma, pat_index, level);539 } else {
524 pte |= xe_walk->default_pte;540 pte = vm->pt_ops->pte_encode_vma(is_null ? 0 :
541 xe_res_dma(curs) +
542 xe_walk->dma_offset,
543 xe_walk->vma,
544 pat_index, level);
545 if (!is_null)
546 pte |= is_vram ? xe_walk->default_vram_pte :
547 xe_walk->default_system_pte;
525 548
526 /*549 /*
527 * Set the XE_PTE_PS64 hint if possible, otherwise if550 * Set the XE_PTE_PS64 hint if possible, otherwise if
528 * this device *requires* 64K PTE size for VRAM, fail.551 * this device *requires* 64K PTE size for VRAM, fail.
529 */552 */
530 if (level == 0 && !xe_parent->is_compact) {553 if (level == 0 && !xe_parent->is_compact) {
531 if (xe_pt_is_pte_ps64K(addr, next, xe_walk)) {554 if (xe_pt_is_pte_ps64K(addr, next, xe_walk)) {
532 xe_walk->vma->gpuva.flags |= XE_VMA_PTE_64K;555 xe_walk->vma->gpuva.flags |=
533 pte |= XE_PTE_PS64;556 XE_VMA_PTE_64K;
534 } else if (XE_WARN_ON(xe_walk->needs_64K)) {557 pte |= XE_PTE_PS64;
535 return -EINVAL;558 } else if (XE_WARN_ON(xe_walk->needs_64K &&
559 is_vram)) {
560 return -EINVAL;
561 }
536 }562 }
537 }563 }
538 564
@@ -540,7 +566,7 @@ xe_pt_stage_bind_entry(struct xe_ptw *parent, pgoff_t offset, · 1 unmodified line
540 if (unlikely(ret))566 if (unlikely(ret))
541 return ret;567 return ret;
542 568
543 if (!is_null)569 if (!is_null && !xe_walk->clear_pt)
544 xe_res_next(curs, next - addr);570 xe_res_next(curs, next - addr);
545 xe_walk->va_curs_start = next;571 xe_walk->va_curs_start = next;
546 xe_walk->vma->gpuva.flags |= (XE_VMA_PTE_4K << level);572 xe_walk->vma->gpuva.flags |= (XE_VMA_PTE_4K << level);
@@ -603,6 +629,44 @@ static const struct xe_pt_walk_ops xe_pt_stage_bind_ops = { · 56 unmodified lines
603 .pt_entry = xe_pt_stage_bind_entry,629 .pt_entry = xe_pt_stage_bind_entry,
604};630};
605 631
632/*
633 * Default atomic expectations for different allocation scenarios are as follows:
634 *
635 * 1. Traditional API: When the VM is not in LR mode:
636 * - Device atomics are expected to function with all allocations.
637 *
638 * 2. Compute/SVM API: When the VM is in LR mode:
639 * - Device atomics are the default behavior when the bo is placed in a single region.
640 * - In all other cases device atomics will be disabled with AE=0 until an application
641 * request differently using a ioctl like madvise.
642 */
643static bool xe_atomic_for_vram(struct xe_vm *vm)
644{
645 return true;
646}
647
648static bool xe_atomic_for_system(struct xe_vm *vm, struct xe_bo *bo)
649{
650 struct xe_device *xe = vm->xe;
651
652 if (!xe->info.has_device_atomics_on_smem)
653 return false;
654
655 /*
656 * If a SMEM+LMEM allocation is backed by SMEM, a device
657 * atomics will cause a gpu page fault and which then
658 * gets migrated to LMEM, bind such allocations with
659 * device atomics enabled.
660 *
661 * TODO: Revisit this. Perhaps add something like a
662 * fault_on_atomics_in_system UAPI flag.
663 * Note that this also prohibits GPU atomics in LR mode for
664 * userptr and system memory on DGFX.
665 */
666 return (!IS_DGFX(xe) || (!xe_vm_in_lr_mode(vm) ||
667 (bo && xe_bo_has_single_placement(bo))));
668}
669
606/**670/**
607 * xe_pt_stage_bind() - Build a disconnected page-table tree for a given address671 * xe_pt_stage_bind() - Build a disconnected page-table tree for a given address
608 * range.672 * range.
@@ -612,6 +676,7 @@ static const struct xe_pt_walk_ops xe_pt_stage_bind_ops = { · 3 unmodified lines
612 * @entries: Storage for the update entries used for connecting the tree to676 * @entries: Storage for the update entries used for connecting the tree to
613 * the main tree at commit time.677 * the main tree at commit time.
614 * @num_entries: On output contains the number of @entries used.678 * @num_entries: On output contains the number of @entries used.
679 * @clear_pt: Clear the page table entries.
615 *680 *
616 * This function builds a disconnected page-table tree for a given address681 * This function builds a disconnected page-table tree for a given address
617 * range. The tree is connected to the main vm tree for the gpu using682 * range. The tree is connected to the main vm tree for the gpu using
@@ -625,13 +690,13 @@ static const struct xe_pt_walk_ops xe_pt_stage_bind_ops = { · 7 unmodified lines
625static int690static int
626xe_pt_stage_bind(struct xe_tile *tile, struct xe_vma *vma,691xe_pt_stage_bind(struct xe_tile *tile, struct xe_vma *vma,
627 struct xe_svm_range *range,692 struct xe_svm_range *range,
628 struct xe_vm_pgtable_update *entries, u32 *num_entries)693 struct xe_vm_pgtable_update *entries,
694 u32 *num_entries, bool clear_pt)
629{695{
630 struct xe_device *xe = tile_to_xe(tile);696 struct xe_device *xe = tile_to_xe(tile);
631 struct xe_bo *bo = xe_vma_bo(vma);697 struct xe_bo *bo = xe_vma_bo(vma);
632 bool is_devmem = !xe_vma_is_userptr(vma) && bo &&
633 (xe_bo_is_vram(bo) || xe_bo_is_stolen_devmem(bo));
634 struct xe_res_cursor curs;698 struct xe_res_cursor curs;
699 struct xe_vm *vm = xe_vma_vm(vma);
635 struct xe_pt_stage_bind_walk xe_walk = {700 struct xe_pt_stage_bind_walk xe_walk = {
636 .base = {701 .base = {
637 .ops = &xe_pt_stage_bind_ops,702 .ops = &xe_pt_stage_bind_ops,
@@ -639,34 +704,31 @@ xe_pt_stage_bind(struct xe_tile *tile, struct xe_vma *vma, · 1 unmodified line
639 .max_level = XE_PT_HIGHEST_LEVEL,704 .max_level = XE_PT_HIGHEST_LEVEL,
640 .staging = true,705 .staging = true,
641 },706 },
642 .vm = xe_vma_vm(vma),707 .vm = vm,
643 .tile = tile,708 .tile = tile,
644 .curs = &curs,709 .curs = &curs,
645 .va_curs_start = range ? range->base.itree.start :710 .va_curs_start = range ? range->base.itree.start :
646 xe_vma_start(vma),711 xe_vma_start(vma),
647 .vma = vma,712 .vma = vma,
648 .wupd.entries = entries,713 .wupd.entries = entries,
714 .clear_pt = clear_pt,
649 };715 };
650 struct xe_pt *pt = xe_vma_vm(vma)->pt_root[tile->id];716 struct xe_pt *pt = vm->pt_root[tile->id];
651 int ret;717 int ret;
652 718
653 if (range) {719 if (range) {
654 /* Move this entire thing to xe_svm.c? */720 /* Move this entire thing to xe_svm.c? */
655 xe_svm_notifier_lock(xe_vma_vm(vma));721 xe_svm_notifier_lock(vm);
656 if (!xe_svm_range_pages_valid(range)) {722 if (!xe_svm_range_pages_valid(range)) {
657 xe_svm_range_debug(range, "BIND PREPARE - RETRY");723 xe_svm_range_debug(range, "BIND PREPARE - RETRY");
658 xe_svm_notifier_unlock(xe_vma_vm(vma));724 xe_svm_notifier_unlock(vm);
659 return -EAGAIN;725 return -EAGAIN;
660 }726 }
661 if (xe_svm_range_has_dma_mapping(range)) {727 if (xe_svm_range_has_dma_mapping(range)) {
662 xe_res_first_dma(range->base.dma_addr, 0,728 xe_res_first_dma(range->base.dma_addr, 0,
663 range->base.itree.last + 1 - range->base.itree.start,729 range->base.itree.last + 1 - range->base.itree.start,
664 &curs);730 &curs);
665 is_devmem = xe_res_is_vram(&curs);731 xe_svm_range_debug(range, "BIND PREPARE - MIXED");
666 if (is_devmem)
667 xe_svm_range_debug(range, "BIND PREPARE - DMA VRAM");
668 else
669 xe_svm_range_debug(range, "BIND PREPARE - DMA");
670 } else {732 } else {
671 xe_assert(xe, false);733 xe_assert(xe, false);
672 }734 }
@@ -674,54 +736,21 @@ xe_pt_stage_bind(struct xe_tile *tile, struct xe_vma *vma, · 1 unmodified line
674 * Note, when unlocking the resource cursor dma addresses may become736 * Note, when unlocking the resource cursor dma addresses may become
675 * stale, but the bind will be aborted anyway at commit time.737 * stale, but the bind will be aborted anyway at commit time.
676 */738 */
677 xe_svm_notifier_unlock(xe_vma_vm(vma));739 xe_svm_notifier_unlock(vm);
678 }740 }
679 741
680 xe_walk.needs_64K = (xe_vma_vm(vma)->flags & XE_VM_FLAG_64K) && is_devmem;742 xe_walk.needs_64K = (vm->flags & XE_VM_FLAG_64K);
743 if (clear_pt)
744 goto walk_pt;
681 745
682 /**
683 * Default atomic expectations for different allocation scenarios are as follows:
684 *
685 * 1. Traditional API: When the VM is not in LR mode:
686 * - Device atomics are expected to function with all allocations.
687 *
688 * 2. Compute/SVM API: When the VM is in LR mode:
689 * - Device atomics are the default behavior when the bo is placed in a single region.
690 * - In all other cases device atomics will be disabled with AE=0 until an application
691 * request differently using a ioctl like madvise.
692 */
693 if (vma->gpuva.flags & XE_VMA_ATOMIC_PTE_BIT) {746 if (vma->gpuva.flags & XE_VMA_ATOMIC_PTE_BIT) {
694 if (xe_vm_in_lr_mode(xe_vma_vm(vma))) {747 xe_walk.default_vram_pte = xe_atomic_for_vram(vm) ? XE_USM_PPGTT_PTE_AE : 0;
695 if (bo && xe_bo_has_single_placement(bo))748 xe_walk.default_system_pte = xe_atomic_for_system(vm, bo) ?
696 xe_walk.default_pte |= XE_USM_PPGTT_PTE_AE;749 XE_USM_PPGTT_PTE_AE : 0;
697 /**
698 * If a SMEM+LMEM allocation is backed by SMEM, a device
699 * atomics will cause a gpu page fault and which then
700 * gets migrated to LMEM, bind such allocations with
701 * device atomics enabled.
702 */
703 else if (is_devmem)
704 xe_walk.default_pte |= XE_USM_PPGTT_PTE_AE;
705 } else {
706 xe_walk.default_pte |= XE_USM_PPGTT_PTE_AE;
707 }
708
709 /**
710 * Unset AE if the platform(PVC) doesn't support it on an
711 * allocation
712 */
713 if (!xe->info.has_device_atomics_on_smem && !is_devmem)
714 xe_walk.default_pte &= ~XE_USM_PPGTT_PTE_AE;
715 }
716
717 if (is_devmem) {
718 xe_walk.default_pte |= XE_PPGTT_PTE_DM;
719 xe_walk.dma_offset = bo ? vram_region_gpu_offset(bo->ttm.resource) : 0;
720 }750 }
721 751
722 if (!xe_vma_has_no_bo(vma) && xe_bo_is_stolen(bo))752 xe_walk.default_vram_pte |= XE_PPGTT_PTE_DM;
723 xe_walk.dma_offset = xe_ttm_stolen_gpu_offset(xe_bo_device(bo));753 xe_walk.dma_offset = bo ? vram_region_gpu_offset(bo->ttm.resource) : 0;
724
725 if (!range)754 if (!range)
726 xe_bo_assert_held(bo);755 xe_bo_assert_held(bo);
727 756
@@ -739,6 +768,7 @@ xe_pt_stage_bind(struct xe_tile *tile, struct xe_vma *vma, · 11 unmodified lines
739 curs.size = xe_vma_size(vma);768 curs.size = xe_vma_size(vma);
740 }769 }
741 770
771walk_pt:
742 ret = xe_pt_walk_range(&pt->base, pt->level,772 ret = xe_pt_walk_range(&pt->base, pt->level,
743 range ? range->base.itree.start : xe_vma_start(vma),773 range ? range->base.itree.start : xe_vma_start(vma),
744 range ? range->base.itree.last + 1 : xe_vma_end(vma),774 range ? range->base.itree.last + 1 : xe_vma_end(vma),
@@ -1103,12 +1133,14 @@ static void xe_pt_free_bind(struct xe_vm_pgtable_update *entries, · 358 unmodified lines
1103static int1133static int
1104xe_pt_prepare_bind(struct xe_tile *tile, struct xe_vma *vma,1134xe_pt_prepare_bind(struct xe_tile *tile, struct xe_vma *vma,
1105 struct xe_svm_range *range,1135 struct xe_svm_range *range,
1106 struct xe_vm_pgtable_update *entries, u32 *num_entries)1136 struct xe_vm_pgtable_update *entries,
1137 u32 *num_entries, bool invalidate_on_bind)
1107{1138{
1108 int err;1139 int err;
1109 1140
1110 *num_entries = 0;1141 *num_entries = 0;
1111 err = xe_pt_stage_bind(tile, vma, range, entries, num_entries);1142 err = xe_pt_stage_bind(tile, vma, range, entries, num_entries,
1143 invalidate_on_bind);
1112 if (!err)1144 if (!err)
1113 xe_tile_assert(tile, *num_entries);1145 xe_tile_assert(tile, *num_entries);
1114 1146
@@ -1420,6 +1452,7 @@ static int xe_pt_userptr_pre_commit(struct xe_migrate_pt_update *pt_update) · 305 unmodified lines
1420 return err;1452 return err;
1421}1453}
1422 1454
1455#if IS_ENABLED(CONFIG_DRM_XE_GPUSVM)
1423static int xe_pt_svm_pre_commit(struct xe_migrate_pt_update *pt_update)1456static int xe_pt_svm_pre_commit(struct xe_migrate_pt_update *pt_update)
1424{1457{
1425 struct xe_vm *vm = pt_update->vops->vm;1458 struct xe_vm *vm = pt_update->vops->vm;
@@ -1453,6 +1486,7 @@ static int xe_pt_svm_pre_commit(struct xe_migrate_pt_update *pt_update) · 27 unmodified lines
1453 1486
1454 return 0;1487 return 0;
1455}1488}
1489#endif
1456 1490
1457struct invalidation_fence {1491struct invalidation_fence {
1458 struct xe_gt_tlb_invalidation_fence base;1492 struct xe_gt_tlb_invalidation_fence base;
@@ -1791,7 +1825,7 @@ static int vma_reserve_fences(struct xe_device *xe, struct xe_vma *vma) · 332 unmodified lines
1791 1825
1792static int bind_op_prepare(struct xe_vm *vm, struct xe_tile *tile,1826static int bind_op_prepare(struct xe_vm *vm, struct xe_tile *tile,
1793 struct xe_vm_pgtable_update_ops *pt_update_ops,1827 struct xe_vm_pgtable_update_ops *pt_update_ops,
1794 struct xe_vma *vma)1828 struct xe_vma *vma, bool invalidate_on_bind)
1795{1829{
1796 u32 current_op = pt_update_ops->current_op;1830 u32 current_op = pt_update_ops->current_op;
1797 struct xe_vm_pgtable_update_op *pt_op = &pt_update_ops->ops[current_op];1831 struct xe_vm_pgtable_update_op *pt_op = &pt_update_ops->ops[current_op];
@@ -1813,7 +1847,7 @@ static int bind_op_prepare(struct xe_vm *vm, struct xe_tile *tile, · 15 unmodified lines
1813 return err;1847 return err;
1814 1848
1815 err = xe_pt_prepare_bind(tile, vma, NULL, pt_op->entries,1849 err = xe_pt_prepare_bind(tile, vma, NULL, pt_op->entries,
1816 &pt_op->num_entries);1850 &pt_op->num_entries, invalidate_on_bind);
1817 if (!err) {1851 if (!err) {
1818 xe_tile_assert(tile, pt_op->num_entries <=1852 xe_tile_assert(tile, pt_op->num_entries <=
1819 ARRAY_SIZE(pt_op->entries));1853 ARRAY_SIZE(pt_op->entries));
@@ -1835,11 +1869,11 @@ static int bind_op_prepare(struct xe_vm *vm, struct xe_tile *tile, · 15 unmodified lines
1835 * If !rebind, and scratch enabled VMs, there is a chance the scratch1869 * If !rebind, and scratch enabled VMs, there is a chance the scratch
1836 * PTE is already cached in the TLB so it needs to be invalidated.1870 * PTE is already cached in the TLB so it needs to be invalidated.
1837 * On !LR VMs this is done in the ring ops preceding a batch, but on1871 * On !LR VMs this is done in the ring ops preceding a batch, but on
1838 * non-faulting LR, in particular on user-space batch buffer chaining,1872 * LR, in particular on user-space batch buffer chaining, it needs to
1839 * it needs to be done here.1873 * be done here.
1840 */1874 */
1841 if ((!pt_op->rebind && xe_vm_has_scratch(vm) &&1875 if ((!pt_op->rebind && xe_vm_has_scratch(vm) &&
1842 xe_vm_in_preempt_fence_mode(vm)))1876 xe_vm_in_lr_mode(vm)))
1843 pt_update_ops->needs_invalidation = true;1877 pt_update_ops->needs_invalidation = true;
1844 else if (pt_op->rebind && !xe_vm_in_lr_mode(vm))1878 else if (pt_op->rebind && !xe_vm_in_lr_mode(vm))
1845 /* We bump also if batch_invalidate_tlb is true */1879 /* We bump also if batch_invalidate_tlb is true */
@@ -1875,7 +1909,7 @@ static int bind_range_prepare(struct xe_vm *vm, struct xe_tile *tile, · 29 unmodified lines
1875 pt_op->rebind = BIT(tile->id) & range->tile_present;1909 pt_op->rebind = BIT(tile->id) & range->tile_present;
1876 1910
1877 err = xe_pt_prepare_bind(tile, vma, range, pt_op->entries,1911 err = xe_pt_prepare_bind(tile, vma, range, pt_op->entries,
1878 &pt_op->num_entries);1912 &pt_op->num_entries, false);
1879 if (!err) {1913 if (!err) {
1880 xe_tile_assert(tile, pt_op->num_entries <=1914 xe_tile_assert(tile, pt_op->num_entries <=
1881 ARRAY_SIZE(pt_op->entries));1915 ARRAY_SIZE(pt_op->entries));
@@ -1987,11 +2021,13 @@ static int op_prepare(struct xe_vm *vm, · 105 unmodified lines
1987 2021
1988 switch (op->base.op) {2022 switch (op->base.op) {
1989 case DRM_GPUVA_OP_MAP:2023 case DRM_GPUVA_OP_MAP:
1990 if ((!op->map.immediate && xe_vm_in_fault_mode(vm)) ||2024 if ((!op->map.immediate && xe_vm_in_fault_mode(vm) &&
2025 !op->map.invalidate_on_bind) ||
1991 op->map.is_cpu_addr_mirror)2026 op->map.is_cpu_addr_mirror)
1992 break;2027 break;
1993 2028
1994 err = bind_op_prepare(vm, tile, pt_update_ops, op->map.vma);2029 err = bind_op_prepare(vm, tile, pt_update_ops, op->map.vma,
2030 op->map.invalidate_on_bind);
1995 pt_update_ops->wait_vm_kernel = true;2031 pt_update_ops->wait_vm_kernel = true;
1996 break;2032 break;
1997 case DRM_GPUVA_OP_REMAP:2033 case DRM_GPUVA_OP_REMAP:
@@ -2005,12 +2041,12 @@ static int op_prepare(struct xe_vm *vm, · 7 unmodified lines
2005 2041
2006 if (!err && op->remap.prev) {2042 if (!err && op->remap.prev) {
2007 err = bind_op_prepare(vm, tile, pt_update_ops,2043 err = bind_op_prepare(vm, tile, pt_update_ops,
2008 op->remap.prev);2044 op->remap.prev, false);
2009 pt_update_ops->wait_vm_bookkeep = true;2045 pt_update_ops->wait_vm_bookkeep = true;
2010 }2046 }
2011 if (!err && op->remap.next) {2047 if (!err && op->remap.next) {
2012 err = bind_op_prepare(vm, tile, pt_update_ops,2048 err = bind_op_prepare(vm, tile, pt_update_ops,
2013 op->remap.next);2049 op->remap.next, false);
2014 pt_update_ops->wait_vm_bookkeep = true;2050 pt_update_ops->wait_vm_bookkeep = true;
2015 }2051 }
2016 break;2052 break;
@@ -2032,7 +2068,7 @@ static int op_prepare(struct xe_vm *vm, · 15 unmodified lines
2032 if (xe_vma_is_cpu_addr_mirror(vma))2068 if (xe_vma_is_cpu_addr_mirror(vma))
2033 break;2069 break;
2034 2070
2035 err = bind_op_prepare(vm, tile, pt_update_ops, vma);2071 err = bind_op_prepare(vm, tile, pt_update_ops, vma, false);
2036 pt_update_ops->wait_vm_kernel = true;2072 pt_update_ops->wait_vm_kernel = true;
2037 break;2073 break;
2038 }2074 }
@@ -2115,7 +2151,7 @@ ALLOW_ERROR_INJECTION(xe_pt_update_ops_prepare, ERRNO); · 76 unmodified lines
2115static void bind_op_commit(struct xe_vm *vm, struct xe_tile *tile,2151static void bind_op_commit(struct xe_vm *vm, struct xe_tile *tile,
2116 struct xe_vm_pgtable_update_ops *pt_update_ops,2152 struct xe_vm_pgtable_update_ops *pt_update_ops,
2117 struct xe_vma *vma, struct dma_fence *fence,2153 struct xe_vma *vma, struct dma_fence *fence,
2118 struct dma_fence *fence2)2154 struct dma_fence *fence2, bool invalidate_on_bind)
2119{2155{
2120 xe_tile_assert(tile, !xe_vma_is_cpu_addr_mirror(vma));2156 xe_tile_assert(tile, !xe_vma_is_cpu_addr_mirror(vma));
2121 2157
@@ -2132,6 +2168,8 @@ static void bind_op_commit(struct xe_vm *vm, struct xe_tile *tile, · 10 unmodified lines
2132 }2168 }
2133 vma->tile_present |= BIT(tile->id);2169 vma->tile_present |= BIT(tile->id);
2134 vma->tile_staged &= ~BIT(tile->id);2170 vma->tile_staged &= ~BIT(tile->id);
2171 if (invalidate_on_bind)
2172 vma->tile_invalidated |= BIT(tile->id);
2135 if (xe_vma_is_userptr(vma)) {2173 if (xe_vma_is_userptr(vma)) {
2136 lockdep_assert_held_read(&vm->userptr.notifier_lock);2174 lockdep_assert_held_read(&vm->userptr.notifier_lock);
2137 to_userptr_vma(vma)->userptr.initial_bind = true;2175 to_userptr_vma(vma)->userptr.initial_bind = true;
@@ -2193,7 +2231,7 @@ static void op_commit(struct xe_vm *vm, · 55 unmodified lines
2193 break;2231 break;
2194 2232
2195 bind_op_commit(vm, tile, pt_update_ops, op->map.vma, fence,2233 bind_op_commit(vm, tile, pt_update_ops, op->map.vma, fence,
2196 fence2);2234 fence2, op->map.invalidate_on_bind);
2197 break;2235 break;
2198 case DRM_GPUVA_OP_REMAP:2236 case DRM_GPUVA_OP_REMAP:
2199 {2237 {
@@ -2206,10 +2244,10 @@ static void op_commit(struct xe_vm *vm, · 6 unmodified lines
2206 2244
2207 if (op->remap.prev)2245 if (op->remap.prev)
2208 bind_op_commit(vm, tile, pt_update_ops, op->remap.prev,2246 bind_op_commit(vm, tile, pt_update_ops, op->remap.prev,
2209 fence, fence2);2247 fence, fence2, false);
2210 if (op->remap.next)2248 if (op->remap.next)
2211 bind_op_commit(vm, tile, pt_update_ops, op->remap.next,2249 bind_op_commit(vm, tile, pt_update_ops, op->remap.next,
2212 fence, fence2);2250 fence, fence2, false);
2213 break;2251 break;
2214 }2252 }
2215 case DRM_GPUVA_OP_UNMAP:2253 case DRM_GPUVA_OP_UNMAP:
@@ -2227,7 +2265,7 @@ static void op_commit(struct xe_vm *vm, · 11 unmodified lines
2227 2265
2228 if (!xe_vma_is_cpu_addr_mirror(vma))2266 if (!xe_vma_is_cpu_addr_mirror(vma))
2229 bind_op_commit(vm, tile, pt_update_ops, vma, fence,2267 bind_op_commit(vm, tile, pt_update_ops, vma, fence,
2230 fence2);2268 fence2, false);
2231 break;2269 break;
2232 }2270 }
2233 case DRM_GPUVA_OP_DRIVER:2271 case DRM_GPUVA_OP_DRIVER:
@@ -2257,11 +2295,15 @@ static const struct xe_migrate_pt_update_ops userptr_migrate_ops = { · 23 unmodified lines
2257 .pre_commit = xe_pt_userptr_pre_commit,2295 .pre_commit = xe_pt_userptr_pre_commit,
2258};2296};
2259 2297
2298#if IS_ENABLED(CONFIG_DRM_XE_GPUSVM)
2260static const struct xe_migrate_pt_update_ops svm_migrate_ops = {2299static const struct xe_migrate_pt_update_ops svm_migrate_ops = {
2261 .populate = xe_vm_populate_pgtable,2300 .populate = xe_vm_populate_pgtable,
2262 .clear = xe_migrate_clear_pgtable_callback,2301 .clear = xe_migrate_clear_pgtable_callback,
2263 .pre_commit = xe_pt_svm_pre_commit,2302 .pre_commit = xe_pt_svm_pre_commit,
2264};2303};
2304#else
2305static const struct xe_migrate_pt_update_ops svm_migrate_ops;
2306#endif
2265 2307
2266/**2308/**
2267 * xe_pt_update_ops_run() - Run PT update operations2309 * xe_pt_update_ops_run() - Run PT update operations
drivers/gpu/drm/xe/xe_query.c+1−1
@@ -340,7 +340,7 @@ static int query_config(struct xe_device *xe, struct drm_xe_device_query *query) · 339 unmodified lines
340 if (xe_device_get_root_tile(xe)->mem.vram.usable_size)340 if (xe_device_get_root_tile(xe)->mem.vram.usable_size)
341 config->info[DRM_XE_QUERY_CONFIG_FLAGS] |=341 config->info[DRM_XE_QUERY_CONFIG_FLAGS] |=
342 DRM_XE_QUERY_CONFIG_FLAG_HAS_VRAM;342 DRM_XE_QUERY_CONFIG_FLAG_HAS_VRAM;
343 if (xe->info.has_usm && IS_ENABLED(CONFIG_DRM_GPUSVM))343 if (xe->info.has_usm && IS_ENABLED(CONFIG_DRM_XE_GPUSVM))
344 config->info[DRM_XE_QUERY_CONFIG_FLAGS] |=344 config->info[DRM_XE_QUERY_CONFIG_FLAGS] |=
345 DRM_XE_QUERY_CONFIG_FLAG_HAS_CPU_ADDR_MIRROR;345 DRM_XE_QUERY_CONFIG_FLAG_HAS_CPU_ADDR_MIRROR;
346 config->info[DRM_XE_QUERY_CONFIG_FLAGS] |=346 config->info[DRM_XE_QUERY_CONFIG_FLAGS] |=
drivers/gpu/drm/xe/xe_reg_sr.c+3−0
@@ -173,6 +173,9 @@ void xe_reg_sr_apply_mmio(struct xe_reg_sr *sr, struct xe_gt *gt) · 172 unmodified lines
173 if (xa_empty(&sr->xa))173 if (xa_empty(&sr->xa))
174 return;174 return;
175 175
176 if (IS_SRIOV_VF(gt_to_xe(gt)))
177 return;
178
176 xe_gt_dbg(gt, "Applying %s save-restore MMIOs\n", sr->name);179 xe_gt_dbg(gt, "Applying %s save-restore MMIOs\n", sr->name);
177 180
178 fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);181 fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
drivers/gpu/drm/xe/xe_ring_ops_types.h+1−1
@@ -8,7 +8,7 @@ · 7 unmodified lines
8 8
9struct xe_sched_job;9struct xe_sched_job;
10 10
11#define MAX_JOB_SIZE_DW 4811#define MAX_JOB_SIZE_DW 58
12#define MAX_JOB_SIZE_BYTES (MAX_JOB_SIZE_DW * 4)12#define MAX_JOB_SIZE_BYTES (MAX_JOB_SIZE_DW * 4)
13 13
14/**14/**
drivers/gpu/drm/xe/xe_rtp.c+0−3
@@ -258,9 +258,6 @@ void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx, · 257 unmodified lines
258 258
259 rtp_get_context(ctx, &hwe, &gt, &xe);259 rtp_get_context(ctx, &hwe, &gt, &xe);
260 260
261 if (IS_SRIOV_VF(xe))
262 return;
263
264 xe_assert(xe, entries);261 xe_assert(xe, entries);
265 262
266 for (entry = entries; entry - entries < n_entries; entry++) {263 for (entry = entries; entry - entries < n_entries; entry++) {
drivers/gpu/drm/xe/xe_sa.c+2−1
@@ -60,7 +60,8 @@ struct xe_sa_manager *__xe_sa_bo_manager_init(struct xe_tile *tile, u32 size, u3 · 59 unmodified lines
60 bo = xe_managed_bo_create_pin_map(xe, tile, size,60 bo = xe_managed_bo_create_pin_map(xe, tile, size,
61 XE_BO_FLAG_VRAM_IF_DGFX(tile) |61 XE_BO_FLAG_VRAM_IF_DGFX(tile) |
62 XE_BO_FLAG_GGTT |62 XE_BO_FLAG_GGTT |
63 XE_BO_FLAG_GGTT_INVALIDATE);63 XE_BO_FLAG_GGTT_INVALIDATE |
64 XE_BO_FLAG_PINNED_NORESTORE);
64 if (IS_ERR(bo)) {65 if (IS_ERR(bo)) {
65 drm_err(&xe->drm, "Failed to prepare %uKiB BO for SA manager (%pe)\n",66 drm_err(&xe->drm, "Failed to prepare %uKiB BO for SA manager (%pe)\n",
66 size / SZ_1K, bo);67 size / SZ_1K, bo);
drivers/gpu/drm/xe/xe_survivability_mode.c+50−19
@@ -10,6 +10,7 @@ · 9 unmodified lines
10#include <linux/pci.h>10#include <linux/pci.h>
11#include <linux/sysfs.h>11#include <linux/sysfs.h>
12 12
13#include "xe_configfs.h"
13#include "xe_device.h"14#include "xe_device.h"
14#include "xe_gt.h"15#include "xe_gt.h"
15#include "xe_heci_gsc.h"16#include "xe_heci_gsc.h"
@@ -28,20 +29,32 @@ · 12 unmodified lines
28 * This is implemented by loading the driver with bare minimum (no drm card) to allow the firmware29 * This is implemented by loading the driver with bare minimum (no drm card) to allow the firmware
29 * to be flashed through mei and collect telemetry. The driver's probe flow is modified30 * to be flashed through mei and collect telemetry. The driver's probe flow is modified
30 * such that it enters survivability mode when pcode initialization is incomplete and boot status31 * such that it enters survivability mode when pcode initialization is incomplete and boot status
31 * denotes a failure. The driver then populates the survivability_mode PCI sysfs indicating32 * denotes a failure.
32 * survivability mode and provides additional information required for debug
33 *33 *
34 * KMD exposes below admin-only readable sysfs in survivability mode34 * Survivability mode can also be entered manually using the survivability mode attribute available
35 * through configfs which is beneficial in several usecases. It can be used to address scenarios
36 * where pcode does not detect failure or for validation purposes. It can also be used in
37 * In-Field-Repair (IFR) to repair a single card without impacting the other cards in a node.
35 *38 *
36 * device/survivability_mode: The presence of this file indicates that the card is in survivability39 * Use below command enable survivability mode manually::
37 * mode. Also, provides additional information on why the driver entered
38 * survivability mode.
39 *40 *
40 * Capability Information - Provides boot status41 * # echo 1 > /sys/kernel/config/xe/0000:03:00.0/survivability_mode
41 * Postcode Information - Provides information about the failure42 *
42 * Overflow Information - Provides history of previous failures43 * Refer :ref:`xe_configfs` for more details on how to use configfs
43 * Auxiliary Information - Certain failures may have information in44 *
44 * addition to postcode information45 * Survivability mode is indicated by the below admin-only readable sysfs which provides additional
46 * debug information::
47 *
48 * /sys/bus/pci/devices/<device>/surivability_mode
49 *
50 * Capability Information:
51 * Provides boot status
52 * Postcode Information:
53 * Provides information about the failure
54 * Overflow Information
55 * Provides history of previous failures
56 * Auxiliary Information
57 * Certain failures may have information in addition to postcode information
45 */58 */
46 59
47static u32 aux_history_offset(u32 reg_value)60static u32 aux_history_offset(u32 reg_value)
@@ -133,6 +146,7 @@ static void xe_survivability_mode_fini(void *arg) · 85 unmodified lines
133 struct pci_dev *pdev = to_pci_dev(xe->drm.dev);146 struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
134 struct device *dev = &pdev->dev;147 struct device *dev = &pdev->dev;
135 148
149 xe_configfs_clear_survivability_mode(pdev);
136 sysfs_remove_file(&dev->kobj, &dev_attr_survivability_mode.attr);150 sysfs_remove_file(&dev->kobj, &dev_attr_survivability_mode.attr);
137}151}
138 152
@@ -186,24 +200,41 @@ bool xe_survivability_mode_is_enabled(struct xe_device *xe) · 47 unmodified lines
186 return xe->survivability.mode;200 return xe->survivability.mode;
187}201}
188 202
189/*203/**
190 * survivability_mode_requested - check if it's possible to enable204 * xe_survivability_mode_is_requested - check if it's possible to enable survivability
191 * survivability mode and that was requested by firmware205 * mode that was requested by firmware or userspace
206 * @xe: xe device instance
192 *207 *
193 * This function reads the boot status from Pcode.208 * This function reads configfs and boot status from Pcode.
194 *209 *
195 * Return: true if platform support is available and boot status indicates210 * Return: true if platform support is available and boot status indicates
196 * failure, false otherwise.211 * failure or if survivability mode is requested, false otherwise.
197 */212 */
198static bool survivability_mode_requested(struct xe_device *xe)213bool xe_survivability_mode_is_requested(struct xe_device *xe)
199{214{
200 struct xe_survivability *survivability = &xe->survivability;215 struct xe_survivability *survivability = &xe->survivability;
201 struct xe_mmio *mmio = xe_root_tile_mmio(xe);216 struct xe_mmio *mmio = xe_root_tile_mmio(xe);
217 struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
202 u32 data;218 u32 data;
219 bool survivability_mode;
203 220
204 if (!IS_DGFX(xe) || xe->info.platform < XE_BATTLEMAGE || IS_SRIOV_VF(xe))221 if (!IS_DGFX(xe) || IS_SRIOV_VF(xe))
205 return false;222 return false;
206 223
224 survivability_mode = xe_configfs_get_survivability_mode(pdev);
225
226 if (xe->info.platform < XE_BATTLEMAGE) {
227 if (survivability_mode) {
228 dev_err(&pdev->dev, "Survivability Mode is not supported on this card\n");
229 xe_configfs_clear_survivability_mode(pdev);
230 }
231 return false;
232 }
233
234 /* Enable survivability mode if set via configfs */
235 if (survivability_mode)
236 return true;
237
207 data = xe_mmio_read32(mmio, PCODE_SCRATCH(0));238 data = xe_mmio_read32(mmio, PCODE_SCRATCH(0));
208 survivability->boot_status = REG_FIELD_GET(BOOT_STATUS, data);239 survivability->boot_status = REG_FIELD_GET(BOOT_STATUS, data);
209 240
@@ -226,7 +257,7 @@ int xe_survivability_mode_enable(struct xe_device *xe) · 16 unmodified lines
226 struct xe_survivability_info *info;257 struct xe_survivability_info *info;
227 struct pci_dev *pdev = to_pci_dev(xe->drm.dev);258 struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
228 259
229 if (!survivability_mode_requested(xe))260 if (!xe_survivability_mode_is_requested(xe))
230 return 0;261 return 0;
231 262
232 survivability->size = MAX_SCRATCH_MMIO;263 survivability->size = MAX_SCRATCH_MMIO;
drivers/gpu/drm/xe/xe_survivability_mode.h+1−0
@@ -12,5 +12,6 @@ struct xe_device; · 11 unmodified lines
12 12
13int xe_survivability_mode_enable(struct xe_device *xe);13int xe_survivability_mode_enable(struct xe_device *xe);
14bool xe_survivability_mode_is_enabled(struct xe_device *xe);14bool xe_survivability_mode_is_enabled(struct xe_device *xe);
15bool xe_survivability_mode_is_requested(struct xe_device *xe);
15 16
16#endif /* _XE_SURVIVABILITY_MODE_H_ */17#endif /* _XE_SURVIVABILITY_MODE_H_ */
drivers/gpu/drm/xe/xe_svm.c+21−2
@@ -4,6 +4,7 @@ · 3 unmodified lines
4 */4 */
5 5
6#include "xe_bo.h"6#include "xe_bo.h"
7#include "xe_gt_stats.h"
7#include "xe_gt_tlb_invalidation.h"8#include "xe_gt_tlb_invalidation.h"
8#include "xe_migrate.h"9#include "xe_migrate.h"
9#include "xe_module.h"10#include "xe_module.h"
@@ -339,6 +340,8 @@ static void xe_svm_garbage_collector_work_func(struct work_struct *w) · 329 unmodified lines
339 up_write(&vm->lock);340 up_write(&vm->lock);
340}341}
341 342
343#if IS_ENABLED(CONFIG_DRM_XE_DEVMEM_MIRROR)
344
342static struct xe_vram_region *page_to_vr(struct page *page)345static struct xe_vram_region *page_to_vr(struct page *page)
343{346{
344 return container_of(page_pgmap(page), struct xe_vram_region, pagemap);347 return container_of(page_pgmap(page), struct xe_vram_region, pagemap);
@@ -577,6 +580,8 @@ static const struct drm_gpusvm_devmem_ops gpusvm_devmem_ops = { · 232 unmodified lines
577 .copy_to_ram = xe_svm_copy_to_ram,580 .copy_to_ram = xe_svm_copy_to_ram,
578};581};
579 582
583#endif
584
580static const struct drm_gpusvm_ops gpusvm_ops = {585static const struct drm_gpusvm_ops gpusvm_ops = {
581 .range_alloc = xe_svm_range_alloc,586 .range_alloc = xe_svm_range_alloc,
582 .range_free = xe_svm_range_free,587 .range_free = xe_svm_range_free,
@@ -650,6 +655,7 @@ static bool xe_svm_range_is_valid(struct xe_svm_range *range, · 67 unmodified lines
650 return (range->tile_present & ~range->tile_invalidated) & BIT(tile->id);655 return (range->tile_present & ~range->tile_invalidated) & BIT(tile->id);
651}656}
652 657
658#if IS_ENABLED(CONFIG_DRM_XE_DEVMEM_MIRROR)
653static struct xe_vram_region *tile_to_vr(struct xe_tile *tile)659static struct xe_vram_region *tile_to_vr(struct xe_tile *tile)
654{660{
655 return &tile->mem.vram;661 return &tile->mem.vram;
@@ -711,12 +717,21 @@ unlock: · 55 unmodified lines
711 717
712 return err;718 return err;
713}719}
720#else
721static int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
722 struct xe_svm_range *range,
723 const struct drm_gpusvm_ctx *ctx)
724{
725 return -EOPNOTSUPP;
726}
727#endif
728
714 729
715/**730/**
716 * xe_svm_handle_pagefault() - SVM handle page fault731 * xe_svm_handle_pagefault() - SVM handle page fault
717 * @vm: The VM.732 * @vm: The VM.
718 * @vma: The CPU address mirror VMA.733 * @vma: The CPU address mirror VMA.
719 * @tile: The tile upon the fault occurred.734 * @gt: The gt upon the fault occurred.
720 * @fault_addr: The GPU fault address.735 * @fault_addr: The GPU fault address.
721 * @atomic: The fault atomic access bit.736 * @atomic: The fault atomic access bit.
722 *737 *
@@ -726,7 +741,7 @@ unlock: · 3 unmodified lines
726 * Return: 0 on success, negative error code on error.741 * Return: 0 on success, negative error code on error.
727 */742 */
728int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,743int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
729 struct xe_tile *tile, u64 fault_addr,744 struct xe_gt *gt, u64 fault_addr,
730 bool atomic)745 bool atomic)
731{746{
732 struct drm_gpusvm_ctx ctx = {747 struct drm_gpusvm_ctx ctx = {
@@ -740,12 +755,15 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma, · 7 unmodified lines
740 struct drm_gpusvm_range *r;755 struct drm_gpusvm_range *r;
741 struct drm_exec exec;756 struct drm_exec exec;
742 struct dma_fence *fence;757 struct dma_fence *fence;
758 struct xe_tile *tile = gt_to_tile(gt);
743 ktime_t end = 0;759 ktime_t end = 0;
744 int err;760 int err;
745 761
746 lockdep_assert_held_write(&vm->lock);762 lockdep_assert_held_write(&vm->lock);
747 xe_assert(vm->xe, xe_vma_is_cpu_addr_mirror(vma));763 xe_assert(vm->xe, xe_vma_is_cpu_addr_mirror(vma));
748 764
765 xe_gt_stats_incr(gt, XE_GT_STATS_ID_SVM_PAGEFAULT_COUNT, 1);
766
749retry:767retry:
750 /* Always process UNMAPs first so view SVM ranges is current */768 /* Always process UNMAPs first so view SVM ranges is current */
751 err = xe_svm_garbage_collector(vm);769 err = xe_svm_garbage_collector(vm);
@@ -866,6 +884,7 @@ int xe_svm_bo_evict(struct xe_bo *bo) · 114 unmodified lines
866}884}
867 885
868#if IS_ENABLED(CONFIG_DRM_XE_DEVMEM_MIRROR)886#if IS_ENABLED(CONFIG_DRM_XE_DEVMEM_MIRROR)
887
869static struct drm_pagemap_device_addr888static struct drm_pagemap_device_addr
870xe_drm_pagemap_device_map(struct drm_pagemap *dpagemap,889xe_drm_pagemap_device_map(struct drm_pagemap *dpagemap,
871 struct device *dev,890 struct device *dev,
drivers/gpu/drm/xe/xe_svm.h+57−23
@@ -6,16 +6,19 @@ · 5 unmodified lines
6#ifndef _XE_SVM_H_6#ifndef _XE_SVM_H_
7#define _XE_SVM_H_7#define _XE_SVM_H_
8 8
9#if IS_ENABLED(CONFIG_DRM_XE_GPUSVM)
10
9#include <drm/drm_pagemap.h>11#include <drm/drm_pagemap.h>
10#include <drm/drm_gpusvm.h>12#include <drm/drm_gpusvm.h>
11 13
12#define XE_INTERCONNECT_VRAM DRM_INTERCONNECT_DRIVER14#define XE_INTERCONNECT_VRAM DRM_INTERCONNECT_DRIVER
13 15
14struct xe_bo;16struct xe_bo;
15struct xe_vram_region;17struct xe_gt;
16struct xe_tile;18struct xe_tile;
17struct xe_vm;19struct xe_vm;
18struct xe_vma;20struct xe_vma;
21struct xe_vram_region;
19 22
20/** struct xe_svm_range - SVM range */23/** struct xe_svm_range - SVM range */
21struct xe_svm_range {24struct xe_svm_range {
@@ -43,7 +46,6 @@ struct xe_svm_range { · 21 unmodified lines
43 u8 skip_migrate :1;46 u8 skip_migrate :1;
44};47};
45 48
46#if IS_ENABLED(CONFIG_DRM_GPUSVM)
47/**49/**
48 * xe_svm_range_pages_valid() - SVM range pages valid50 * xe_svm_range_pages_valid() - SVM range pages valid
49 * @range: SVM range51 * @range: SVM range
@@ -64,7 +66,7 @@ void xe_svm_fini(struct xe_vm *vm); · 14 unmodified lines
64void xe_svm_close(struct xe_vm *vm);66void xe_svm_close(struct xe_vm *vm);
65 67
66int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,68int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
67 struct xe_tile *tile, u64 fault_addr,69 struct xe_gt *gt, u64 fault_addr,
68 bool atomic);70 bool atomic);
69 71
70bool xe_svm_has_mapping(struct xe_vm *vm, u64 start, u64 end);72bool xe_svm_has_mapping(struct xe_vm *vm, u64 start, u64 end);
@@ -72,7 +74,50 @@ bool xe_svm_has_mapping(struct xe_vm *vm, u64 start, u64 end); · 1 unmodified line
72int xe_svm_bo_evict(struct xe_bo *bo);74int xe_svm_bo_evict(struct xe_bo *bo);
73 75
74void xe_svm_range_debug(struct xe_svm_range *range, const char *operation);76void xe_svm_range_debug(struct xe_svm_range *range, const char *operation);
77
78/**
79 * xe_svm_range_has_dma_mapping() - SVM range has DMA mapping
80 * @range: SVM range
81 *
82 * Return: True if SVM range has a DMA mapping, False otherwise
83 */
84static inline bool xe_svm_range_has_dma_mapping(struct xe_svm_range *range)
85{
86 lockdep_assert_held(&range->base.gpusvm->notifier_lock);
87 return range->base.flags.has_dma_mapping;
88}
89
90#define xe_svm_assert_in_notifier(vm__) \
91 lockdep_assert_held_write(&(vm__)->svm.gpusvm.notifier_lock)
92
93#define xe_svm_notifier_lock(vm__) \
94 drm_gpusvm_notifier_lock(&(vm__)->svm.gpusvm)
95
96#define xe_svm_notifier_unlock(vm__) \
97 drm_gpusvm_notifier_unlock(&(vm__)->svm.gpusvm)
98
75#else99#else
100#include <linux/interval_tree.h>
101
102struct drm_pagemap_device_addr;
103struct xe_bo;
104struct xe_gt;
105struct xe_vm;
106struct xe_vma;
107struct xe_tile;
108struct xe_vram_region;
109
110#define XE_INTERCONNECT_VRAM 1
111
112struct xe_svm_range {
113 struct {
114 struct interval_tree_node itree;
115 const struct drm_pagemap_device_addr *dma_addr;
116 } base;
117 u32 tile_present;
118 u32 tile_invalidated;
119};
120
76static inline bool xe_svm_range_pages_valid(struct xe_svm_range *range)121static inline bool xe_svm_range_pages_valid(struct xe_svm_range *range)
77{122{
78 return false;123 return false;
@@ -102,7 +147,7 @@ void xe_svm_close(struct xe_vm *vm) · 23 unmodified lines
102 147
103static inline148static inline
104int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,149int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
105 struct xe_tile *tile, u64 fault_addr,150 struct xe_gt *gt, u64 fault_addr,
106 bool atomic)151 bool atomic)
107{152{
108 return 0;153 return 0;
@@ -124,27 +169,16 @@ static inline · 15 unmodified lines
124void xe_svm_range_debug(struct xe_svm_range *range, const char *operation)169void xe_svm_range_debug(struct xe_svm_range *range, const char *operation)
125{170{
126}171}
127#endif
128 172
129/**173#define xe_svm_assert_in_notifier(...) do {} while (0)
130 * xe_svm_range_has_dma_mapping() - SVM range has DMA mapping174#define xe_svm_range_has_dma_mapping(...) false
131 * @range: SVM range175
132 *176static inline void xe_svm_notifier_lock(struct xe_vm *vm)
133 * Return: True if SVM range has a DMA mapping, False otherwise
134 */
135static inline bool xe_svm_range_has_dma_mapping(struct xe_svm_range *range)
136{177{
137 lockdep_assert_held(&range->base.gpusvm->notifier_lock);
138 return range->base.flags.has_dma_mapping;
139}178}
140 179
141#define xe_svm_assert_in_notifier(vm__) \180static inline void xe_svm_notifier_unlock(struct xe_vm *vm)
142 lockdep_assert_held_write(&(vm__)->svm.gpusvm.notifier_lock)181{
143 182}
144#define xe_svm_notifier_lock(vm__) \183#endif
145 drm_gpusvm_notifier_lock(&(vm__)->svm.gpusvm)
146
147#define xe_svm_notifier_unlock(vm__) \
148 drm_gpusvm_notifier_unlock(&(vm__)->svm.gpusvm)
149
150#endif184#endif
drivers/gpu/drm/xe/xe_uc_fw.c+55−39
@@ -92,6 +92,8 @@ · 91 unmodified lines
92 92
93struct uc_fw_entry {93struct uc_fw_entry {
94 enum xe_platform platform;94 enum xe_platform platform;
95 enum xe_gt_type gt_type;
96
95 struct {97 struct {
96 const char *path;98 const char *path;
97 u16 major;99 u16 major;
@@ -106,32 +108,37 @@ struct fw_blobs_by_type { · 8 unmodified lines
106 u32 count;108 u32 count;
107};109};
108 110
109#define XE_GUC_FIRMWARE_DEFS(fw_def, mmp_ver, major_ver) \111/*
110 fw_def(BATTLEMAGE, major_ver(xe, guc, bmg, 70, 29, 2)) \112 * Add an "ANY" define just to convey the meaning it's given here.
111 fw_def(LUNARLAKE, major_ver(xe, guc, lnl, 70, 29, 2)) \113 */
112 fw_def(METEORLAKE, major_ver(i915, guc, mtl, 70, 29, 2)) \114#define XE_GT_TYPE_ANY XE_GT_TYPE_UNINITIALIZED
113 fw_def(DG2, major_ver(i915, guc, dg2, 70, 29, 2)) \115
114 fw_def(DG1, major_ver(i915, guc, dg1, 70, 29, 2)) \116#define XE_GUC_FIRMWARE_DEFS(fw_def, mmp_ver, major_ver) \
115 fw_def(ALDERLAKE_N, major_ver(i915, guc, tgl, 70, 29, 2)) \117 fw_def(BATTLEMAGE, GT_TYPE_ANY, major_ver(xe, guc, bmg, 70, 44, 1)) \
116 fw_def(ALDERLAKE_P, major_ver(i915, guc, adlp, 70, 29, 2)) \118 fw_def(LUNARLAKE, GT_TYPE_ANY, major_ver(xe, guc, lnl, 70, 44, 1)) \
117 fw_def(ALDERLAKE_S, major_ver(i915, guc, tgl, 70, 29, 2)) \119 fw_def(METEORLAKE, GT_TYPE_ANY, major_ver(i915, guc, mtl, 70, 44, 1)) \
118 fw_def(ROCKETLAKE, major_ver(i915, guc, tgl, 70, 29, 2)) \120 fw_def(DG2, GT_TYPE_ANY, major_ver(i915, guc, dg2, 70, 44, 1)) \
119 fw_def(TIGERLAKE, major_ver(i915, guc, tgl, 70, 29, 2))121 fw_def(DG1, GT_TYPE_ANY, major_ver(i915, guc, dg1, 70, 44, 1)) \
122 fw_def(ALDERLAKE_N, GT_TYPE_ANY, major_ver(i915, guc, tgl, 70, 44, 1)) \
123 fw_def(ALDERLAKE_P, GT_TYPE_ANY, major_ver(i915, guc, adlp, 70, 44, 1)) \
124 fw_def(ALDERLAKE_S, GT_TYPE_ANY, major_ver(i915, guc, tgl, 70, 44, 1)) \
125 fw_def(ROCKETLAKE, GT_TYPE_ANY, major_ver(i915, guc, tgl, 70, 44, 1)) \
126 fw_def(TIGERLAKE, GT_TYPE_ANY, major_ver(i915, guc, tgl, 70, 44, 1))
120 127
121#define XE_HUC_FIRMWARE_DEFS(fw_def, mmp_ver, no_ver) \128#define XE_HUC_FIRMWARE_DEFS(fw_def, mmp_ver, no_ver) \
122 fw_def(BATTLEMAGE, no_ver(xe, huc, bmg)) \129 fw_def(BATTLEMAGE, GT_TYPE_ANY, no_ver(xe, huc, bmg)) \
123 fw_def(LUNARLAKE, no_ver(xe, huc, lnl)) \130 fw_def(LUNARLAKE, GT_TYPE_ANY, no_ver(xe, huc, lnl)) \
124 fw_def(METEORLAKE, no_ver(i915, huc_gsc, mtl)) \131 fw_def(METEORLAKE, GT_TYPE_ANY, no_ver(i915, huc_gsc, mtl)) \
125 fw_def(DG1, no_ver(i915, huc, dg1)) \132 fw_def(DG1, GT_TYPE_ANY, no_ver(i915, huc, dg1)) \
126 fw_def(ALDERLAKE_P, no_ver(i915, huc, tgl)) \133 fw_def(ALDERLAKE_P, GT_TYPE_ANY, no_ver(i915, huc, tgl)) \
127 fw_def(ALDERLAKE_S, no_ver(i915, huc, tgl)) \134 fw_def(ALDERLAKE_S, GT_TYPE_ANY, no_ver(i915, huc, tgl)) \
128 fw_def(ROCKETLAKE, no_ver(i915, huc, tgl)) \135 fw_def(ROCKETLAKE, GT_TYPE_ANY, no_ver(i915, huc, tgl)) \
129 fw_def(TIGERLAKE, no_ver(i915, huc, tgl))136 fw_def(TIGERLAKE, GT_TYPE_ANY, no_ver(i915, huc, tgl))
130 137
131/* for the GSC FW we match the compatibility version and not the release one */138/* for the GSC FW we match the compatibility version and not the release one */
132#define XE_GSC_FIRMWARE_DEFS(fw_def, major_ver) \139#define XE_GSC_FIRMWARE_DEFS(fw_def, major_ver) \
133 fw_def(LUNARLAKE, major_ver(xe, gsc, lnl, 104, 1, 0)) \140 fw_def(LUNARLAKE, GT_TYPE_ANY, major_ver(xe, gsc, lnl, 104, 1, 0)) \
134 fw_def(METEORLAKE, major_ver(i915, gsc, mtl, 102, 1, 0))141 fw_def(METEORLAKE, GT_TYPE_ANY, major_ver(i915, gsc, mtl, 102, 1, 0))
135 142
136#define MAKE_FW_PATH(dir__, uc__, shortname__, version__) \143#define MAKE_FW_PATH(dir__, uc__, shortname__, version__) \
137 __stringify(dir__) "/" __stringify(shortname__) "_" __stringify(uc__) version__ ".bin"144 __stringify(dir__) "/" __stringify(shortname__) "_" __stringify(uc__) version__ ".bin"
@@ -159,12 +166,13 @@ struct fw_blobs_by_type { · 21 unmodified lines
159 a, b, c }166 a, b, c }
160 167
161/* All blobs need to be declared via MODULE_FIRMWARE() */168/* All blobs need to be declared via MODULE_FIRMWARE() */
162#define XE_UC_MODULE_FIRMWARE(platform__, fw_filename) \169#define XE_UC_MODULE_FIRMWARE(platform__, gt_type__, fw_filename) \
163 MODULE_FIRMWARE(fw_filename);170 MODULE_FIRMWARE(fw_filename);
164 171
165#define XE_UC_FW_ENTRY(platform__, entry__) \172#define XE_UC_FW_ENTRY(platform__, gt_type__, entry__) \
166 { \173 { \
167 .platform = XE_ ## platform__, \174 .platform = XE_ ## platform__, \
175 .gt_type = XE_ ## gt_type__, \
168 entry__, \176 entry__, \
169 },177 },
170 178
@@ -222,30 +230,38 @@ uc_fw_auto_select(struct xe_device *xe, struct xe_uc_fw *uc_fw) · 51 unmodified lines
222 [XE_UC_FW_TYPE_HUC] = { entries_huc, ARRAY_SIZE(entries_huc) },230 [XE_UC_FW_TYPE_HUC] = { entries_huc, ARRAY_SIZE(entries_huc) },
223 [XE_UC_FW_TYPE_GSC] = { entries_gsc, ARRAY_SIZE(entries_gsc) },231 [XE_UC_FW_TYPE_GSC] = { entries_gsc, ARRAY_SIZE(entries_gsc) },
224 };232 };
225 static const struct uc_fw_entry *entries;233 struct xe_gt *gt = uc_fw_to_gt(uc_fw);
226 enum xe_platform p = xe->info.platform;234 enum xe_platform p = xe->info.platform;
235 const struct uc_fw_entry *entries;
227 u32 count;236 u32 count;
228 int i;237 int i;
229 238
230 xe_assert(xe, uc_fw->type < ARRAY_SIZE(blobs_all));239 xe_gt_assert(gt, uc_fw->type < ARRAY_SIZE(blobs_all));
240 xe_gt_assert(gt, gt->info.type != XE_GT_TYPE_UNINITIALIZED);
241
231 entries = blobs_all[uc_fw->type].entries;242 entries = blobs_all[uc_fw->type].entries;
232 count = blobs_all[uc_fw->type].count;243 count = blobs_all[uc_fw->type].count;
233 244
234 for (i = 0; i < count && p <= entries[i].platform; i++) {245 for (i = 0; i < count && p <= entries[i].platform; i++) {
235 if (p == entries[i].platform) {246 if (p != entries[i].platform)
236 uc_fw->path = entries[i].path;247 continue;
237 uc_fw->versions.wanted.major = entries[i].major;248
238 uc_fw->versions.wanted.minor = entries[i].minor;249 if (entries[i].gt_type != XE_GT_TYPE_ANY &&
239 uc_fw->versions.wanted.patch = entries[i].patch;250 entries[i].gt_type != gt->info.type)
240 uc_fw->full_ver_required = entries[i].full_ver_required;251 continue;
241 252
242 if (uc_fw->type == XE_UC_FW_TYPE_GSC)253 uc_fw->path = entries[i].path;
243 uc_fw->versions.wanted_type = XE_UC_FW_VER_COMPATIBILITY;254 uc_fw->versions.wanted.major = entries[i].major;
244 else255 uc_fw->versions.wanted.minor = entries[i].minor;
245 uc_fw->versions.wanted_type = XE_UC_FW_VER_RELEASE;256 uc_fw->versions.wanted.patch = entries[i].patch;
246 257 uc_fw->full_ver_required = entries[i].full_ver_required;
247 break;258
248 }259 if (uc_fw->type == XE_UC_FW_TYPE_GSC)
260 uc_fw->versions.wanted_type = XE_UC_FW_VER_COMPATIBILITY;
261 else
262 uc_fw->versions.wanted_type = XE_UC_FW_VER_RELEASE;
263
264 break;
249 }265 }
250}266}
251 267
drivers/gpu/drm/xe/xe_vm.c+29−10
@@ -2049,7 +2049,8 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, · 2048 unmodified lines
2049 return -EINVAL;2049 return -EINVAL;
2050 2050
2051 if (XE_IOCTL_DBG(xe, args->flags & DRM_XE_VM_CREATE_FLAG_SCRATCH_PAGE &&2051 if (XE_IOCTL_DBG(xe, args->flags & DRM_XE_VM_CREATE_FLAG_SCRATCH_PAGE &&
2052 args->flags & DRM_XE_VM_CREATE_FLAG_FAULT_MODE))2052 args->flags & DRM_XE_VM_CREATE_FLAG_FAULT_MODE &&
2053 !xe->info.needs_scratch))
2053 return -EINVAL;2054 return -EINVAL;
2054 2055
2055 if (XE_IOCTL_DBG(xe, !(args->flags & DRM_XE_VM_CREATE_FLAG_LR_MODE) &&2056 if (XE_IOCTL_DBG(xe, !(args->flags & DRM_XE_VM_CREATE_FLAG_LR_MODE) &&
@@ -2201,6 +2202,20 @@ static void print_op(struct xe_device *xe, struct drm_gpuva_op *op) · 145 unmodified lines
2201}2202}
2202#endif2203#endif
2203 2204
2205static bool __xe_vm_needs_clear_scratch_pages(struct xe_vm *vm, u32 bind_flags)
2206{
2207 if (!xe_vm_in_fault_mode(vm))
2208 return false;
2209
2210 if (!xe_vm_has_scratch(vm))
2211 return false;
2212
2213 if (bind_flags & DRM_XE_VM_BIND_FLAG_IMMEDIATE)
2214 return false;
2215
2216 return true;
2217}
2218
2204/*2219/*
2205 * Create operations list from IOCTL arguments, setup operations fields so parse2220 * Create operations list from IOCTL arguments, setup operations fields so parse
2206 * and commit steps are decoupled from IOCTL arguments. This step can fail.2221 * and commit steps are decoupled from IOCTL arguments. This step can fail.
@@ -2273,6 +2288,8 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_bo *bo, · 66 unmodified lines
2273 DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR;2288 DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR;
2274 op->map.dumpable = flags & DRM_XE_VM_BIND_FLAG_DUMPABLE;2289 op->map.dumpable = flags & DRM_XE_VM_BIND_FLAG_DUMPABLE;
2275 op->map.pat_index = pat_index;2290 op->map.pat_index = pat_index;
2291 op->map.invalidate_on_bind =
2292 __xe_vm_needs_clear_scratch_pages(vm, flags);
2276 } else if (__op->op == DRM_GPUVA_OP_PREFETCH) {2293 } else if (__op->op == DRM_GPUVA_OP_PREFETCH) {
2277 op->prefetch.region = prefetch_region;2294 op->prefetch.region = prefetch_region;
2278 }2295 }
@@ -2472,8 +2489,9 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops, · 193 unmodified lines
2472 return PTR_ERR(vma);2489 return PTR_ERR(vma);
2473 2490
2474 op->map.vma = vma;2491 op->map.vma = vma;
2475 if ((op->map.immediate || !xe_vm_in_fault_mode(vm)) &&2492 if (((op->map.immediate || !xe_vm_in_fault_mode(vm)) &&
2476 !op->map.is_cpu_addr_mirror)2493 !op->map.is_cpu_addr_mirror) ||
2494 op->map.invalidate_on_bind)
2477 xe_vma_ops_incr_pt_update_ops(vops,2495 xe_vma_ops_incr_pt_update_ops(vops,
2478 op->tile_mask);2496 op->tile_mask);
2479 break;2497 break;
@@ -2726,9 +2744,10 @@ static int op_lock_and_prep(struct drm_exec *exec, struct xe_vm *vm, · 246 unmodified lines
2726 2744
2727 switch (op->base.op) {2745 switch (op->base.op) {
2728 case DRM_GPUVA_OP_MAP:2746 case DRM_GPUVA_OP_MAP:
2729 err = vma_lock_and_validate(exec, op->map.vma,2747 if (!op->map.invalidate_on_bind)
2730 !xe_vm_in_fault_mode(vm) ||2748 err = vma_lock_and_validate(exec, op->map.vma,
2731 op->map.immediate);2749 !xe_vm_in_fault_mode(vm) ||
2750 op->map.immediate);
2732 break;2751 break;
2733 case DRM_GPUVA_OP_REMAP:2752 case DRM_GPUVA_OP_REMAP:
2734 err = check_ufence(gpuva_to_vma(op->base.remap.unmap->va));2753 err = check_ufence(gpuva_to_vma(op->base.remap.unmap->va));
@@ -3109,7 +3128,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm, · 374 unmodified lines
3109 3128
3110 if (XE_IOCTL_DBG(xe, is_cpu_addr_mirror &&3129 if (XE_IOCTL_DBG(xe, is_cpu_addr_mirror &&
3111 (!xe_vm_in_fault_mode(vm) ||3130 (!xe_vm_in_fault_mode(vm) ||
3112 !IS_ENABLED(CONFIG_DRM_GPUSVM)))) {3131 !IS_ENABLED(CONFIG_DRM_XE_GPUSVM)))) {
3113 err = -EINVAL;3132 err = -EINVAL;
3114 goto free_bind_ops;3133 goto free_bind_ops;
3115 }3134 }
@@ -3243,7 +3262,7 @@ static int xe_vm_bind_ioctl_validate_bo(struct xe_device *xe, struct xe_bo *bo, · 127 unmodified lines
3243 XE_64K_PAGE_MASK) ||3262 XE_64K_PAGE_MASK) ||
3244 XE_IOCTL_DBG(xe, addr & XE_64K_PAGE_MASK) ||3263 XE_IOCTL_DBG(xe, addr & XE_64K_PAGE_MASK) ||
3245 XE_IOCTL_DBG(xe, range & XE_64K_PAGE_MASK)) {3264 XE_IOCTL_DBG(xe, range & XE_64K_PAGE_MASK)) {
3246 return -EINVAL;3265 return -EINVAL;
3247 }3266 }
3248 }3267 }
3249 3268
@@ -3251,7 +3270,7 @@ static int xe_vm_bind_ioctl_validate_bo(struct xe_device *xe, struct xe_bo *bo, · 1 unmodified line
3251 if (bo->cpu_caching) {3270 if (bo->cpu_caching) {
3252 if (XE_IOCTL_DBG(xe, coh_mode == XE_COH_NONE &&3271 if (XE_IOCTL_DBG(xe, coh_mode == XE_COH_NONE &&
3253 bo->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB)) {3272 bo->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB)) {
3254 return -EINVAL;3273 return -EINVAL;
3255 }3274 }
3256 } else if (XE_IOCTL_DBG(xe, coh_mode == XE_COH_NONE)) {3275 } else if (XE_IOCTL_DBG(xe, coh_mode == XE_COH_NONE)) {
3257 /*3276 /*
@@ -3260,7 +3279,7 @@ static int xe_vm_bind_ioctl_validate_bo(struct xe_device *xe, struct xe_bo *bo, · 2 unmodified lines
3260 * how it was mapped on the CPU. Just assume is it3279 * how it was mapped on the CPU. Just assume is it
3261 * potentially cached on CPU side.3280 * potentially cached on CPU side.
3262 */3281 */
3263 return -EINVAL;3282 return -EINVAL;
3264 }3283 }
3265 3284
3266 /* If a BO is protected it can only be mapped if the key is still valid */3285 /* If a BO is protected it can only be mapped if the key is still valid */
drivers/gpu/drm/xe/xe_vm_types.h+2−0
@@ -330,6 +330,8 @@ struct xe_vma_op_map { · 329 unmodified lines
330 bool is_cpu_addr_mirror;330 bool is_cpu_addr_mirror;
331 /** @dumpable: whether BO is dumped on GPU hang */331 /** @dumpable: whether BO is dumped on GPU hang */
332 bool dumpable;332 bool dumpable;
333 /** @invalidate: invalidate the VMA before bind */
334 bool invalidate_on_bind;
333 /** @pat_index: The pat index to use for this operation. */335 /** @pat_index: The pat index to use for this operation. */
334 u16 pat_index;336 u16 pat_index;
335};337};
drivers/gpu/drm/xe/xe_vram.c+4−1
@@ -49,7 +49,7 @@ _resize_bar(struct xe_device *xe, int resno, resource_size_t size) · 48 unmodified lines
49 */49 */
50static void resize_vram_bar(struct xe_device *xe)50static void resize_vram_bar(struct xe_device *xe)
51{51{
52 u64 force_vram_bar_size = xe_modparam.force_vram_bar_size;52 int force_vram_bar_size = xe_modparam.force_vram_bar_size;
53 struct pci_dev *pdev = to_pci_dev(xe->drm.dev);53 struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
54 struct pci_bus *root = pdev->bus;54 struct pci_bus *root = pdev->bus;
55 resource_size_t current_size;55 resource_size_t current_size;
@@ -66,6 +66,9 @@ static void resize_vram_bar(struct xe_device *xe) · 10 unmodified lines
66 if (!bar_size_mask)66 if (!bar_size_mask)
67 return;67 return;
68 68
69 if (force_vram_bar_size < 0)
70 return;
71
69 /* set to a specific size? */72 /* set to a specific size? */
70 if (force_vram_bar_size) {73 if (force_vram_bar_size) {
71 u32 bar_size_bit;74 u32 bar_size_bit;
drivers/gpu/drm/xe/xe_wa.c+12−0
@@ -230,6 +230,18 @@ static const struct xe_rtp_entry_sr gt_was[] = { · 229 unmodified lines
230 XE_RTP_ENTRY_FLAG(FOREACH_ENGINE),230 XE_RTP_ENTRY_FLAG(FOREACH_ENGINE),
231 },231 },
232 232
233 /* Xe2_HPG */
234
235 { XE_RTP_NAME("16025250150"),
236 XE_RTP_RULES(GRAPHICS_VERSION(2001)),
237 XE_RTP_ACTIONS(SET(LSN_VC_REG2,
238 LSN_LNI_WGT(1) |
239 LSN_LNE_WGT(1) |
240 LSN_DIM_X_WGT(1) |
241 LSN_DIM_Y_WGT(1) |
242 LSN_DIM_Z_WGT(1)))
243 },
244
233 /* Xe2_HPM */245 /* Xe2_HPM */
234 246
235 { XE_RTP_NAME("16021867713"),247 { XE_RTP_NAME("16021867713"),
drivers/gpu/drm/xe/xe_wa_oob.rules+2−0
@@ -57,3 +57,5 @@ no_media_l3 MEDIA_VERSION(3000) · 56 unmodified lines
57 GRAPHICS_VERSION(1260), GRAPHICS_STEP(A0, B0)57 GRAPHICS_VERSION(1260), GRAPHICS_STEP(A0, B0)
5816023105232 GRAPHICS_VERSION_RANGE(2001, 3001)5816023105232 GRAPHICS_VERSION_RANGE(2001, 3001)
59 MEDIA_VERSION_RANGE(1301, 3000)59 MEDIA_VERSION_RANGE(1301, 3000)
6016026508708 GRAPHICS_VERSION_RANGE(1200, 3001)
61 MEDIA_VERSION_RANGE(1300, 3000)
include/uapi/drm/xe_drm.h+5−1
@@ -917,7 +917,11 @@ struct drm_xe_gem_mmap_offset { · 916 unmodified lines
917 * struct drm_xe_vm_create - Input of &DRM_IOCTL_XE_VM_CREATE917 * struct drm_xe_vm_create - Input of &DRM_IOCTL_XE_VM_CREATE
918 *918 *
919 * The @flags can be:919 * The @flags can be:
920 * - %DRM_XE_VM_CREATE_FLAG_SCRATCH_PAGE920 * - %DRM_XE_VM_CREATE_FLAG_SCRATCH_PAGE - Map the whole virtual address
921 * space of the VM to scratch page. A vm_bind would overwrite the scratch
922 * page mapping. This flag is mutually exclusive with the
923 * %DRM_XE_VM_CREATE_FLAG_FAULT_MODE flag, with an exception of on x2 and
924 * xe3 platform.
921 * - %DRM_XE_VM_CREATE_FLAG_LR_MODE - An LR, or Long Running VM accepts925 * - %DRM_XE_VM_CREATE_FLAG_LR_MODE - An LR, or Long Running VM accepts
922 * exec submissions to its exec_queues that don't have an upper time926 * exec submissions to its exec_queues that don't have an upper time
923 * limit on the job execution time. But exec submissions to these927 * limit on the job execution time. But exec submissions to these

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t