aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nvdebug.h46
-rw-r--r--nvdebug_entry.c150
2 files changed, 125 insertions, 71 deletions
diff --git a/nvdebug.h b/nvdebug.h
index f0662cd..39b2e6e 100644
--- a/nvdebug.h
+++ b/nvdebug.h
@@ -436,7 +436,9 @@ typedef union {
436#define NV_MC_BOOT_0 0x00000000 436#define NV_MC_BOOT_0 0x00000000
437#define NV_CHIP_ID_GP106 0x136 // Discrete GeForce GTX 1060 437#define NV_CHIP_ID_GP106 0x136 // Discrete GeForce GTX 1060
438#define NV_CHIP_ID_GV11B 0x15B // Jetson Xavier embedded GPU 438#define NV_CHIP_ID_GV11B 0x15B // Jetson Xavier embedded GPU
439
439#define NV_CHIP_ID_KEPLER 0x0E0 440#define NV_CHIP_ID_KEPLER 0x0E0
441#define NV_CHIP_ID_MAXWELL 0x120
440#define NV_CHIP_ID_PASCAL 0x130 442#define NV_CHIP_ID_PASCAL 0x130
441#define NV_CHIP_ID_VOLTA 0x140 443#define NV_CHIP_ID_VOLTA 0x140
442#define NV_CHIP_ID_VOLTA_INTEGRATED 0x150 444#define NV_CHIP_ID_VOLTA_INTEGRATED 0x150
@@ -700,29 +702,47 @@ typedef union {
700 uint32_t raw; 702 uint32_t raw;
701} ptop_device_info_gk104_t; 703} ptop_device_info_gk104_t;
702 704
703/* Graphics Processing Cluster (GPC) information 705/* Graphics Processing Cluster (GPC) on-chip information
704 The GPU's Compute/Graphics engine is subdivided into Graphics Processing 706 The GPU's Compute/Graphics engine is subdivided into Graphics Processing
705 Clusters (also known as GPU Processing Clusters, starting with Ampere). 707 Clusters (also known as GPU Processing Clusters, starting with Ampere).
706 708
707 Each GPC is subdivided into Texture Processing Clusters (TPCs) which contain 709 Each GPC is subdivided into Texture Processing Clusters (TPCs) which contain
708 Streaming Multiprocessors (SMs). 710 Streaming Multiprocessors (SMs).
709 711
712 The number of these units etched onto the chip may vary from the number
713 enabled and software-visible. These registers expose the number of on-chip
714 GPCs, the number of on-chip TPCs inside a GPC.
710 715
716 Support: Fermi through (at least) Blackwell
711*/ 717*/
712// Support: Fermi through Blackwell
713// Get the number of GPCs **on die**
714#define NV_PTOP_SCAL_NUM_GPCS 0x00022430 718#define NV_PTOP_SCAL_NUM_GPCS 0x00022430
715// Get the number of TPCs per GPC **on die**
716#define NV_PTOP_SCAL_NUM_TPC_PER_GPC 0x00022434 719#define NV_PTOP_SCAL_NUM_TPC_PER_GPC 0x00022434
717// GPC and TPC masks 720
718// Support: Maxwell, Pascal, Volta, Turing 721/* Graphics Processing Cluster (GPC) enablement information
719// Bitmask of which GPC **are enabled** of the max on die 722 (See above for a description of GPCs and TPCs.)
720#define NV_FUSE_GPC 0x00021c1c 723
721// Bitmask of which TPCs **are enabled** on each GPC 724 The number of on-chip GPCs and TPCs enabled is driven by:
722#define NV_FUSE_TPC_FOR_GPC(i) (0x00021c38+(i)*4) 725 1) Manufacturing errors which make some units nonfunctional.
723// Support: Ampere, Ada, Hopper, Blackwell 726 2) Commercialization decisions about how many units should be enabled for a
724//#define NV_FUSE_GPC 0x00820c1c 727 specific GPU model.
725//#define NV_FUSE_TPC_FOR_GPC(i) (0x00820c38+(i)*4) 728
729 Generally, reason (1) drives disablement early in product manufacturing,
730 whereas, as the manufacturing process matures, (2) steps in to ensure
731 consistency between early-manufactured and late-manufactured products.
732
733 On-chip fuses are used to dictate which units are enabled and disabled. These
734 registers expose the fuse configuration for GPCs, and the TPCs in each GPC.
735
736 FUSE_GPC : Bitmask of which GPCs are enabled
737 FUSE_TPC_FOR_GPC(i) : Bitmask of which TPCs are enabled for GPC i
738
739 Support: Maxwell through Blackwell
740 Note the registers were relocated starting with Ampere.
741*/
742#define NV_FUSE_GPC_GM107 0x00021c1c
743#define NV_FUSE_TPC_FOR_GPC_GM107(i) (0x00021c38+(i)*4)
744#define NV_FUSE_GPC_GA100 0x00820c1c
745#define NV_FUSE_TPC_FOR_GPC_GA100(i) (0x00820c38+(i)*4)
726 746
727/* Logical Copy Engine (LCE) Information 747/* Logical Copy Engine (LCE) Information
728 Every GPU has some number of copy engines which can process transfers to, 748 Every GPU has some number of copy engines which can process transfers to,
diff --git a/nvdebug_entry.c b/nvdebug_entry.c
index 7593a3a..0cf5344 100644
--- a/nvdebug_entry.c
+++ b/nvdebug_entry.c
@@ -12,7 +12,8 @@
12#include "nvdebug.h" 12#include "nvdebug.h"
13#include "stubs.h" 13#include "stubs.h"
14 14
15// Enable to intercept and log GPU interrupts 15// Enable to intercept and log GPU interrupts. Historically used to benchmark
16// interrupt latency.
16#define INTERRUPT_DEBUG 0 17#define INTERRUPT_DEBUG 0
17 18
18// MIT is GPL-compatible. We need to be GPL-compatible for symbols like 19// MIT is GPL-compatible. We need to be GPL-compatible for symbols like
@@ -31,14 +32,16 @@ extern struct file_operations copy_topology_file_ops;
31extern struct file_operations nvdebug_read_reg32_file_ops; 32extern struct file_operations nvdebug_read_reg32_file_ops;
32extern struct file_operations nvdebug_read_reg_range_file_ops; 33extern struct file_operations nvdebug_read_reg_range_file_ops;
33 34
34// Bus types are global symbols in the kernel
35extern struct bus_type platform_bus_type;
36struct nvdebug_state g_nvdebug_state[NVDEBUG_MAX_DEVICES]; 35struct nvdebug_state g_nvdebug_state[NVDEBUG_MAX_DEVICES];
37unsigned int g_nvdebug_devices = 0; 36unsigned int g_nvdebug_devices = 0;
37// Bus types are global symbols in the kernel
38extern struct bus_type platform_bus_type;
38 39
39// Starting in Kernel 5.6, proc_ops is required instead of file_operations 40// Starting in Kernel 5.6, proc_ops is required instead of file_operations.
41// As file_operations is larger than proc_ops, we can overwrite the memory
42// backing the file_operations struct to follow the proc_ops layout, and then
43// cast on newer kernels.
40#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) 44#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
41// This rewrites the struct to the proc_ops layout on newer kernels
42const struct proc_ops* compat_ops(const struct file_operations* ops) { 45const struct proc_ops* compat_ops(const struct file_operations* ops) {
43 struct proc_ops new_ops = {}; 46 struct proc_ops new_ops = {};
44 new_ops.proc_open = ops->open; 47 new_ops.proc_open = ops->open;
@@ -64,7 +67,7 @@ irqreturn_t nvdebug_irq_tap(int irq_num, void * dev) {
64 67
65// Find any and all NVIDIA GPUs in the system 68// Find any and all NVIDIA GPUs in the system
66// Note: This function fails if any of them are in a bad state 69// Note: This function fails if any of them are in a bad state
67int probe_and_cache_device(void) { 70int probe_and_cache_devices(void) {
68 // platform bus (SoC) iterators 71 // platform bus (SoC) iterators
69 struct device *dev = NULL; 72 struct device *dev = NULL;
70 struct device *temp_dev; 73 struct device *temp_dev;
@@ -143,13 +146,14 @@ int probe_and_cache_device(void) {
143#endif // INTERRUPT_DEBUG 146#endif // INTERRUPT_DEBUG
144 i++; 147 i++;
145 } 148 }
146 // Return the number of devices we found 149 // Return the number of devices found
147 if (i > 0) 150 if (i > 0)
148 return i; 151 return i;
149 return -ENODEV; 152 return -ENODEV;
150} 153}
151 154
152// Create files `/proc/gpu#/runlist#`, world readable 155// Create files `/proc/gpu#/runlist#`, world readable
156// Support: Fermi, Maxwell, Pascal, Volta, Turing
153int create_runlist_files(int device_id, struct proc_dir_entry *dir) { 157int create_runlist_files(int device_id, struct proc_dir_entry *dir) {
154 ptop_device_info_gk104_t info; 158 ptop_device_info_gk104_t info;
155 struct proc_dir_entry *rl_entry; 159 struct proc_dir_entry *rl_entry;
@@ -179,16 +183,24 @@ int create_runlist_files(int device_id, struct proc_dir_entry *dir) {
179 return 0; 183 return 0;
180} 184}
181 185
182// Create files /proc/gpu# 186// Create files `/proc/gpu#/gpc#_tpc_mask`, world readable
183// TODO: Don't run this on unsupported GPUs 187// Support: Maxwell+
184int create_tpc_mask_files(int device_id, struct proc_dir_entry *dir) { 188int create_tpc_mask_files(int device_id, struct proc_dir_entry *dir) {
189 struct nvdebug_state* g = &g_nvdebug_state[device_id];
185 char file_name[20]; 190 char file_name[20];
186 int i; 191 int i;
187 struct proc_dir_entry *gpc_tpc_mask_entry; 192 struct proc_dir_entry *gpc_tpc_mask_entry;
188 // Get a bitmask of which GPCs are disabled
189 uint32_t gpcs_mask = nvdebug_readl(&g_nvdebug_state[device_id], NV_FUSE_GPC);
190 // Get maximum number of enabled GPCs for this chip 193 // Get maximum number of enabled GPCs for this chip
191 uint32_t max_gpcs = nvdebug_readl(&g_nvdebug_state[device_id], NV_PTOP_SCAL_NUM_GPCS); 194 uint32_t max_gpcs = nvdebug_readl(&g_nvdebug_state[device_id], NV_PTOP_SCAL_NUM_GPCS);
195 // Get a bitmask of which GPCs are disabled
196 uint32_t gpcs_mask;
197 if (g->chip_id < NV_CHIP_ID_AMPERE)
198 gpcs_mask = nvdebug_readl(g, NV_FUSE_GPC_GM107);
199 else
200 gpcs_mask = nvdebug_readl(g, NV_FUSE_GPC_GA100);
201 // Verify the reads succeeded
202 if (max_gpcs == -1 || gpcs_mask == -1)
203 return -EIO;
192 // For each enabled GPC, expose a mask of disabled TPCs 204 // For each enabled GPC, expose a mask of disabled TPCs
193 for (i = 0; i < max_gpcs; i++) { 205 for (i = 0; i < max_gpcs; i++) {
194 // Do nothing if GPC is disabled 206 // Do nothing if GPC is disabled
@@ -196,9 +208,14 @@ int create_tpc_mask_files(int device_id, struct proc_dir_entry *dir) {
196 continue; 208 continue;
197 // If GPC is enabled, create an entry to read disabled TPCs mask 209 // If GPC is enabled, create an entry to read disabled TPCs mask
198 snprintf(file_name, 20, "gpc%d_tpc_mask", i); 210 snprintf(file_name, 20, "gpc%d_tpc_mask", i);
199 gpc_tpc_mask_entry = proc_create_data( 211 if (g->chip_id < NV_CHIP_ID_AMPERE)
200 file_name, 0444, dir, compat_ops(&nvdebug_read_reg32_file_ops), 212 gpc_tpc_mask_entry = proc_create_data(
201 (void*)(uintptr_t)NV_FUSE_TPC_FOR_GPC(i)); 213 file_name, 0444, dir, compat_ops(&nvdebug_read_reg32_file_ops),
214 (void*)(uintptr_t)NV_FUSE_TPC_FOR_GPC_GM107(i));
215 else
216 gpc_tpc_mask_entry = proc_create_data(
217 file_name, 0444, dir, compat_ops(&nvdebug_read_reg32_file_ops),
218 (void*)(uintptr_t)NV_FUSE_TPC_FOR_GPC_GA100(i));
202 if (!gpc_tpc_mask_entry) 219 if (!gpc_tpc_mask_entry)
203 return -ENOMEM; 220 return -ENOMEM;
204 } 221 }
@@ -206,64 +223,84 @@ int create_tpc_mask_files(int device_id, struct proc_dir_entry *dir) {
206} 223}
207 224
208int __init nvdebug_init(void) { 225int __init nvdebug_init(void) {
209 struct proc_dir_entry *dir, *preempt_entry, *disable_channel_entry, 226 struct proc_dir_entry *dir;
210 *enable_channel_entry, *switch_to_tsg_entry, *device_info_entry, 227 int err, res;
211 *num_gpcs_entry;
212 int rl_create_err, tpc_masks_create_err;
213 // Check that an NVIDIA GPU is present and initialize g_nvdebug_state 228 // Check that an NVIDIA GPU is present and initialize g_nvdebug_state
214 int res = probe_and_cache_device(); 229 if ((res = probe_and_cache_devices()) < 0)
215 if (res < 0)
216 return res; 230 return res;
217 g_nvdebug_devices = res; 231 g_nvdebug_devices = res;
218 // Create seperate ProcFS directories for each gpu 232 // Create seperate ProcFS directories for each gpu
219 while (res--) { 233 while (res--) {
220 char device_id_str[7]; 234