aboutsummaryrefslogtreecommitdiffstats
path: root/runlist.c
diff options
context:
space:
mode:
authorJoshua Bakita <jbakita@cs.unc.edu>2021-09-22 11:02:45 -0400
committerJoshua Bakita <jbakita@cs.unc.edu>2021-09-22 11:16:58 -0400
commitb69863043538d9fd4590acb249124526772a80ea (patch)
tree5f1329a97c7c1ff80823362e7538ab5fc6ea6eaf /runlist.c
parent54e783959b5d3622556bbf34a3a7ad8e481d9e25 (diff)
Fix a pre-4.19 bug in seq procfs files and add detailed channel print
- The sequence file infrastructure prior to kernel version 4.19 has a bug in the retry code when the write buffer overflows that causes our private iterator state to be corrupted. Work around this by tracking some info out-of-band. - Now supports including detailed channel status information from channel RAM when printing the runlist. - Adds helper function to probe for and return struct gk20a*.
Diffstat (limited to 'runlist.c')
-rw-r--r--runlist.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/runlist.c b/runlist.c
index 8691b51..8dfa1c7 100644
--- a/runlist.c
+++ b/runlist.c
@@ -8,23 +8,20 @@
8// Bus types are global symbols in the kernel 8// Bus types are global symbols in the kernel
9extern struct bus_type platform_bus_type; 9extern struct bus_type platform_bus_type;
10 10
11int get_runlist_iter(struct runlist_iter *rl_iter) { 11struct gk20a* get_live_gk20a(void) {
12 struct device *dev = NULL; 12 struct device *dev = NULL;
13 struct device *temp_dev; 13 struct device *temp_dev;
14 struct gk20a *g; 14 struct gk20a *g;
15 struct entry_tsg head; 15 struct nvgpu_os_linux *l;
16 runlist_base_t rl_base;
17 runlist_info_t rl_info;
18 u64 runlist_iova;
19 // Get the last device that matches our name 16 // Get the last device that matches our name
20 while ((temp_dev = bus_find_device_by_name(&platform_bus_type, dev, "17000000.gv11b"))) { 17 while ((temp_dev = bus_find_device_by_name(&platform_bus_type, dev, "17000000.gv11b"))) {
21 dev = temp_dev; 18 dev = temp_dev;
22 printk(KERN_INFO "[nvdebug] Found a matching device %s\n", dev_name(dev)); 19 printk(KERN_INFO "[nvdebug] Found a matching device %s\n", dev_name(dev));
23 } 20 }
24 if (!dev) 21 if (!dev)
25 return -EIO; 22 return NULL;
26 g = get_gk20a(dev); 23 g = get_gk20a(dev);
27 // This address seems to not be: 24 // The address pointed to `regs` + NV_PFIFO_RUNLIST_BASE seems to not be:
28 // - A GPU address (type is sysmem_coherent) 25 // - A GPU address (type is sysmem_coherent)
29 // - A physical address (dereferencing after ioremap crashes) 26 // - A physical address (dereferencing after ioremap crashes)
30 // - A kernel virtual address (dereferencing segfaults) 27 // - A kernel virtual address (dereferencing segfaults)
@@ -49,15 +46,23 @@ int get_runlist_iter(struct runlist_iter *rl_iter) {
49 // BUT, it turns out that it IS JUST A PHYSICAL ADDRESS! It wasn't working 46 // BUT, it turns out that it IS JUST A PHYSICAL ADDRESS! It wasn't working
50 // before because the GPU had simply gone to sleep and invalidated its 47 // before because the GPU had simply gone to sleep and invalidated its
51 // register state, so nvgpu_readl() was simply returning garbage. 48 // register state, so nvgpu_readl() was simply returning garbage.
52 49 l = container_of(g, struct nvgpu_os_linux, g);
53 printk(KERN_INFO "[nvdebug] Pulling runlist base address from %x\n", NV_PFIFO_RUNLIST_BASE);
54 printk(KERN_INFO "[nvdebug] Using struct gk20a* of %px\n", g);
55 printk(KERN_INFO "[nvdebug] g->name: %s, g->power_on: %d, g->sw_ready: %d, g->is_virtual %d\n",
56 g->name, g->power_on, g->sw_ready, g->is_virtual);
57 struct nvgpu_os_linux *l = container_of(g, struct nvgpu_os_linux, g);
58 printk(KERN_INFO "[nvdebug] l->regs %px, l->regs_saved %px\n", l->regs, l->regs_saved);
59 if (!l->regs) 50 if (!l->regs)
60 return -EIO; 51 return NULL;
52 return g;
53}
54
55/* Get runlist head and info (incl. length)
56 @param rl_iter Location at which to store output
57*/
58int get_runlist_iter(struct runlist_iter *rl_iter) {
59 struct entry_tsg head;
60 runlist_base_t rl_base;
61 runlist_info_t rl_info;
62 u64 runlist_iova;
63 struct gk20a *g = get_live_gk20a();
64 if (!g)
65 return -EIO;
61 rl_base.raw = nvdebug_readl(g, NV_PFIFO_RUNLIST_BASE); 66 rl_base.raw = nvdebug_readl(g, NV_PFIFO_RUNLIST_BASE);
62 rl_info.raw = nvdebug_readl(g, NV_PFIFO_RUNLIST); 67 rl_info.raw = nvdebug_readl(g, NV_PFIFO_RUNLIST);
63 runlist_iova = ((u64)rl_base.ptr) << 12; 68 runlist_iova = ((u64)rl_base.ptr) << 12;