nx_gpu_mem_gate.nx source
↩ module page · 121 lines · 7811 B
1// nx_gpu_mem_gate.nx -- gpu GP6 heaps and residency on the real device, driven directly through nx_gpu_mem.
2//
3// Teeth: the budget is READ from the device for both segment groups; a bounded window of heaps (well under the budget)
4// is allocated, placed and made resident; every heap is then EVICTED through the device's own EVICT and the proof of
5// eviction is the device's own paging answer -- a make-resident after the evict returns DXG_MKRES_PENDING, where a heap
6// that was never evicted answers 0. Tampers: an evict of a bogus handle is refused; a budget query for an invalid
7// segment group is refused; and a positive control after the tampers reads the same local budget back.
8// THE THIRD STATE: absent /dev/dxg (every host but the GPU laptop) is a gv_need precondition -> SKIP, never RED.
9// SCOPE the board carries: the heaps are non-local (sysmem-backed, UMD-less); exhausting the LOCAL segment to force
10// driver-initiated eviction needs VRAM allocations the vendor UMD owns, and exhausting the non-local segment would
11// exhaust the host's RAM -- so this gate proves the EVICT MECHANISM and the budget accounting, not budget exhaustion.
12// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 (or 3 = SKIP where there is no /dev/dxg)
13import "nx_syscalls.nx"
14import "nx_dxg.nx"
15import "nx_gpu_sync.nx"
16import "nx_gpu_mem.nx"
17import "nx_gate_verdict.nx"
18
19const GMG_HEAPS: i64 = 16
20const GMG_HEAP_BYTES: i64 = 1048576 // 1 MiB per heap: 16 MiB in flight, a bounded window under any budget here
21const GMG_BAD_GROUP: i64 = 5
22const GMG_BOGUS_ALLOC: i64 = 0xdeadbeef
23
24func main() -> i64 {
25 let ctr: *i64 = gv_ctr()
26 gv_head("nx_gpu_mem_gate -- GP6 heaps and residency: budget read from the 5080, heaps placed and resident, evicted through the device and proven evicted by its paging answer" as *u8)
27
28 let fd: i64 = dxg_open()
29 var have: i64 = 0
30 if fd >= 0 { have = 1 }
31 if gv_need("a /dev/dxg device to allocate on (absent on every host but the GPU laptop)" as *u8, have, ctr) == 0 {
32 return gv_verdict("nx_gpu_mem_gate" as *u8, ctr, "subject absent: no /dev/dxg on this host" as *u8)
33 }
34 let ah: *i64 = sys_mmap(16) as *i64
35 let dh: *i64 = sys_mmap(16) as *i64
36 let orc: i64 = gpu_sync_open(fd, ah, dh)
37 gv_check("T1-the-discrete-adapter-and-a-device-resolve" as *u8, orc == 0, ctr)
38 if orc != 0 { sys_close(fd); return gv_verdict("nx_gpu_mem_gate" as *u8, ctr, "the device did not resolve; nothing below could run" as *u8) }
39 let adapter: i64 = ah[0]
40 let device: i64 = dh[0]
41
42 // the budget, read from the device, both segment groups
43 let bl: *i64 = sys_mmap(64) as *i64
44 let bn: *i64 = sys_mmap(64) as *i64
45 let bl_rc: i64 = gpu_mem_budget(fd, adapter, DXG_SEG_LOCAL, bl)
46 let bn_rc: i64 = gpu_mem_budget(fd, adapter, DXG_SEG_NONLOCAL, bn)
47 gv_puts(" local: budget=" as *u8); gv_num(bl[0]); gv_puts(" usage=" as *u8); gv_num(bl[1]); gv_puts(" reservation=" as *u8); gv_num(bl[2]); gv_puts(" available=" as *u8); gv_num(bl[3]); gv_puts("\n" as *u8)
48 gv_puts(" non-local: budget=" as *u8); gv_num(bn[0]); gv_puts(" usage=" as *u8); gv_num(bn[1]); gv_puts(" reservation=" as *u8); gv_num(bn[2]); gv_puts(" available=" as *u8); gv_num(bn[3]); gv_puts("\n" as *u8)
49 gv_check("T2-the-local-segment-budget-is-read-from-the-device-and-positive" as *u8, bl_rc == 0, ctr)
50 gv_check("T3-the-non-local-segment-budget-is-read-from-the-device-and-positive" as *u8, bn_rc == 0, ctr)
51 let window: i64 = GMG_HEAPS * GMG_HEAP_BYTES
52 gv_check("T4-the-heap-window-is-bounded-under-the-non-local-budget" as *u8, window < bn[0], ctr)
53
54 // a paging queue for placement, then the heaps
55 let pqh: *i64 = sys_mmap(16) as *i64
56 let pqf: *i64 = sys_mmap(16) as *i64
57 let pqr: i64 = dxg_create_pq(fd, device, pqh, pqf)
58 gv_check("T5-a-paging-queue-is-created-for-placement" as *u8, pqr == 0, ctr)
59 let t: *i64 = gm_table_new()
60 let mapf: *i64 = sys_mmap(16) as *i64
61 let resf: *i64 = sys_mmap(16) as *i64
62 var placed: i64 = 0
63 var i: i64 = 0
64 while i < GMG_HEAPS {
65 if gpu_mem_heap(fd, device, pqh[0], t, i, GMG_HEAP_BYTES, mapf, resf) == 0 { placed = placed + 1 }
66 i = i + 1
67 }
68 gv_puts(" heaps placed+resident=" as *u8); gv_num(placed); gv_puts(" of " as *u8); gv_num(GMG_HEAPS); gv_puts(" x " as *u8); gv_num(GMG_HEAP_BYTES); gv_puts(" B\n" as *u8)
69 gv_check("T6-every-heap-in-the-window-allocates-places-and-becomes-resident" as *u8, placed == GMG_HEAPS, ctr)
70
71 // the device's accounting after residency: MEASURED on the first run, the non-local usage rose by EXACTLY the
72 // window (0 -> 16,777,216 for 16 x 1 MiB), so the delta is pinned -- the budget ruler counts our heaps, byte for byte
73 let bn2: *i64 = sys_mmap(64) as *i64
74 let bn2_rc: i64 = gpu_mem_budget(fd, adapter, DXG_SEG_NONLOCAL, bn2)
75 gv_puts(" non-local after residency: usage=" as *u8); gv_num(bn2[1]); gv_puts(" (was " as *u8); gv_num(bn[1]); gv_puts(", window " as *u8); gv_num(window); gv_puts(")\n" as *u8)
76 gv_check("T7-the-budget-query-still-answers-with-the-same-non-local-budget-after-placement" as *u8, (bn2_rc == 0) & (bn2[0] == bn[0]), ctr)
77 gv_check("T7b-the-device-accounts-the-resident-window-exactly-usage-delta-equals-the-bytes-placed" as *u8, bn2[1] - bn[1] == window, ctr)
78
79 // EVICT every heap through the device, then prove it by the device's own paging answer
80 var evicted: i64 = 0
81 let trim: *i64 = sys_mmap(16) as *i64
82 i = 0
83 while i < GMG_HEAPS {
84 if gpu_mem_evict(fd, device, t, i, trim) == 0 { evicted = evicted + 1 }
85 i = i + 1
86 }
87 gv_check("T8-every-heap-is-evicted-through-the-device-EVICT" as *u8, evicted == GMG_HEAPS, ctr)
88 let bn3: *i64 = sys_mmap(64) as *i64
89 let bn3_rc: i64 = gpu_mem_budget(fd, adapter, DXG_SEG_NONLOCAL, bn3)
90 gv_puts(" non-local after evict: usage=" as *u8); gv_num(bn3[1]); gv_puts("\n" as *u8)
91 gv_check("T8b-the-usage-falls-back-to-the-pre-placement-value-after-the-evicts" as *u8, (bn3_rc == 0) & (bn3[1] == bn[1]), ctr)
92 var pending: i64 = 0
93 var still: i64 = 0
94 i = 0
95 while i < GMG_HEAPS {
96 let rr: i64 = gpu_mem_reresident(fd, pqh[0], t, i, resf)
97 if rr == DXG_MKRES_PENDING { pending = pending + 1 }
98 if rr == 0 { still = still + 1 }
99 i = i + 1
100 }
101 gv_puts(" re-resident answers: pending(evicted)=" as *u8); gv_num(pending); gv_puts(" still-resident=" as *u8); gv_num(still); gv_puts("\n" as *u8)
102 gv_check("T9-the-device-reports-every-evicted-heap-as-PAGING-PENDING-on-re-residency-the-eviction-was-real" as *u8, pending == GMG_HEAPS, ctr)
103
104 // tampers
105 let bogus: *i64 = sys_mmap(64) as *i64
106 bogus[0] = GMG_BOGUS_ALLOC
107 let et: i64 = dxg_evict(fd, device, GMG_BOGUS_ALLOC, trim)
108 gv_check("neg-control-T10-an-evict-of-a-bogus-allocation-handle-is-refused" as *u8, et < 0, ctr)
109 let bb: *i64 = sys_mmap(64) as *i64
110 let bad_rc: i64 = dxg_query_vidmem(fd, adapter, GMG_BAD_GROUP, bb)
111 var bad_refused: i64 = 0
112 if bad_rc != 0 { bad_refused = 1 }
113 if bad_rc == 0 { if bb[0] == 0 { bad_refused = 1 } }
114 gv_check("neg-control-T11-a-budget-query-for-an-invalid-segment-group-is-refused-or-empty" as *u8, bad_refused == 1, ctr)
115 let bl2: *i64 = sys_mmap(64) as *i64
116 let bl2_rc: i64 = gpu_mem_budget(fd, adapter, DXG_SEG_LOCAL, bl2)
117 gv_check("T12-positive-control-the-local-budget-reads-back-identical-after-the-tampers" as *u8, (bl2_rc == 0) & (bl2[0] == bl[0]), ctr)
118
119 sys_close(fd)
120 return gv_verdict("nx_gpu_mem_gate" as *u8, ctr, "budget read from the device, a bounded heap window placed and resident, every heap evicted through the device and proven evicted by its paging answer; local-segment exhaustion is UMD-bound and stays on the board" as *u8)
121}