diff options
| author | Benjamin Hadad IV <bh4@unc.edu> | 2023-07-13 12:13:17 -0400 |
|---|---|---|
| committer | Benjamin Hadad IV <bh4@unc.edu> | 2023-07-13 12:13:17 -0400 |
| commit | bfb4dcf0e78954c0163f3a06a5a088c4d1b437a8 (patch) | |
| tree | 5288dc03523647f01d9952557b282b1019daa774 | |
| parent | 068e7f4e7208d6c9250ad72208e0b36fd9fdf2f6 (diff) | |
This commit is to update the repo for display during a meeting.
- Added an Ampere version of the device info data.
- Added Ampere versions of auxillary functions.
- Modified display functions to accommodate Ampere data.
- Made other various small modifications.
| -rw-r--r-- | device_info_procfs.c | 140 | ||||
| -rw-r--r-- | nvdebug.h | 37 | ||||
| -rw-r--r-- | nvdebug_entry.c | 41 |
3 files changed, 179 insertions, 39 deletions
diff --git a/device_info_procfs.c b/device_info_procfs.c index 1fc0586..b1e58b1 100644 --- a/device_info_procfs.c +++ b/device_info_procfs.c | |||
| @@ -31,7 +31,7 @@ struct file_operations nvdebug_read_reg32_file_ops = { | |||
| 31 | 31 | ||
| 32 | // Called to start or resume a sequence. Prior to 4.19, *pos is unreliable. | 32 | // Called to start or resume a sequence. Prior to 4.19, *pos is unreliable. |
| 33 | // Initializes iterator `idx` state and returns it. Ends sequence on NULL. | 33 | // Initializes iterator `idx` state and returns it. Ends sequence on NULL. |
| 34 | static void* device_info_file_seq_start(struct seq_file *s, loff_t *pos) { | 34 | static void* device_info_file_seq_start_previous(struct seq_file *s, loff_t *pos) { |
| 35 | static int idx; | 35 | static int idx; |
| 36 | // If start of sequence, reset `idx` | 36 | // If start of sequence, reset `idx` |
| 37 | if (*pos == 0) | 37 | if (*pos == 0) |
| @@ -42,9 +42,21 @@ static void* device_info_file_seq_start(struct seq_file *s, loff_t *pos) { | |||
| 42 | return &idx; | 42 | return &idx; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | static void* device_info_file_seq_start_ampere(struct seq_file *s, loff_t *pos) { | ||
| 46 | static int idx; | ||
| 47 | // If start of sequence, reset `idx` | ||
| 48 | if (*pos == 0) | ||
| 49 | idx = 0; | ||
| 50 | struct nvdebug_state *g = &g_nvdebug_state[seq2gpuidx(s)]; | ||
| 51 | // Number of possible info entries is fixed, and list is sparse | ||
| 52 | if (idx >= (nvdebug_readl(g, 0x0224fc) >> 20)) | ||
| 53 | return NULL; | ||
| 54 | return &idx; | ||
| 55 | } | ||
| 56 | |||
| 45 | // Steps to next record. Returns new value of `idx`. | 57 | // Steps to next record. Returns new value of `idx`. |
| 46 | // Calls show() on non-NULL return | 58 | // Calls show() on non-NULL return |
| 47 | static void* device_info_file_seq_next(struct seq_file *s, void *idx, | 59 | static void* device_info_file_seq_next_previous(struct seq_file *s, void *idx, |
| 48 | loff_t *pos) { | 60 | loff_t *pos) { |
| 49 | (*pos)++; // Required by seq interface | 61 | (*pos)++; // Required by seq interface |
| 50 | // Number of possible info entries is fixed, and list is sparse | 62 | // Number of possible info entries is fixed, and list is sparse |
| @@ -53,12 +65,50 @@ static void* device_info_file_seq_next(struct seq_file *s, void *idx, | |||
| 53 | return idx; | 65 | return idx; |
| 54 | } | 66 | } |
| 55 | 67 | ||
| 68 | // Steps to next record. Returns new value of `idx`. | ||
| 69 | // Calls show() on non-NULL return | ||
| 70 | static void* device_info_file_seq_next_ampere(struct seq_file *s, void *idx, | ||
| 71 | loff_t *pos) { | ||
| 72 | (*pos)++; // Required by seq interface | ||
| 73 | // Number of possible info entries is fixed, and list is sparse | ||
| 74 | struct nvdebug_state *g = &g_nvdebug_state[seq2gpuidx(s)]; | ||
| 75 | if ((*(int*)idx)++ >= (nvdebug_readl(g, 0x0224fc) >> 20)) | ||
| 76 | return NULL; | ||
| 77 | return idx; | ||
| 78 | } | ||
| 79 | /* | ||
| 80 | // Steps to next record on Ampere GPUs. Returns new value of `idx`. | ||
| 81 | static void* device_info_file_seq_next_ampere(struct seq_file *s, void *idx, | ||
| 82 | loff_t *pos) { | ||
| 83 | (*pos)++; // Required by seq interface | ||
| 84 | // Number of possible info entries is fixed, and list is sparse | ||
| 85 | while(1) { | ||
| 86 | struct nvdebug_state *g = &g_nvdebug_state[seq2gpuidx(s)]; | ||
| 87 | if ((*(int*)idx)++ >= (nvdebug_readl(g, 0x0224fc) >> 20)) | ||
| 88 | return NULL; | ||
| 89 | ptop_device_info_t curr_info; | ||
| 90 | curr_info.raw = nvdebug_readl(g, NV_PTOP_DEVICE_INFO_AMPERE(*(int*)idx)); | ||
| 91 | if(!curr_info.raw && !*info_type) continue; | ||
| 92 | (*info_type)++; | ||
| 93 | break; | ||
| 94 | } | ||
| 95 | while(1) { | ||
| 96 | struct nvdebug_state *g = &g_nvdebug_state[seq2gpuidx(s)]; | ||
| 97 | if ((*(int*)idx)++ >= (nvdebug_readl(g, 0x0224fc) >> 20)) | ||
| 98 | return NULL; | ||
| 99 | ptop_device_info_t curr_info; | ||
| 100 | curr_info.raw = nvdebug_readl(g, NV_PTOP_DEVICE_INFO_AMPERE(*(int*)idx)); | ||
| 101 | if(curr_info.raw & 0x80000000) continue; | ||
| 102 | break; | ||
| 103 | } | ||
| 104 | return idx; | ||
| 105 | } | ||
| 106 | */ | ||
| 56 | // Print info at index *idx. Returns non-zero on error. | 107 | // Print info at index *idx. Returns non-zero on error. |
| 57 | static int device_info_file_seq_show(struct seq_file *s, void *idx) { | 108 | static int device_info_file_seq_show_previous(struct seq_file *s, void *idx) { |
| 58 | ptop_device_info_t curr_info; | 109 | ptop_device_info_t curr_info; |
| 59 | struct nvdebug_state *g = &g_nvdebug_state[seq2gpuidx(s)]; | 110 | struct nvdebug_state *g = &g_nvdebug_state[seq2gpuidx(s)]; |
| 60 | 111 | curr_info.raw = nvdebug_readl(g, NV_PTOP_DEVICE_INFO_PREVIOUS(*(int*)idx)); | |
| 61 | curr_info.raw = nvdebug_readl(g, NV_PTOP_DEVICE_INFO(*(int*)idx)); | ||
| 62 | // Check for read errors | 112 | // Check for read errors |
| 63 | if (curr_info.raw == -1) | 113 | if (curr_info.raw == -1) |
| 64 | return -EIO; | 114 | return -EIO; |
| @@ -104,24 +154,88 @@ static int device_info_file_seq_show(struct seq_file *s, void *idx) { | |||
| 104 | return 0; | 154 | return 0; |
| 105 | } | 155 | } |
| 106 | 156 | ||
| 157 | // Print info at index *idx for Ampere GPUs. Returns non-zero on error. | ||
| 158 | static int device_info_file_seq_show_ampere(struct seq_file *s, void *idx) { | ||
| 159 | ptop_device_info_t curr_info; | ||
| 160 | struct nvdebug_state *g = &g_nvdebug_state[seq2gpuidx(s)]; | ||
| 161 | curr_info.raw = nvdebug_readl(g, NV_PTOP_DEVICE_INFO_AMPERE(*(int*)idx)); | ||
| 162 | // Check for read errors | ||
| 163 | if (curr_info.raw == -1) | ||
| 164 | return -EIO; | ||
| 165 | int info_type = -1; | ||
| 166 | if(curr_info.raw) { | ||
| 167 | if(*(int*)idx < 1 || !nvdebug_readl(g, NV_PTOP_DEVICE_INFO_AMPERE(*(int*)idx) - 1)) info_type = 0; | ||
| 168 | if(*(int*)idx < 2 || !nvdebug_readl(g, NV_PTOP_DEVICE_INFO_AMPERE(*(int*)idx) - 2)) info_type = 1; | ||
| 169 | if(*(int*)idx < 3 || !nvdebug_readl(g, NV_PTOP_DEVICE_INFO_AMPERE(*(int*)idx) - 3)) info_type = 2; | ||
| 170 | } | ||
| 171 | // Parse and print the data | ||
| 172 | switch(info_type) { | ||
| 173 | case 0: | ||
| 174 | seq_printf(s, "| instance %d\n", curr_info.inst_id_ampere); | ||
| 175 | seq_printf(s, "| Fault ID: %3d\n", curr_info.fault_id_ampere); | ||
| 176 | seq_printf(s, "| Engine Type: %2d (", curr_info.engine_type_ampere); | ||
| 177 | if (curr_info.engine_type_ampere < ENGINE_TYPES_LEN) | ||
| 178 | seq_printf(s, "%s)\n", ENGINE_TYPES_NAMES[curr_info.engine_type_ampere]); | ||
| 179 | else | ||
| 180 | seq_printf(s, "Unknown Engine, introduced post-Ampere)\n"); | ||
| 181 | break; | ||
| 182 | case 1: | ||
| 183 | seq_printf(s, "| BAR0 Base %#.8x\n", curr_info.pri_base_ampere << 12); | ||
| 184 | seq_printf(s, "| Reset ID: %2d\n", curr_info.reset_enum_ampere); | ||
| 185 | break; | ||
| 186 | case 2: | ||
| 187 | seq_printf(s, "| Host's Engine ID: %2d\n", curr_info.engine_enum_ampere); | ||
| 188 | seq_printf(s, "| Runlist ID: %2d\n", curr_info.runlist_enum_ampere); | ||
| 189 | break; | ||
| 190 | default: | ||
| 191 | // Device info records are sparse, so skip unset or unknown ones | ||
| 192 | return 0; | ||
| 193 | } | ||
| 194 | |||
| 195 | // Draw a line between each device entry | ||
| 196 | if (!curr_info.has_next_entry_ampere) { | ||
| 197 | seq_printf(s, "+---------------------+\n"); | ||
| 198 | } | ||
| 199 | return 0; | ||
| 200 | } | ||
| 201 | |||
| 202 | |||
| 107 | static void device_info_file_seq_stop(struct seq_file *s, void *idx) { | 203 | static void device_info_file_seq_stop(struct seq_file *s, void *idx) { |
| 108 | // No cleanup needed | 204 | // No cleanup needed |
| 109 | } | 205 | } |
| 110 | 206 | ||
| 111 | static const struct seq_operations device_info_file_seq_ops = { | 207 | static const struct seq_operations device_info_file_seq_ops_previous = { |
| 112 | .start = device_info_file_seq_start, | 208 | .start = device_info_file_seq_start_previous, |
| 113 | .next = device_info_file_seq_next, | 209 | .next = device_info_file_seq_next_previous, |
| 114 | .stop = device_info_file_seq_stop, | 210 | .stop = device_info_file_seq_stop, |
| 115 | .show = device_info_file_seq_show, | 211 | .show = device_info_file_seq_show_previous, |
| 212 | }; | ||
| 213 | |||
| 214 | static const struct seq_operations device_info_file_seq_ops_ampere = { | ||
| 215 | .start = device_info_file_seq_start_ampere, | ||
| 216 | .next = device_info_file_seq_next_ampere, | ||
| 217 | .stop = device_info_file_seq_stop, | ||
| 218 | .show = device_info_file_seq_show_ampere, | ||
| 116 | }; | 219 | }; |
| 117 | 220 | ||
| 118 | static int device_info_file_open(struct inode *inode, struct file *f) { | 221 | static int device_info_file_open_previous(struct inode *inode, struct file *f) { |
| 119 | return seq_open(f, &device_info_file_seq_ops); | 222 | return seq_open(f, &device_info_file_seq_ops_previous); |
| 120 | } | 223 | } |
| 121 | 224 | ||
| 122 | struct file_operations device_info_file_ops = { | 225 | static int device_info_file_open_ampere(struct inode *inode, struct file *f) { |
| 123 | .open = device_info_file_open, | 226 | return seq_open(f, &device_info_file_seq_ops_ampere); |
| 227 | } | ||
| 228 | |||
| 229 | struct file_operations device_info_file_ops_previous = { | ||
| 230 | .open = device_info_file_open_previous, | ||
| 124 | .read = seq_read, | 231 | .read = seq_read, |
| 125 | .llseek = seq_lseek, | 232 | .llseek = seq_lseek, |
| 126 | .release = seq_release, | 233 | .release = seq_release, |
| 127 | }; | 234 | }; |
| 235 | |||
| 236 | struct file_operations device_info_file_ops_ampere = { | ||
| 237 | .open = device_info_file_open_ampere, | ||
| 238 | .read = seq_read, | ||
| 239 | .llseek = seq_lseek, | ||
| 240 | .release = seq_release, | ||
| 241 | }; | ||
| @@ -554,34 +554,30 @@ static const char* const ENGINE_TYPES_NAMES[ENGINE_TYPES_LEN] = { | |||
| 554 | See dev_top.ref.txt of NVIDIA's open-gpu-doc for more info. | 554 | See dev_top.ref.txt of NVIDIA's open-gpu-doc for more info. |
| 555 | */ | 555 | */ |
| 556 | 556 | ||
| 557 | #ifdef NV_BUILD_FOR_AMPERE | 557 | #define NV_PTOP_DEVICE_INFO_AMPERE(i) (0x00022800+(i)*4) |
| 558 | #define NV_PTOP_DEVICE_INFO(i) (0x00022800+(i)*4) | 558 | #define NV_PTOP_DEVICE_INFO_PREVIOUS(i) (0x00022700+(i)*4) |
| 559 | #define NV_PTOP_DEVICE_INFO__SIZE_1 64 | 559 | #define NV_PTOP_DEVICE_INFO__SIZE_1 64 |
| 560 | typedef union { | 560 | typedef union { |
| 561 | struct { | 561 | struct { |
| 562 | uint32_t fault_id:7; | 562 | uint32_t fault_id_ampere:7; |
| 563 | uint32_t padding0:9; | 563 | uint32_t padding0_ampere:9; |
| 564 | uint32_t inst_id:4; | 564 | uint32_t inst_id_ampere:4; |
| 565 | uint32_t padding1:4; | 565 | uint32_t padding1_ampere:4; |
| 566 | enum ENGINE_TYPES engine_type:7; | 566 | enum ENGINE_TYPES engine_type_ampere:7; |
| 567 | bool has_next_entry:1; | 567 | bool has_next_entry_ampere:1; |
| 568 | } __attribute__((packed)); | 568 | } __attribute__((packed)); |
| 569 | struct { | 569 | struct { |
| 570 | uint32_t reset_enum:5; | 570 | uint32_t reset_enum_ampere:5; |
| 571 | uint32_t padding2:7; | 571 | uint32_t padding2_ampere:7; |
| 572 | uint32_t pri_base:12; | 572 | uint32_t pri_base_ampere:12; |
| 573 | uint32_t padding3_ampere:8; | ||
| 573 | } __attribute__((packed)); | 574 | } __attribute__((packed)); |
| 574 | struct { | 575 | struct { |
| 575 | uint32_t engine_enum:2; | 576 | uint32_t engine_enum_ampere:2; |
| 576 | uint32_t padding3:4; | 577 | uint32_t padding4_ampere:4; |
| 577 | uint32_t runlist_enum:14; | 578 | uint32_t runlist_enum_ampere:14; |
| 579 | uint32_t padding5_ampere:12; | ||
| 578 | } __attribute__((packed)); | 580 | } __attribute__((packed)); |
| 579 | uint32_t raw; | ||
| 580 | } ptop_device_info_t; | ||
| 581 | #else | ||
| 582 | #define NV_PTOP_DEVICE_INFO(i) (0x00022700+(i)*4) | ||
| 583 | #define NV_PTOP_DEVICE_INFO__SIZE_1 64 | ||
| 584 | typedef union { | ||
| 585 | // DATA type fields | 581 | // DATA type fields |
| 586 | struct { | 582 | struct { |
| 587 | enum DEVICE_INFO_TYPE info_type:2; | 583 | enum DEVICE_INFO_TYPE info_type:2; |
| @@ -619,7 +615,6 @@ typedef union { | |||
| 619 | } __attribute__((packed)); | 615 | } __attribute__((packed)); |
| 620 | uint32_t raw; | 616 | uint32_t raw; |
| 621 | } ptop_device_info_t; | 617 | } ptop_device_info_t; |
| 622 | #endif | ||
| 623 | 618 | ||
| 624 | #define NV_PTOP_SCAL_NUM_GPCS 0x00022430 | 619 | #define NV_PTOP_SCAL_NUM_GPCS 0x00022430 |
| 625 | #define NV_PTOP_SCAL_NUM_TPC_PER_GPC 0x00022434 | 620 | #define NV_PTOP_SCAL_NUM_TPC_PER_GPC 0x00022434 |
diff --git a/nvdebug_entry.c b/nvdebug_entry.c index 8e8266c..d82c648 100644 --- a/nvdebug_entry.c +++ b/nvdebug_entry.c | |||
| @@ -23,12 +23,14 @@ extern struct file_operations preempt_tsg_file_ops; | |||
| 23 | extern struct file_operations disable_channel_file_ops; | 23 | extern struct file_operations disable_channel_file_ops; |
| 24 | extern struct file_operations enable_channel_file_ops; | 24 | extern struct file_operations enable_channel_file_ops; |
| 25 | extern struct file_operations switch_to_tsg_file_ops; | 25 | extern struct file_operations switch_to_tsg_file_ops; |
| 26 | extern struct file_operations device_info_file_ops; | 26 | extern struct file_operations device_info_file_ops_previous; |
| 27 | extern struct file_operations device_info_file_ops_ampere; | ||
| 27 | extern struct file_operations nvdebug_read_reg32_file_ops; | 28 | extern struct file_operations nvdebug_read_reg32_file_ops; |
| 28 | 29 | ||
| 29 | // Bus types are global symbols in the kernel | 30 | // Bus types are global symbols in the kernel |
| 30 | extern struct bus_type platform_bus_type; | 31 | extern struct bus_type platform_bus_type; |
| 31 | struct nvdebug_state g_nvdebug_state[NVDEBUG_MAX_DEVICES]; | 32 | struct nvdebug_state g_nvdebug_state[NVDEBUG_MAX_DEVICES]; |
| 33 | int g_architectures[NVDEBUG_MAX_DEVICES]; | ||
| 32 | unsigned int g_nvdebug_devices = 0; | 34 | unsigned int g_nvdebug_devices = 0; |
| 33 | 35 | ||
| 34 | // Starting in Kernel 5.6, proc_ops is required instead of file_operations | 36 | // Starting in Kernel 5.6, proc_ops is required instead of file_operations |
| @@ -123,6 +125,7 @@ int probe_and_cache_device(void) { | |||
| 123 | return -EADDRNOTAVAIL; | 125 | return -EADDRNOTAVAIL; |
| 124 | } | 126 | } |
| 125 | g_nvdebug_state[i].chip_id = ids.chip_id; | 127 | g_nvdebug_state[i].chip_id = ids.chip_id; |
| 128 | g_architectures[i] = ids.architecture; | ||
| 126 | printk(KERN_INFO "[nvdebug] Chip ID %x (architecture %s) detected on PCI bus and initialized.", | 129 | printk(KERN_INFO "[nvdebug] Chip ID %x (architecture %s) detected on PCI bus and initialized.", |
| 127 | ids.chip_id, ARCH2NAME(ids.architecture)); | 130 | ids.chip_id, ARCH2NAME(ids.architecture)); |
| 128 | // TEMP | 131 | // TEMP |
| @@ -138,7 +141,7 @@ int probe_and_cache_device(void) { | |||
| 138 | } | 141 | } |
| 139 | 142 | ||
| 140 | // Create files `/proc/gpu#/runlist#`, world readable | 143 | // Create files `/proc/gpu#/runlist#`, world readable |
| 141 | int create_runlist_files(int device_id, struct proc_dir_entry *dir) { | 144 | int create_runlist_files_previous(int device_id, struct proc_dir_entry *dir) { |
| 142 | ptop_device_info_t info; | 145 | ptop_device_info_t info; |
| 143 | struct proc_dir_entry *rl_entry; | 146 | struct proc_dir_entry *rl_entry; |
| 144 | int i, rl_id; | 147 | int i, rl_id; |
| @@ -148,7 +151,7 @@ int create_runlist_files(int device_id, struct proc_dir_entry *dir) { | |||
| 148 | // registers. Runlists are always numbered sequentially, so we just have | 151 | // registers. Runlists are always numbered sequentially, so we just have |
| 149 | // to find the highest-valued one and add 1 to get the number of runlists. | 152 | // to find the highest-valued one and add 1 to get the number of runlists. |
| 150 | for (i = 0; i < NV_PTOP_DEVICE_INFO__SIZE_1; i++) { | 153 | for (i = 0; i < NV_PTOP_DEVICE_INFO__SIZE_1; i++) { |
| 151 | info.raw = nvdebug_readl(&g_nvdebug_state[device_id], NV_PTOP_DEVICE_INFO(i)); | 154 | info.raw = nvdebug_readl(&g_nvdebug_state[device_id], NV_PTOP_DEVICE_INFO_PREVIOUS(i)); |
| 152 | if (info.info_type != INFO_TYPE_ENUM || !info.runlist_is_valid) | 155 | if (info.info_type != INFO_TYPE_ENUM || !info.runlist_is_valid) |
| 153 | continue; | 156 | continue; |
| 154 | if (info.runlist_enum > max_rl_id) | 157 | if (info.runlist_enum > max_rl_id) |
| @@ -167,6 +170,34 @@ int create_runlist_files(int device_id, struct proc_dir_entry *dir) { | |||
| 167 | return 0; | 170 | return 0; |
| 168 | } | 171 | } |
| 169 | 172 | ||
| 173 | // Create files `/proc/gpu#/runlist#`, world readable | ||
| 174 | int create_runlist_files_ampere(int device_id, struct proc_dir_entry *dir) { | ||
| 175 | ptop_device_info_t info; | ||
| 176 | struct proc_dir_entry *rl_entry; | ||
| 177 | int i, rl_id; | ||
| 178 | char runlist_name[12]; | ||
| 179 | int max_rl_id = 0; // Always at least one runlist | ||
| 180 | // Figure out how many runlists there are by checking the device info | ||
| 181 | // registers. Runlists are always numbered sequentially, so we just have | ||
| 182 | // to find the highest-valued one and add 1 to get the number of runlists. | ||
| 183 | for (i = 0; i < (nvdebug_readl(&g_nvdebug_state[device_id], 0x0224fc) >> 20); i++) { | ||
| 184 | info.raw = nvdebug_readl(&g_nvdebug_state[device_id], NV_PTOP_DEVICE_INFO_AMPERE(i)); | ||
| 185 | if (info.runlist_enum_ampere > max_rl_id) | ||
| 186 | max_rl_id = info.runlist_enum; | ||
| 187 | } | ||
| 188 | // Create files to read each runlist. The read handling code looks at the | ||
| 189 | // PDE_DATA associated with the file to determine what the runlist ID is. | ||
| 190 | for (rl_id = 0; rl_id <= max_rl_id; rl_id++) { | ||
| 191 | snprintf(runlist_name, 12, "runlist%d", rl_id); | ||
| 192 | rl_entry = proc_create_data( | ||
| 193 | runlist_name, 0444, dir, compat_ops(&runlist_file_ops), | ||
| 194 | (void*)(uintptr_t)rl_id); | ||
| 195 | if (!rl_entry) | ||
| 196 | return -ENOMEM; | ||
| 197 | } | ||
| 198 | return 0; | ||
| 199 | } | ||
| 200 | |||
| 170 | // Create files /proc/gpu# | 201 | // Create files /proc/gpu# |
| 171 | // TODO: Don't run this on unsupported GPUs | 202 | // TODO: Don't run this on unsupported GPUs |
| 172 | int create_tpc_mask_files(int device_id, struct proc_dir_entry *dir) { | 203 | int create_tpc_mask_files(int device_id, struct proc_dir_entry *dir) { |
| @@ -212,7 +243,7 @@ int __init nvdebug_init(void) { | |||
| 212 | if (!(dir = proc_mkdir_data(device_id_str, 0555, NULL, (void*)device_id))) | 243 | if (!(dir = proc_mkdir_data(device_id_str, 0555, NULL, (void*)device_id))) |
| 213 | goto out_nomem; | 244 | goto out_nomem; |
| 214 | // Create files `/proc/gpu#/runlist#`, world readable | 245 | // Create files `/proc/gpu#/runlist#`, world readable |
| 215 | rl_create_err = create_runlist_files(device_id, dir); | 246 | rl_create_err = g_architectures[device_id] == 0x17 ? create_runlist_files_ampere(device_id, dir) : create_runlist_files_previous(device_id, dir); |
| 216 | // Create files `/proc/gpu#/gpc#_tpc_mask`, world readable | 247 | // Create files `/proc/gpu#/gpc#_tpc_mask`, world readable |
| 217 | tpc_masks_create_err = create_tpc_mask_files(device_id, dir); | 248 | tpc_masks_create_err = create_tpc_mask_files(device_id, dir); |
| 218 | // Create file `/proc/gpu#/preempt_tsg`, world writable | 249 | // Create file `/proc/gpu#/preempt_tsg`, world writable |
| @@ -233,7 +264,7 @@ int __init nvdebug_init(void) { | |||
| 233 | (void*)device_id); | 264 | (void*)device_id); |
| 234 | // Create file `/proc/gpu#/device_info`, world readable | 265 | // Create file `/proc/gpu#/device_info`, world readable |
| 235 | device_info_entry = proc_create_data( | 266 | device_info_entry = proc_create_data( |
| 236 | "device_info", 0444, dir, compat_ops(&device_info_file_ops), | 267 | "device_info", 0444, dir, compat_ops(g_architectures[device_id] == 0x17 ? &device_info_file_ops_previous : &device_info_file_ops_ampere), |
| 237 | (void*)device_id); | 268 | (void*)device_id); |
| 238 | // Create file `/proc/gpu#/num_gpcs`, world readable | 269 | // Create file `/proc/gpu#/num_gpcs`, world readable |
| 239 | num_gpcs_entry = proc_create_data( | 270 | num_gpcs_entry = proc_create_data( |
