aboutsummaryrefslogtreecommitdiffstats
path: root/runlist.c
diff options
context:
space:
mode:
authorJoshua Bakita <bakitajoshua@gmail.com>2024-09-16 15:34:41 -0400
committerJoshua Bakita <bakitajoshua@gmail.com>2024-09-16 15:34:41 -0400
commit232eafd04f272ed69d97a250c50a7bbed4d2894c (patch)
treebf1d03cd66e6f37b2c9ac9a9d48e4f359fcdd6b5 /runlist.c
parent0b1c304e53b88fe628d350d1380a88317f071e69 (diff)
Support printing the runlist and channels on Ampere+ GPUs
**Modifes the user API from `cat /proc/gpuX/runlist0` to `cat /proc/gpuX/runlist0/runlist` to support runlist-scoped registers** - Count number of runlists via Ampere-style PTOP parsing. - Create a ProcFS directory for each runlist, and create the runlist printing file in this directory. - Document the newly-added/-formatted Runlist RAM and Channel RAM registers. - Add a helper function `get_runlist_ram()` to obtain the location of each runlist's registers. - Support printing Ampere-style Channel RAM entries. Tested on Jetson Orin (ga10b), A100, H100, and AD102 (RTX 6000 Ada)
Diffstat (limited to 'runlist.c')
-rw-r--r--runlist.c69
1 files changed, 67 insertions, 2 deletions
diff --git a/runlist.c b/runlist.c
index 2e9577d..7e6d292 100644
--- a/runlist.c
+++ b/runlist.c
@@ -14,6 +14,52 @@
14// be enabled to print the runlist on the TX2. 14// be enabled to print the runlist on the TX2.
15//#define FALLBACK_TO_PRAMIN 15//#define FALLBACK_TO_PRAMIN
16 16
17/* Get RunList RAM (RLRAM) offset for a runlist from the device topology
18 @param rl_id Which runlist to obtain [numbered in order of appearance in
19 the device topology (PTOP) registers]
20 @param rl_ram_off Location at which to store runlist private register
21 interface base address (PRI base); an offset into the BAR0
22 register range.
23 @return 0 or -errno on error
24*/
25int get_runlist_ram(struct nvdebug_state *g, int rl_id, uint32_t *rl_ram_off) {
26 int i;
27 int curr_rl_id = 0;
28 int ptop_size = NV_PTOP_DEVICE_INFO__SIZE_1_GA100(g);
29 // Each PTOP entry is composed of 1--3 subrows, and the fields available
30 // on each row vary. The runlist RAM location is only available on row 3
31 int ptop_entry_subrow = 0;
32 ptop_device_info_ga100_t ptop_entry;
33 // Iterate through all PTOP entries
34 for (i = 0; i < ptop_size; i++) {
35 if ((ptop_entry.raw = nvdebug_readl(g, NV_PTOP_DEVICE_INFO_GA100(i))) == -1)
36 return -EIO;
37 // Skip empty entries
38 if (!ptop_entry.raw)
39 continue;
40 // If on subrow 3 (zero-base-index 2), runlist info is available
41 // Multiple engines may be associated with a single runlist, so
42 // multiple PTOP entries may refer to the same runlist. Only match when
43 // on the 0th-associated entry.
44 if (ptop_entry_subrow == 2 && ptop_entry.rleng_id == 0) {
45 // If this is the requested runlist, return it
46 if (curr_rl_id == rl_id) {
47 *rl_ram_off = (uint32_t)ptop_entry.runlist_pri_base << 10;
48 return 0;
49 }
50 // Otherwise, update our accounting of what the next runlist ID is
51 curr_rl_id++;
52 }
53 // Track if the next row is a subrow of the current entry
54 if (ptop_entry.has_next_entry)
55 ptop_entry_subrow += 1;
56 else
57 ptop_entry_subrow = 0;
58 }
59 // Search failed; requested index does not exist
60 return -EINVAL;
61}
62
17/* Get runlist head and info (incl. length) 63/* Get runlist head and info (incl. length)
18 @param rl_id Which runlist to obtain? 64 @param rl_id Which runlist to obtain?
19 @param rl_iter Location at which to store output 65 @param rl_iter Location at which to store output
@@ -39,7 +85,7 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl
39 runlist_target = rl.target; 85 runlist_target = rl.target;
40 runlist_len = rl.len; 86 runlist_len = rl.len;
41 printk(KERN_INFO "[nvdebug] Runlist %d for %x: %d entries @ %llx in %s (config raw: %#018llx)\n", 87 printk(KERN_INFO "[nvdebug] Runlist %d for %x: %d entries @ %llx in %s (config raw: %#018llx)\n",
42 rl_id, g->chip_id, rl.len, runlist_iova, target_to_text(rl.target), rl.raw); 88 rl_id, g->chip_id, rl.len, runlist_iova, target_to_text(rl.target), rl.raw);
43 } else if (g->chip_id < NV_CHIP_ID_AMPERE) { 89 } else if (g->chip_id < NV_CHIP_ID_AMPERE) {
44 runlist_base_tu102_t base; 90 runlist_base_tu102_t base;
45 runlist_submit_tu102_t submit; 91 runlist_submit_tu102_t submit;
@@ -51,7 +97,26 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl
51 runlist_target = base.target; 97 runlist_target = base.target;
52 runlist_len = submit.len; 98 runlist_len = submit.len;
53 printk(KERN_INFO "[nvdebug] Runlist %d for %x: %d entries @ %llx in %s (config raw: %#018llx %#018llx)\n", 99 printk(KERN_INFO "[nvdebug] Runlist %d for %x: %d entries @ %llx in %s (config raw: %#018llx %#018llx)\n",
54 rl_id, g->chip_id, submit.len, runlist_iova, target_to_text(runlist_target), base.raw, submit.raw); 100 rl_id, g->chip_id, submit.len, runlist_iova, target_to_text(runlist_target), base.raw, submit.raw);
101 } else {
102 runlist_base_tu102_t base;
103 runlist_submit_tu102_t submit;
104 uint32_t runlist_pri_base;
105 // Runlist configurations are stored in per-runlist regions on Ampere+
106 if ((err = get_runlist_ram(g, rl_id, &runlist_pri_base)) < 0)
107 return err;
108 // The runlist configuration region (RLRAM) contains Turing-like BASE
109 // and SUBMIT registers at static offsets
110 if ((base.raw = nvdebug_readq(g, runlist_pri_base + NV_RUNLIST_BASE_GA100)) == -1)
111 return -EIO;
112 if ((submit.raw = nvdebug_readq(g, runlist_pri_base + NV_RUNLIST_SUBMIT_GA100)) == -1)
113 return -EIO;
114 runlist_iova = ((uint64_t)base.ptr) << 12;
115 runlist_target = base.target;
116 runlist_len = submit.len;
117 printk(KERN_INFO "[nvdebug] Runlist %d for %x: %d entries @ %llx in %s (config raw: %#018llx %#018llx)\n",
118 rl_id, g->chip_id, submit.len, runlist_iova, target_to_text(runlist_target), base.raw, submit.raw);
119 rl_iter->runlist_pri_base = runlist_pri_base;
55 } 120 }
56 // Return early on an empty runlist 121 // Return early on an empty runlist
57 if (!runlist_len) 122 if (!runlist_len)