summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
Commit message (Collapse)AuthorAge
* vgsp: rescue the direct-GL draw-state pushes from the LOW fb band, admit ↵HEADmasterArthur Hanson Rasmusson3 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | them to the 3D replay lane, and let the forced golden MME overlay satisfy the prelude maturity gate (eng28) The direct-GL client's draw-state pushes (476/624/728/324 B; invariant lead 90110087 = IMMD NVC597_INVALIDATE_SHADER_CACHES 0x21C<-0x1011) are intermittently unreadable while byte-identical copies park in the LOW framebuffer; the copies do not share the VA's in-page offset, so the page-stepped rescue scan could never land on them. Add a word-granular LOW-band sweep gated on the two recognisable push images (state lead via the method-stream window gate; 256-B VTG SPH upload by exact signature) and pin hits exactly like the existing rescue. The same pushes carry the frame's real state (SET_COLOR_CLEAR_VALUE 0xD80, NVC597_CLEAR_SURFACE 0x19D0, MME macro calls, vertex state) but no BEGIN/RT opener, so they never opened a C597 section and the state stream never reached the replay lane; admit the 0x21C lead as an opener on beef channels and exempt state-led windows from the eng25 colour-target guard (the guard's data-blob rejects continue unchanged - only the invariant state lead passes). Where the client's 0x114 IRAM upload is not captured (code words stay <= 4 on every boot observed), the forced golden overlay (sema_gl_mme_golden + _force; golden-only, fail-closed) can serve every called macro slot; add gsp_phys_gr_golden_ready() and skip the IMMATURE-SKIP software completion while it holds (see the golden-slot/pack machinery). Live (c348/c350/c351, r1624 params): the LOW-band rescue fired (VTG SPH 256-B push -> fb 0x2010200, pinned); the 324-B state push opened a section, captured (recs=4 nprog=1) and was marked for the verbatim 3D lane; with the bypass the lane submitted it to the engine for the first time (GR LAUNCH submitted + GUEST GR LAUNCH OK, MME-PRELUDE pack 1701 IR words, MME-GOLDEN slot 0 accepted). The emitted 51-word window still omits the 0xD80/0x19D0 clear runs (marked window 81), so pixel stores remain 0 and frames black; receipts under /tmp/opencode/eng28-*. Refs: CONT.490.
* vgsp: add sema_draw_census - bounded draw-marker census over every client ↵Arthur Hanson Rasmusson4 hours
| | | | | | | | | | | | | | | | | | | | | push (eng26 instrument) One green cycle must answer 'which push carries the direct-GL draw'. The census scans every non-engine push with the canonical op/cnt run grammar and logs one bounded row per push containing any draw-family method id (BEGIN 0x1618, END 0x1614, VA_START 0xd74, DRAW_VERTEX_ARRAY 0xd78, index 0x17c8/0x17d8/0x17e0, draw list 0x1b0, vertex streams 0x1c00/0x1c10), with the hit's word index inside its run so a run that merely NUMERICALLY spans a method address is distinguishable from a real method data word. Beef pushes without hits are enumerated once per (va,len) so the cycle yields a full push inventory. Module param sema_draw_census (default 0), 256 hit + 256 push rows, read-only. Live result (c346): full beef push inventory captured; every marker 'hit' is a k>0 lattice artifact of a data blob (e.g. the 59580-B push's single m=0 run at off=0x78 covers 0x1b0..0x1c10 at fixed word indices, and its BEGIN-address word value changes between reads - 0x00058202 then 0x01047220), i.e. no push carries a real draw method stream. Companion to a4215afa; docs in CONT.487.
* vgsp: reject beef draw-synth windows whose last colour-target bind is ↵Arthur Hanson Rasmusson4 hours
| | | | | | | | | | | | | | | | | | | | | | unusable (eng25 correctness guard) The direct-GL lane's draw-synth captures join the verbatim 3D replay lane by numerical run-cover alone, so a non-method data blob whose INC run merely spans the C597 RT block is replayed as state: its last A/B/W/H write per colour target is an unmapped 40-bit VA (c344: RT1 -> 0xff000480a0) and the engine retires with no stores (NOWRITE wrote=0). Gate the beef 'd' admission (single-block and chunk-split) on svc_gl_window_rt_valid(): walk the window with the run grammar, keep the last A/B/W/H write per colour target, and require at least one usable bind (A[7:0]<=1, B<2^30 aligned, 1<=W,H<=0x4000). Validated live (c346, mdev 53dc06b5, ENG26 instrument cycle): 23 bounded '3D mark rejected (beef draw-synth: no valid last colour-target bind)' rows, including the 14865-word 59580-B blob window @off=0x78 and the 542-word 0x4010ed0 twin; the one timing-variant window that does carry a usable RT bind still passed and replayed (wrote=0), and the X lane is unregressed (15x '3D stream marked h=0x1000013' + 'GUEST GR LAUNCH OK' ok=16/17). Refs: CONT.486/487; eng25/eng26 evidence under /tmp/opencode/eng26-*.
* vgsp: route direct-GL draw-synth captures through the verbatim 3D replay ↵Arthur Hanson Rasmusson4 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | lane; beef rel_mod launches may take the ch_rel release branch (eng24) Clause 1 (gsp_sema_service.c, svc_gl_flush): the direct-GL (beef-family) section captures opened by the eng23 inside-run openers carry synthesized PROG/PARAM/REL (src=draw-synth) but a REAL method window; include 'd' in the stream-3d marking (single 448-word block and the method-aligned chunk split) so the window replays verbatim on the engine like the X/stream/hold lanes, instead of waiting on a synthesized compute-QMD release the engine never writes. Verified live: '3D stream chunked h=0xbeef0100 push=0x4250110 window=779 words -> 3 chunk(s)' and 'GR LAUNCH submitted h=0xbeef0100 ... polling qmd_rel=0'. Clause 2 (gsp_phys_booter.c, gsp_phys_backend_guest_gr_submit): a beef-family launch whose QMD release0 was redirected to the module semaphore with the rel_mod sentinel (0x600df00d) may break its poll on the channel release alone (the X lane's proven branch) once the engine has retired the method block; witnessed by 'GR LAUNCH OK ch_rel branch (beef rel_mod; ...)'. Verified live: 4+ beef launches now complete (engine fetch OK, GUEST GR LAUNCH OK ok=22..25) where the c338 shape timed out (qmd_rel=0xc0ffee01 want=0x600df00d). Known residual (unchanged by this commit): the replayed beef windows retire without stores (NOWRITE-CONFIRMED/AMBIGUOUS, wrote=0 -> px0=0), the same engine-store wall the X lane shows; and with the default sema_mme_immature_skip=1 the service soft-completes replayed beef windows before any engine contact (A/B with the knob at 0 was used to put the real window on the engine).
* vgsp: RM-record 3D attach + inside-run C597 openers for the direct-GL ↵Arthur Hanson Rasmusson5 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | channel (eng23, mechanism validated) The direct-GL (GZDoom/glx) channel family 0xbeef01xx never opened a C597 section because its class bind is channel-side: the client allocates TURING_A (0xc597) with hParent = its own channel (measured: alloc 0xc597 h=0xbeef9097 parent=0xbeef0100 client=0xc1d00013) and never re-emits a SET_OBJECT push, so the section recognizer's sticky-attachment gate (svc_gl_att_accept_run) dropped every push. The X lane binds inline in its init push and was unaffected. - gsp_rm_emulation.c: report the 0xc597 allocation's hParent to the sema service (gsp_sema_service_gl_attach), which applies it as the sticky 3D attach on its own thread (pending-slot queue; no cross-thread writes to the attachment tables). - gsp_sema_service.[ch]: the queue + drain (svc_thread pass), and accept the inside-run opener shapes on attached channels: the direct-GL client emits NVC597_BEGIN (0x1618) and the RT-setup family (0x840) as methods INSIDE multi-method INC runs (measured: run addr=0x80c count=256 covers 0x840..0xc0c; census decoded method=0x1618 op=1 from a run payload), not as the one-word IMMD form the X lane emits. - Also carries the eng22-rescue scan-cap widening (0x4000000 -> full 2 GiB shadow; observed live: "no content-gated window in 0x80000000 shadow"). Validated live (c335/c337/c338, receipts /tmp/opencode/eng23-receipts-c331.txt): - RM-record attach fires and applies for 0xbeef0100 (c335 12:49:04, c338). - sections now open (c337) and capture (c338) on 0xbeef0100 incl. the 59556-B setup push and the 6400-B draw push (src=draw-synth). - first GR LAUNCH submitted for 0xbeef0100 (c338 13:01:58) - fails at the physical QMD release (qmd_rel=0xc0ffee01 want=0x600df00d); new frontier. - px0 still 00000000; mission not launched. A/B control: the same X-lane lottery behaviour was reproduced with the pre-change module (c333), so no X-lane regression is attributable here.
* vgsp: content-gated FB-shadow push rescue for recycled client pushes (eng20, ↵Arthur Hanson Rasmusson7 hours
| | | | | | | | | | | | | | | | | | end-to-end validation pending) The direct-GL client's one-shot 59,556 B setup push (VA 0x4001004) reads zero at decode time: the live page is recycled before our decode runs, so no C597 bind attaches for h=0xbeef0100. The rescue recovers the push body from the FB shadow with strict content gates: reject fill windows (require >=2 multi-word INC runs + >=8 distinct headers), scan at the push VA's in-page offset (0x4041004 starts 4 B into a page), and log the channel handle. eng20 refuted the unregistered-VAS hypothesis: the payload pages DO walk via VAS 0xbeef0300 (0x4000000->pa=0x342ead000, 0x4001000->pa=0x342eae000, consistent delta). Also found: sema_gl_xlate (absent from params-r1780; default 0) gates every C597 section-recognition site - with it on, the lane produced its first C597 captures (127x c305, 20x c307). Validation cyclic c308 (guest init panic) / c309 (QGA wedge) blocked; no observation yet. Unvalidated end to end.
* vgsp: extend the live PA acceptance bound to the registered guest-RAM top ↵Arthur Hanson Rasmusson8 hours
| | | | | | | | | | | | | | | | (svc_pa_max/svc_push_pa_ceiling) The direct-GL client parks its VAS page directory and push pages in the 4-14 GiB high RAM band while the runtime bound stopped at 10 GiB (param/compile), so svc_ap_ok rejected every walk read above 10 GiB before vfio_dma_rw could answer: the client ring walk reported 'L0 read fail' / 'walk rc=-2' on the one boot the RAM content scan latched the real ring (c296), and the push bodies stayed unreadable (src=3 window garbage / src=255). svc_pa_max() now never shrinks below the registered guest-RAM top (sanity-clamped to the scan max), and svc_push_pa_ceiling() floors on the same live bound. c297 (first boot with the fix): 'RING-VAS h=0xbeef0100 gpfifo=0x4020000 mapped by VAS 0xbeef0300 (pdb=0x110aae000) -> pa=0x23771f000' and pushdec 'src=4 plausible=1' with the read ceiling witness ceil=0x380000000.
* vgsp: reject the dense-lookalike class in svc_gr_ram_ring_scan ↵Arthur Hanson Rasmusson9 hours
| | | | | | | | | | | | | | | | | | (entry0==entry1 gate) The GL client ring content scan admitted the lookalike page measured at pa 0x10a828000 / 0x10ad3e000 (dword 0x04000100 repeating) whose entry0 and entry1 decode identically (va=0x4000100 len=262144) and which passed every window/terminus gate. The pump then read a phantom 256 KiB push at VA 0x4000100 forever (sema-rdw rc=-2, sema-entry: unread, unregistered submissions=0; c271/c285), poisoning the client-VAS verify chain. A real ring does not repeat one entry verbatim in slots 0/1. Partial validation: c288 (fixed module) resolved the REAL ring pair via the VAS (pa=0x235f7c000, entry0 va=0x4000000 len=2236) and decoded real client pushes (submissions=15, CB-DIAG match=67). End-to-end pixel validation (gl_frames px0 != 0) is still pending; c286/c287 did not exercise the scan (no channel created).
* vgsp: CB parser decode fix + pre-replay FE context clear attempt (cwd3 latch ↵Arthur Hanson Rasmusson12 hours
| | | | | | | | | | | | | | | | | | | | | | | | | survives; zero-store persists) (a) svc_gl_cb_upload_scan decode now follows the class definitions (cla16f.h: method 11:0, subchannel 15:13): addr=(hdr&0xfff)<<2, subch=(hdr>>13)&7; selector B/C swapped (0x2384=B=ADDRESS_UPPER high dword, 0x2388=C=lower, cla097.h); 0x238c runs apply [offset][constants...] inline data. CB-DIAG prints subch. Other classes untouched. (b) Pre-replay CWD poison clear for the stream3d lane: new gsp_phys_gr_cwd_clear_locked() (checks 0x404490/0x40706c/0x400504 for 0xbadf, runs the wedge recovery's bounded TSG preempt/resched re-arm + shared latch wipe) before build_gr_launch; once per launch, stream3d+sema_gr_wedge_recover gated (CUDA/CE unaffected). Validation (c250-c254, rich args, ladder armed): the re-arm probes green ('WEDGE-REARM probe rc=0 (engine ALIVE)') but the cwd3 latch does NOT move ('CWD-CLEAR after re-arm ... cwd3=badf5040') and wrote=0 persists (0/1024) with the 0x1528 trap gone under sema_gl_shader_exc=0 - clause (b) is falsified as sufficient: the poison is not the TSG/PBDMA context the re-arm touches. CB-DIAG on these draws shows n3800/n39c8/n2390=0 because bit 12 is 0 on that stream (old/new decodes identical there) - the parser fix stands on the class definition. X regressed to the DDX DMA wall on these cycles (DMA-init 0x51 + per-start SIGSEGVs), so clean gl_frames windows were rare.
* vgsp: serve word-34..47 section pages from their resolved PAs; seed the ↵Arthur Hanson Rasmusson15 hours
| | | | | | | | | | | | | | | | | | | | | | | | | pointer pairs (n_data 0->1024) The final-pixel-wall data window: svc_gr_data_fill discarded a candidate page that HAD resolved in gr_pages (launch_internal blanket skip: c203 evidence 'page[2] va=0x120400000 pa=0xa00000 ap=2 word=34' + '10 candidate ptrs, 0 pages resolved; 7 dropped' -> GR-DEC n_data=0), and the stream3d lane (qmd=0x0) never seeded the capture's decoded operand pairs (inline-QMD words 34..47) as candidates. Serve word-34..47 pages from their resolved gr_pages PA (li_pa, span=1; word 32/48/49 stay excluded as before) and seed the pointer pairs from a request-carried copy (race-free vs the capture ring). Live proof c215: 'li cand va=0x120400000 word=34 pa=0xa00000 ap=2' -> 'GR-DEC n_data=1024' (was 0). Residual: the 1524 B first-frame's pointer pages are not yet resolvable at that instant (n_ptr_req=5 seed_add=0; frames 2+ resolve 1024) - resolver timing, documented. Also documented (no change): the copy-out refusal for dst=0x120700000 (the GL client's fixed-CB page) falls through to the forced-seed path and is benign for pixels; the TRUE px0 blocker is engine-zero-write: every stream3d launch ends 'NOWRITE-CONFIRMED ... n_data=1024 tracked=1024 wrote=0' + 'NOWRITE-REGS fe_esr=0x80000000 trap=0x8000022c/00000800/00000000' even with the full RT window (SURF-PRELUDE target=0xa000000) - the engine executes but stores nothing.
* vgsp: DDX latch adoption grace + last-proven-block parking (X now lives >10 min)Arthur Hanson Rasmusson17 hours
| | | | | | | | | | | | | | | | | | | | | | | | | Thread A of the X longevity wall, validated c195/c198 (rich args + tick): - Adoption grace: gr_ram_userd_adopt_at stamped at every DDX fresh-adopt site; svc_userd_ddx_reprobe refuses a speculative switch within 1 s of an adopt (kills the c190/c197 same-pass cascade to frozen lookalikes). - Clause 3: the last CONFIRMED block is parked (pa/as/put/probes) on every DDX confirm; svc_userd_ddx_park_probe checks it first in the re-probe and discovery scan and prefers it when its PUT advances across two probes (kick excluded, half-ring bound, reset re-syncs). Receipts: c195 X GREEN >10 min with 0 DMA failures ('shape scan fb 0x8f0000 -> CONFIRMED 2->6 at +63 ms, zero SWITCHED/DEFERRED/REJECTED all boot'); c198 GREEN >2 min likewise (+69 ms confirm, zero switches). Residual (documented): the RAM-scan 'LIVE' vote can still admit pool lookalikes on a first generation before any block is parked; the grace only delays that switch. Thread B (documented, no change): in c195's green window gl_frames still reads black (px0=0, ~12 s/frame) although the rich args capture the modern-GL sections ('sema-gl: 3D stream marked', 'section captured len=1524' + 2 draw sections, prog-images vs=1408 ps=384) - ZERO GR LAUNCH and zero readback/copy-out lines; the beef0100 channel re-registers every ~13 s with submissions=0. Modern-GL work is section-captured but never executed/forwarded - the next frontier.
* vgsp: refuse DDX-family garbage USERD candidates (get>put) and bound the ↵Arthur Hanson Rasmusson17 hours
| | | | | | | | | | | | | | | | | | | | | | | speculative CONFIRM jump Wall (a) garbage-admission fix, validated c190-c194 (rich args + tick): - svc_gr_ram_userd_scan and the FB shape scan (svc_chan_userd) now refuse get > put for the DDX family (svc_userd_ddx_family), dropping the entries>1024 exemption that admitted c181's 'put=1 get=288190567' block; bounded refusal logs ('RAM scan REFUSES ...', 'userdp ... REFUSES fb ... (DDX get>put; c181 garbage class)'). - The pump's speculative CONFIRM bounds a non-wrap DDX (non-kick) forward PUT jump to gpfifo_entries/2 (mirrors the wrap bound); a runaway jump like c181's 'put 1 -> 1170688059' now falls to the DEFERRED/REJECT ladder ('forward PUT jump REFUSED ...'). Kick any-step and wrap paths unchanged; SYS/CE/UVM untouched. Receipts (5 cycles): 146 refusal lines (80 RAM, 66 FB), ZERO huge-jump confirms (all 16 confirms are real small steps), real blocks serving 25+24 submissions from pristine fb 0x8f0000 and RAM 0x11ae6e000. Residual wall (a): a same-pass re-probe switch to a frozen lookalike (c190) and a late 'Failed to idle DMA' at 60-130 s of X life; gl_frames still reads black (px0=0, ~12 s/frame) in the windows it ran (c193/c194).
* vgsp: flip-event delivery defaults to assoc+strict (clears Flip event ↵Arthur Hanson Rasmusson19 hours
| | | | | | | | | | | | | | | | | | | | | | | timeout); DDX latch reset clauses Wall (b) 'Flip event timeout on head 0' fix (validated c171): NVKMS/kernel- callback events register hSrcResource=0, so every display UPDATE completion rode the all-events shotgun (6-7 POST_EVENT records each), the guest's status-queue read cursor fell 20-44 slots behind (rc=-11 ring-full bursts) and flip records arrived past the 3 s NvDrm window. Default the r1765 pair ON - gsp_rm_ev_assoc (hSrc==0 -> alloc-parent channel) and gsp_disp_events_strict (armed UPDATE posts only to that channel's events, no fallback) - the exact combination r1771 measured as '0 flip WARNs'. Validating cycle c171: registrations carry real sources (hEvent=0x1007a hSrc=0x1001b etc.), UPDATE posts are exact 1:1 (posts=27), WARN count 1 for the boot, serial timeouts=0 (c160 pre-fix: 34). Both stay runtime-writable. Also stage the gsp_sema_service.c candidates for wall (a) (the later-DMA 0x51 is a consequence of 'Failed to idle DMA' on a recycled channel): the served-refusal in svc_userd_ddx_reprobe now exempts a latch reset to put==0, and the put-reset latch keep extends to the DDX family (was kick-only). These clauses target c171's observed reset/junk-adopt sequence; validation pending on a roll where wall (a) is otherwise survivable.
* vgsp: DDX re-probe stops once the latch has served (stops lookalike switch ↵Arthur Hanson Rasmusson20 hours
| | | | | | | | | | | | | | | | | | thrash) In svc_userd_ddx_reprobe, refuse to switch while the current latch has just delivered decoded entries (ch->submissions != gr_ram_userd_latch_sub), the same 'served' criterion the pump's DEFERRED clause uses. The switch path resets defers=0, so a defers-based guard would have stopped only the first of c141's six switches; forward-only nput>oput is semantically wrong for DDX generations (a fresh block starts with a tiny put) and would lock onto the junk maximum. Validated c150-c153 (rich args + tick): latch SWITCHED 0/run (was 6-8 at ~2 s), sema-xchan uok=1 continuous, and c152/c153 Xorg logs show ZERO 'Failed to (idle|initialize) DMA'/push-buffer/AddScreen lines - the ScreenInit DMA instance is now stable on the deferral alone. Residual (next): Xorg then spins in-kernel (95% CPU, SIGKILL-immune, xdpyinfo unanswered; userd put=0 get=0 vs last=7098 in sema-xchan is the lead) - gl_frames still hangs at BAR map.
* vgsp: DDX-family USERD latch lifetime - served-latch deferral + live ↵Arthur Hanson Rasmusson20 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | re-probe + FB backoff The X DDX's push-on-demand generations allocate a new USERD control block every 11-24 s, but the 15 s no-advance judge dropped the latch that had just passed the DMA test, and the next scan adopted a frozen FB lookalike (put=2 get=0) - the retry window then closed with 'Failed to idle DMA'. For the DDX/kick handle families only (0x01xxxxxx / 0xbfef00xx; SYS/CE/UVM untouched): - svc_userd_ddx_family() gates all of it; - a latch that HAS delivered decoded entries (submissions advanced since adoption, no contradiction) is DEFERRED from rejection (bound 32; timer reset) instead of dropped; - before any latch decision (and on a 2 s cadence while unconfirmed) the content scan re-probes the live path and switches the latch in place to a newly validated block (svc_userd_ddx_reprobe; near-empty page + ring-entry validation + PUT-step liveness are the ownership proof); - after a rejection the FB shape scan backs off 6 s so the RAM scan wins the window; the DDX re-probe is exempt from the retired slice budget (rejects < 255). Validated (c141, rich r1624 args, tick): X ScreenInit passed with ZERO 'Failed to (idle|initialize) DMA' / push-buffer / AddScreen lines; the channel decoded a 5090+-entry burst and served across block moves (latch SWITCHED 0x24128e100 -> 0x103774100 -> 0x122309d00, uok=1 held). Known residual (next refinement): the switch is not yet forward-only/ rate-limited, so lookalike blocks can oscillate at ~2 s and starve the client; make the switch require nput > latch_put and a >=10 s cadence (or stop switching once defers>0), then the real block wins.
* vgsp: X-DMA wall witness for 0x1000013; add params-r1624.txt (rich bring-up set)Arthur Hanson Rasmusson21 hours
| | | | | | | | | | | | | | | | One rate-limited (0.5 s) sema-xchan line per pass for the X DDX channel: rrc/uok/upa/uas/put/get/last/ring_pa/entry0 - names the decode-gate state independently of the shared userdp budget. Diagnostic only, no behaviour change. params-r1624.txt is the rich r1624 insmod set as a durable tools/guest-diag file (INSMOD_PARAMS=tools/guest-diag/params-r1624.txt). Context (c130/c131 with the rich set): the DDX DMA test now PASSES on most attempts (tracker release decoded + delivered); the remaining gap is the USERD speculative-latch lifetime (a latch that delivered the test kick is REJECTED 15 s later with no PUT advance; the next generation then adopts a stale VRAM block, put=2 get=0, and the retry window closes) plus a later 'Push buffer object allocation failed: 0x51 NV_ERR_NO_MEMORY' (emulated heap accounting; 1872 MiB free).
* vgsp: resolve the completion counter through its real aperture (fb/vidmem) ↵Arthur Hanson Rasmusson22 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | and use it on publish/flush The X DDX/kick channels' nvPush progress semaphore is a 4 KB sysmem surface whose GPU mapping resolves to the emulated VIDMEM aperture (va 0x20400ffe0 -> vidmem pa 0x3f8ffe0), while svc_counter_derive only accepted SVC_APERTURE_SYS translations; it therefore kept a false guest-RAM pair (a page holding unrelated data) and svc_counter_publish's put-advance both read and wrote the wrong page through the SYS aperture - the client's tracker never matched and the DDX failed 'Failed to initialize DMA' after its 10 s push-buffer sanity test. Carry the aperture with the registration (new svc_channel.counter_ap, svc_cnt_der[].ap): accept FB translations in the derive chain (chanvas, vaspaces, discovered; targeted stays SYS), probe with the found aperture, keep it through pin override/re-registration; svc_counter_publish and svc_counter_flush_pending read/write through it (release_pa stays SYS). Live receipts (c109/c110, 12 GiB guest, params-r1780): - counter derived h=0x1000013 ... pa=0x211c42fe0 (rank=1) with pub-adv writing 14..26 (was silently skipped on a false page in c107); - the DDX's OWN C36F tracker releases decode and land: 'sema-push h=0x1000013 va=0x1200a0000 ... rel=0x120001000 pay=1 have_rel=1' -> 'sema-sw h=0x1000013 va=0x120001000 pa=0x11cc68000 ap=1 val=0x1 rc=0 rb_ok=1' - the 10 s push-buffer test's exact wait word is delivered and the DDX proceeds to further work (values advancing 0x4017e..0x24024f); previously no release ever decoded. Remaining X-side flakiness (a later DMA init still failing on some instances) is tracked in the handoff.
* vgsp: stop fabricating 0xFFFF into the nvPush error notifier; add r1780 GL ↵Arthur Hanson Rasmusson22 hours
| | | | | | | | | | | | | | | | | | | | | ops tooling The uncommitted keep-alive change wrote 0xFFFF into slot 0's status field (u16 at notifier+0x0e) on the X DDX / GLX kick-idle channel families. Ground truth (570.144 reference sources + stock nvidia_drv.so disassembly): slot 0 of an nvPush notifier block is the ERROR notifier; nvPushCheckChannelError reads that status and 0xFFFF aborts every nvPushWaitForNotifier/idle wait as a channel error. There is no pb_kickIfIdle in 570.144 - the DDX DMA-idle test reads the progress-tracker semaphore word, not this slot. Leave slot 0 untouched; keep the 0x8000->0 completion ack for the remaining slots and the r864 0xFFFF/0x8000 completion on the RC-watchdog/beef families. Correct the CONT.408/409 comments accordingly. New host/guest tooling: gpa.py (QMP gva2gpa), tick_gen.py (guest-RM timer BO tick), guest_mode.sh (shared nvClip modeNum reader), gl_verify.sh (X/GLX bring-up with ScreenInit-lottery retries), push_gl_tools.sh, the gzdoom_pbuf_run.sh guest recipe and the test_tri SDL2 harness validation program; ignore tools/guest-diag/build/.
* vgsp: accept wrapped FB USERD latches and dedup direct channel event postsArthur Hanson Rasmusson27 hours
|
* vgsp: direct-GL ring/push rescue, VAS/pdb scanners and PTIMER tick; r1780 ↵Arthur Hanson Rasmusson27 hours
| | | | cycle tooling
* vgsp: aperture-aware foreign USERD guard and wire fallbackArthur Hanson Rasmusson41 hours
| | | | | | | | | | | | | | c24 (V30) skipped the X/GLX channel's own sysmem USERD block because the same numeric PA 0x8f0000 is owned by the RC watchdog channel in vidmem; the X server then failed with 'Failed to initialize DMA' and 'Failed to allocate push buffer'. Compare the aperture as well as the page, and keep base 0 + userdOffset as a fallback when the client memory-object table cannot name the USERD (the resolver still wins when it has a verified object). This restores the c23 X bring-up while keeping the fail-closed table path. Validation pending a fresh V31 cycle: X starts, glxinfo/glxgears, chan_dump userd page/aper, and the USERD resolution/fallback witness lines.
* vgsp: resolve GSP-client USERD from hUserdMemory and skip foreign USERD pagesArthur Hanson Rasmusson41 hours
| | | | | | | | | | | | | | | | | | | | | | | | | GSP-client kernel channels carry their USERD as hUserdMemory[subdev] (NV_CHANNEL_ALLOC_PARAMS @32) plus userdOffset[subdev] (@64), leaving the userdMem memdesc (@168) zero. The service therefore adopted another live channel's USERD page (c23: h=0x1000013 took the RC watchdog h=0x31415900's block at fb 0x8f0000 every pass) and the Xorg PB progress wait never advanced. Remember client memory-object ALLOCs (class 0x3e sysmem, 0x40 vidmem; 0x70/0x50a0 are virtual ranges and are refused) in a bounded (hClient,hObject) table, alias them on DUP_OBJECT and retire them on FREE. At channel registration, if the wire userdMem base is zero, resolve hUserdMemory+userdOffset through that table and set userd_pa/userd_as only when the base is nonzero, page-aligned and in bounds; otherwise fail closed with a rate-limited reason. Also skip FB-sweep USERD candidates on a page already owned by another live channel. Validation pending a fresh V30 cycle: glxinfo -B exit 0, Xorg WAIT count 0, chan_dump h=0x1000013 userd!=0 ok=1 get advancing, sema-push have_rel=1, glxgears FPS unchanged, GZDoom -glversion 4.0 past V_Init. Evidence: handoff-meta-plan.md CONT.438; c23 X/GLX logs; ABI gsp_abi_check.c:1764, nvos.h:1631-1668, cl003e.h/cl0040.h.
* vgsp: gate the injected shared-surface pin author (default off)Arthur Hanson Rasmusson48 hours
| | | | | | | | | | The strict signature scan used to locate the shared surface can match a guest page-table page: the same 1.4M 'refCount/lkr' values reappear at the same offsets across VMs, and writing the lkr into it coincides with guest bad-pmd and soft-lockup storms in unrelated processes. Keep the VAS-walk author on, but require sema_gl_shsurf_pin=1 for the injected-pin page; only a page proven to be the client's shared surface (release target VA resolved through a verified VAS) should be authored.
* vgsp: pdb neighbourhood discovery + injected shared-surface pin syncArthur Hanson Rasmusson48 hours
| | | | | | | | | | | | | | | | | - when a content-verified ring pair is known, also scan a bounded window around every COPY_SERVER_PDES candidate pdb for a root that reproduces the pair; register the found root under the candidate's VAS handle so the channel's own VAS lookup resolves the ring even when the offered pdb is a stale incarnation - the periodic shared-surface watchdog now also honours an operator-injected shared-surface pin (sema_map_add): read lastKickoffRefCount at +0x880 and author it into gpuRefCount at +0x800, forward-only and validated Live receipt (r1780 c14): with the strict shared-surface signature page injected, the pin sync advanced gpuRefCount 1420471 -> 1420488 (== lkr), the DDX idle warning did not repeat, and GZDoom reached V_Init with X alive. Next walls observed: the DDX push-buffer idle wait (W2) at teardown and a guest OOM that kills gzdoom.
* vgsp: periodic GLX shared-surface refCount watchdogArthur Hanson Rasmusson2 days
| | | | | | | | | | | The GLX client writes lastKickoffRefCount during init before its first kick, while the X DDX may already poll gpuRefCount against it; if a previous client left the count lower the wait can only clear after the GLX request the DDX is blocking. Once per second (and on a manual sema_gl_shsurf_kick write) walk the known shared-surface VA and the last decoded release VA, and author the client's plausible lastKickoffRefCount forward-only. The strict lkr gate (high dword zero, small, cur < lkr) keeps it a no-op when the VA maps something else. Gated by sema_gl_shsurf_watch (default on).
* vgsp: direct-GL ring scan hardening + USERD orientation overridesArthur Hanson Rasmusson2 days
| | | | | | | | | | | | | | - per-rank GR shadow-scan cadence (the global 1.5 s window was consumed by the first channel in pump order, starving the direct-GL ring scan) - low-aperture ring content gate: entry0 within +/-8 MB of the ring VA and a zero terminus within the first 128 slots (dense data pages and transient copies were being latched as the ring and fed phantom entries) - stop skipping the guest-RAM content scan when the shadow-scan window is closed; only the shadow scan is rate-limited now - strict shared-surface author: write lastKickoffRefCount only, never the raw payload into an unvalidated translation - dev-only sema_userd_swap / sema_userd_override to test the direct-GL USERD orientation and a known control page; both default off
* vgsp: GLX shared-surface refCount fan-out + persistent direct-GL ring scanArthur Hanson Rasmusson2 days
| | | | | | | | | | | | | | | | V14: when the decoded GLX kickoff release targets the shared-surface gpuRefCount word, write the forward-only value through every published VAS translation and, when a candidate page carries a plausible lastKickoffRefCount at +0x880, author that value instead. The X DDX idle-channel wait compares those two words; a stale single-target write left it polling until its 5 s warning. Gated by sema_gl_shsurf_allvas (default on) with a bounded sema_gl_shsurf_dbg candidate log. V15: refresh the beef GR ring content-scan slice budget while the ring is unresolved and no submission has been observed, so a direct-GL client that registers an empty ring before its first kick is still found when it submits. Gated by sema_gr_ram_keep (default on). Adds a bounded per-second scan witness (cursor/passes/hit) and a read-failure witness.
* vgsp: verify the scrub ring ledger before authoring (P0 for the X/GL wedge, ↵Arthur Hanson Rasmusson2 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | CONT.427) - Resolve the channel GPFIFO ring page through the GPU page tables (the same resolver the stash geometry path trusts) instead of deriving it as "hsem page - entries*8"; that subtraction is only correct when the buffer's GPFIFO and sema pages are PA-contiguous, and it could land on a stale or dense page (r1775/r1777 boots). - Validate the first read with the strict GPFIFO entry shape (flag bits, length field, push VA bounded around the channel's own gpfifo) plus a clean zero terminus (the next slot and the following 32 slots must be zero). An all-zero page, a dense data page or a dirty tail is not trusted as a submission ledger. - Detect a guest scrubber reset by a regressed finish word (or fin returning to 0 while a release was authored) and reseed the ledger instead of re-applying the pre-reset absolute count - that re-application underflowed the guest's scrub-list size (r1775 c6: 4076 into an empty list -> 0xFFFFFFFFFFFFF014 -> the scrubCheckAndWaitForSize spin, _nv052600rm+0x7b). - Never author the finish word from an unverified or unresolved ring: fin stays a no-op. A blocked scrub wait is recoverable; an underflowed list is not. A/B: sema_scrub_ring=0 skips the ledger entirely. Live validation of this build is pending (6-cycle wedge acceptance + GZDoom run).
* vgsp: client-VAS CE ring probe + L0 sanity gate (V12, default off)Arthur Hanson Rasmusson2 days
| | | | | | | | | | | | | - CE siblings (0xbeef0101/0102): extend the beef-family ring discovery with an identity probe and the GR guest-RAM content scan plus a sparse-run gate and a RAM ring-page ownership table; keep >=2 fresh same-VAS park candidates during the client's VAS churn. - Add svc_pdb_l0_sane() and apply it to unverified directory candidates so a freed/reused incarnation is skipped instead of walked. - Both behaviors are gated behind sema_ce_ram (default 0): the live A/B latched false positives on dense data pages and the L0 predicate needs tightening before it may guard the GR lane (the validated V9/V10 GR behavior is preserved by the default).
* vgsp: kick-lane + client-VAS ring resolution upgrades (CONT.421-423)Arthur Hanson Rasmusson2 days
| | | | | | | | | | | | | | | | | | | | | | | - kick latch: keep an adopted-but-unconfirmed kick-family USERD latch across a transient put=0 (sema_kick_latch_keep, default 1) - the r1771 ADOPT->REJECT sequence dropped the block 7 s after adoption and left the GL/kick lane dark. - service-thread starvation: budget the VAS-PROMOTE walk log and back the promote sweep off 250 ms after a failed pass (sema_vas_promote_backoff, default 1); both brought ~100 pr_info/s down to <1/s during GZDoom's GL init stall; also budget the RING-VAS mapped print. - direct-GL client ring: always-probe the beef-family channels against the parked VAS candidates (sema_vas_client_ring, default 1, rate-limited per channel) with per-channel failure backoff, a smallest-unused-rank fallback (rank collision had disabled the content-scan backup) and oldest-same-VAS park eviction for the client's VAS churn. Live receipts: ring mapped, GR latch confirmed, push count 20->157, releases applied per frame (values 0x1->0x20), X channel-idle timeouts 0 during GL bursts. - Validation: glxgears 469-522 FPS (no regression); GZDoom now completes GL init and reaches screen allocation with the client lane live (~120 s) instead of dying seconds after V_Init.
* vgsp: ring-ledger scrub release + gated flip-event fixes (CONT.418-419)Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | | | | - gsp_sema_service: never fabricate scrub completions. The guest decrements its scrub-list size by the reported finish delta without a guard, so a fabricated delta larger than the pending list underflows it and the guest spins (~2^64) under the scrubber mutex (r1766-r1768 X soft-locks and guest panics; root-caused by static analysis + gdbstub decode of lastSeen/lastSubmitted/scrubListSize). The release now mirrors the registered channel's own ring: count new valid pushes (wrap-safe snapshot delta) and set the finish word forward-only to the cumulative count - exactly the work the guest submitted, never more. False ring-page registrations are detected and skipped (a mis-registered ring page had its first GPFIFO entry clobbered by an all-ones write). sema_scrub_ramp=0 keeps the legacy all-ones release for A/B; the finish word is never all-ones with the ledger enabled. - gsp_rm_emulation/gsp_display_engine: gate the hSrcResource==0 -> alloc parent event association behind ev_assoc (default 0) and keep strict display-event posting behind disp_events_strict (default 0) - both remain A/B knobs for the flip-event delivery fix. - Live validation (r1769): 4/4 green boots, 0 panics, 0 wedges; glprobe pixel=ff0000ff; gl_frames 500/500 non-black frames captured to a 45 s 640x480 mp4 via pbuffer -> sysmem -> ivshmem.
* vgsp: all-ones scrub release for registered waits; walk-page registration; ↵Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | GL frame publisher (CONT.416-417) - gsp_sema_service: merge a scanner registration arriving after the stash record instead of dropping it (a dropped registration let the next authoring pass write the blocking pair into the page the guest was polling, so the wait never ended); author the finish word all-ones for every registered record while the sema word stays put-based once real submissions were observed (CONT.416/417). - scrub_pin_qmp (host scanner): accept an unstable-but-live wait page instead of skipping it, and register the walk-resolved scrubber channel page - first the walk summary, then the per-VAS kernel row (h=0xc) when the summary path fails - so the release is armed before the guest polls (r1762/r1764 evidence). - guest-diag: add gl_frames, the direct-GL (GLX pbuffer) frame publisher; with it the stack produced the first non-black GPU-rendered frames (40/40, 640x480, animated) through pbuffer -> sysmem -> ivshmem -> host frame_reader. - gsp_rm_emulation: log the display-shim request words for triage.
* vgsp: author the scrub release pair for scanner-registered waits (CONT.414)Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | The X DDX vidheap scrub wait polls the finish payload at channel buffer +0x6c004 while the host still reads USERD GP_PUT=0, so put-based forward authoring wrote sema=entries-1 / fin=0: exactly the values that leave channelWaitForFreeEntry and channelWaitForFinishPayload blocked. Xorg then held the NVRM RM API write lock inside NV_ESC_RM_VID_HEAP_CONTROL, and the GL thread and nvidia-modeset both sat D-state on os_acquire_rwlock_write. A scanner-registered buffer with no observed submissions now gets the proven all-ones release pair (sema=fin=0xffffffff) and is re-authored every pass so a guest rewrite cannot re-block the wait. Put-driven records keep forward-only authoring. Result: the GL thread leaves D-state and a glClear+glFinish+glReadPixels probe returns rc=0 with pixel=ff0000ff (a real red readback).
* vgsp: USERD index/alias resolution, DDX kick-idle fix, completion-slot ↵Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | authorship (CONT.403-412) Ten debugging rounds against the direct-GL channel, each fixing the wall that blocked the previous one: - USERD index: honour USERD_INDEX_VALUE/PAGE_VALUE from NVOS04 flags (X idx=3, GL idx=4) instead of always reading the block at base+0. This fixed the X "Failed to initialize DMA" wall. - USERD alias: learn the BAR1-alias bias from the first ring-validated FB latch (wire 0x80600 -> live 0x910000) and prefer alias/wire-page candidates before falling back to the RAM scan, which previously adopted another channel's control page. - USERD latch: keep a ring-validated kick-family block across a transient put=0 instead of dropping it (bounded, per-channel log). - VAS alias: DUP_OBJECT copies pdb/entries/ap/verified so hVASpace 0xbfef0001 resolves to 0x10005 and its gpfifo VA stops re-resolving to a bogus FB PA. - Short-kick NOTIFY: complete a kick that has no armed class-2D target (release + event, no write) so the client proceeds past setup. - DDX kick-idle: slot 0 of the 0x01xxxxxx family is the pb_kickIfIdle gate and 0xFFFF is its IDLE value; the keepalive no longer zeroes it. Removes the GR-STALL-stale-wedge on the X channel. - Completion slots: register a per-channel completion on every successful kick and reuse it when a NOTIFY has no per-push SET_NOTIFY; prefer the channel's notifier page over the VA walk. - Empty/no-op submit: author the completion even when there is no push to replay, so a synchronous GL submit does not wait forever. - Scrub records: multi-record per guest, stash-first lookup, registered PA is authoritative against the GPU-VAS walk, scanner-only records author the proven 0xffffffff/0xffffffff pair. - GL attachment: accept a draw run whose own subchannel is the engine subchannel the channel uses (bind is subch 0, draws on subch 3), not only the bind subchannel. Measured: glxgears 427 -> 526 FPS sustained with no GR stall; X binds and renders its 2D path; 3D draw capture on the GL channel still does not occur (see CONT.412: the GL thread blocks on the NVRM RM write lock before it reaches any ioctl). Adds tools/guest-diag/scrub_pin_qmp.py to register guest channel-buffer vmap pages as scrub records from the host.
* vgsp: fix VAS-staleness on client restart + unstarve the ring scan (CONT.401)Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Three fixes, all verified live (cycle r1696): 1. Parked-VAS age-out flood. CONT.400 kept the candidate parked after registering it UNVERIFIED, so with sema_vas_cand_ms=1 the age-out re-registered and re-logged every pump pass (~480 lines/s) and each store memset the learned translation cache. Register once via a new 'aged_out' flag (reset when a slot is recycled); the candidate stays parked for the verified upgrade path. 2. Stale verified VAS on client restart. A client restart rebuilds its page directory under the SAME VAS handle (observed X 0x10005: pdb 0x12a82f000 -> 0x14b259000). CONT.400's 'never downgrade verified' guard then pinned the previous session's directory forever: the pump served stale ring/push pages, consumed zero entries and the DDX pushbuffer NOP test timed out ('Failed to initialize DMA' / 'Failed to allocate push buffer'). svc_chan_vas_candidate_promote now demotes a verified directory when a parked candidate names a different pdb, so the live one can be content-validated and installed. Result: X starts reliably and the pump consumes the 2D stream (chan_dump 0x1000014: get=1088 sub=1088). 3. Ring-scan starvation. The GR RAM content scan is budgeted to 40 slices per channel incarnation, and its only re-arm sits at the END of the pump loop, which is unreachable because svc_chan_userd() failure hits 'continue' first - exactly the unresolved-ring state that needs the scan. Re-arm before the USERD probe by reading the raw GP_PUT from the registered USERD block and resetting the bounded budget when it moves. Live result: glxgears now reports 529 FPS (was 0.15-0.22 FPS) with 'direct rendering: Yes' and the NVIDIA renderer string; the framebuffer is still black because the consumed command stream is not executed (see handoff CONT.401).
* vgsp: family-aware GR ring scan + GR completion event post (CONT.400)Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | | | | | | 1. svc_gr_ram_ring_scan: the direct-GL client's kernel channels live in the RM low aperture (ring 0x4020000, pushes 0x4000000/0x4001004/0x4250000/ 0xcae2894). The scan rejected every one of them: entry VAs below SEMA_VA_LO (0x100000000), entry-1 outside +/-1MB of the ring, and the 1MB-alignment gate in svc_gr_entry_plausible. For the low family (gpfifo_va in [0x4000000,0x10000000) or h_object 0xbeef0xxx) accept any low-aperture push VA, drop the 1MB alignment to 4 bytes, and use the low aperture as the upper bound. High-family rules unchanged. 2. GR completion event: a launch completion is an RM event edge, not only a memory word. The guest client waits in the RM software event queue (NV_ESC_RM_GET_EVENT_DATA), populated only by a GSP 0x1003 EVENT_POST_EVENT record. Post it via gsp_rm_post_channel_event_force() after the release is visible, on both the hold success edge and the software/failure edge. Diagnostics added: VAS-PROMOTE walk results and the RING-VAS probe. Open (see handoff CONT.400): the beef ring VA is still not mapped by any registered VAS, not at guest PA 0x4020000, not at vidmem 0x4020000. The guest never publishes the channel's effective TSG/device-default VAS via SET_PAGE_DIRECTORY; all registered VASes come from COPY_SERVER_PDES. Guest screen is 100% black; glxgears 0.2 FPS.
* vgsp: verified-VAS tracking + ring-VAS probe (CONT.400)Arthur Hanson Rasmusson3 days
| | | | | | | | | | | | | | | | | | | | | | | | | | The beef GR client channel (0xbeef0100) declares hVASpace==0 and its ring gpfifo=0x4020000 was never resolved (ring_pa=0, rrc=-2) for whole boots, so the whole GL draw stream was never decoded (black screen, 0.2 FPS). Root cause chain fixed here: - svc_chan_vas_candidate_promote returned early because it gated on svc_vaspace_known(), and the bounded age-out (sema_vas_cand_ms) had already registered the directory UNVERIFIED. It now gates on a new svc_vaspace_verified() and keeps retrying by content. - The age-out no longer clears the parked candidate (it used to consume it), so the content-verified upgrade path still has something to walk. - New 'verified' flag on struct svc_vaspace/sema_vaspace_desc; RM's own SET_PAGE_DIRECTORY, the verified ring walk, and the auto-discovered client VAS mark it verified; an unverified registration never downgrades a verified one. - New RING-VAS probe: when no parked candidate maps the ring VA, walk every registered directory for it and adopt the first that yields a plausible entry-0 push. Result: VAS 0xbeef0300 now registers VERIFIED (was always UNVERIFIED). The ring VA itself is still not mapped by any registered directory - the guest never publishes SET_PAGE_DIRECTORY to us; all VASes come from COPY_SERVER_PDES discovery. Diagnostic added for the next step.
* vgsp: WIP beef ring VAS promote + widen CB scan to draw channel (CONT.399)Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | - svc_chan_vas_candidate_promote: fall back to svc_channel_owner_vas when the GR client channel declares hVASpace==0 (the helper previously returned early for exactly the channel whose ring we need to resolve). - svc_gl_cb_upload_scan: also scan the 0x01xxxxxx RM-channel family (the channel that actually replays the draws), not only beef. NOT YET VERIFIED to resolve the beef ring: the CE siblings register ~19 ms after the GR channel, and VAS 0xbeef0300 is already 'known' (registered UNVERIFIED after 1 ms) by then, so the content-verify is skipped. The beef ring gpfifo=0x4020000 stays ring_pa=0 and the CB scan never runs. See CONT.399 in handoff-meta-plan.md for the full diagnosis.
* vgsp: fix X DMA init + GR backend timeouts (CONT.399)Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | X-DMA-FIX (gsp_sema_service.c): - svc_chan_userd: run the pristine-FB USERD scan when the r496b sweep ran on a resolved-but-unvalidated ring (ring_pa!=0 but no entry decoded), not only when the ring is untranslated. A stale pin/foreign VAS left the channel without a USERD and X's 10 s pushbuffer NOP test timed out ('Failed to initialize DMA'). - svc_fb_userd_pristine_scan: claim-check with (off,off) so a second GR channel is not considered foreign against the first adopter's ring_off=0. - svc_chan_vas_candidate_promote: register the channel's own parked COPY_SERVER_PDES candidate at the pump turn once its GPFIFO entry 0 content-validates, instead of waiting for the 1000 ms age-out. - pump: fall back to svc_channel_owner_vas when hVASpace==0 (driver 'attach to the TSG address space') so the GR client ring resolves. PAIR-SAFE (gsp_phys_booter.c): default sema_gl_pair_close_entry and sema_gl_sph_bind_pair_safe ON. An unclosed BEGIN/END pair made the replayed window raise ILLEGAL_METHOD_IN_BEGIN_END (Class Error 0x2018 EC 0x0d), the FE parked before the release semaphore, and draws timed out (backend_timeout). Diagnostics: CB-DIAG/CB-DIAG2 per-push fixed-CB capture summary. Verified: X direct-rendering green on attempt 1; work_gr backend_timeout=0 (was 6), backend_ok=5-7.
* vgsp: probe the low-aperture GR ring identity, skip GR holes, widen the ↵Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | pristine-FB scan The GL client's GR kernel ring lives in the RM low aperture (0x4000000..0xfffffff) and is not mapped by any published client VAS, so svc_lookup returns ring_pa=0 and the ring-gated USERD discovery never runs. - svc_pump_channels: for the 0xbeef0000 GR family, prove the ring content with a raw PA==VA read and adopt that identity translation (re-proven every pass so the churning ring VA re-resolves). - ce_fb_scan / svc_gr_ram_userd_scan: treat zero holes as not-a-window for the 0xbeef0000 GR family and accept entry VAs inside the SEMA VA window even outside the +-2 MB ring window. - svc_fb_userd_pristine_scan: raise the pristine-FB cap from 32 MiB to 512 MiB so the 32.5 MiB USERD candidate (0x207fc00) is scanned. These are defensive and do not by themselves dispatch the guest's real GL draws (the ring entry format and the missing default VAS are still open); see handoff CONT.393-CONT.395.
* vgsp: complete the X DDX's push-buffer notifications and class-aware display armArthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Four fixes, built and validated on fresh boots (r1675/r1677): - gsp_display_engine: gsp_disp_update_armed() is class-aware. NVC57D (core) carries the NOTIFY bit (12:12); NVC57E (window) has no NOTIFY bit, so a bound notifier ctxDMA is the arm. Every c57e window flip computed armed=0 before this, so FINISHED and the channel event were never authored and the DDX's composite/flip waits sat out their timeout. - gsp_sema_service: complete the bfef family's NvNotification status (0x8000 -> 0) in svc_client_slot_sweep(). The DDX marks the record IN_PROGRESS before a submit and the GPU (or RM) must write it back to 0; the emulation never did. - gsp_sema_service: sema_gl_hold_apply (default 0) applies a decoded GL release forward-only at svc_gl_flush() out: when the draw section is not captured, with a stale-value and 1 MB jump guard. - gsp_sema_service: extend the 0x8000 sweep to the X DDX's own RM channels (h=0x01xxxxxx). pb_armNotifiers() writes 0x8000 at notif+0xe and pb_wait() polls it back to 0; the bfef-only filter skipped these channels, so the 8 s submit wait expired ("WAIT (2, 8, 0x8000, ...)" then "Wait for channel idle timed out") even though the class2d NOTIFY ack had zeroed the same page before the arm. Evidence: r1675 keeps the X alive past the old 212 s crash point with 0 "Caught signal" lines; the DDX's 2D pipeline runs (get word advances), the host decodes live 3D method streams (VP-METHOD ... 0x1618 BEGIN topology) and the release sweep applies thousands.
* vgsp-sema: read a channel's push through the VAS it declaredArthur Hanson Rasmusson4 days
| | | | | | | | | | Several VA spaces can map the same GPU VA. The push read's learned/pin chain is global over VASes, so the GL client's CE channel 0xcaf00012 (which pushes at 0x120000000) was answered with a zero page from another VAS and every entry was 'unreadable' while the channel's own VAS mapped the real method stream. Try the channel's declared VAS first; fall back to the existing source chain when it has no published directory or the walk misses.
* vgsp-sema: keep the scrubber release alive while the event pump blocksArthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | The guest's PMA scrub wait and the host's status-queue pump can deadlock: the X server's scrub wait holds the guest RM lock the status consumer needs, the ring fills, and every critical event post then waits out its full 200 ms ring-full budget. A service pass can take many seconds, so the next pass's scrub step - the only thing that can release the scrub wait - is starved and the guest never makes progress. Run the scrub step from inside the send path's ring-full wait (service thread only), and re-resolve the scrubber's finish/host-sema words on every pass instead of once: the guest re-creates its RM kernel VAS and re-maps the channel buffer under the same GPU VA (observed: gpfifo VA 0x120064000 moved from PA 0x127e6a000 to 0x1122e9000), so a once-only resolution authored a page the guest no longer polled. Prefer the RM kernel VAS (h=0xc) RAM mapping over a client VAS vidmem mapping, and force re-resolution when a scrubber re-registers.
* vgsp-sema: resolve the scrubber's finish words through the GPU page tablesArthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | The guest PMA scrubber's host-side completion (channel buffer + pbSize + entries*8) was resolved through the learned VA->PA pair map first. When the guest reused the scrubber's GPU VA for a new channel buffer, that map still named the previous allocation's page, and the host authored the finish payload there while the guest polled the new page through its kernel VAS (h=0xc). r1667 live proof: walk_probe 0x12006c000 -> only VAS[1] (h=0xc) resolves to PA 0x10812a000 (the page the guest's vmalloc mapping of the channel buffer points at, and the value it polls); the pair map returned 0x10526a000. Writing the finish value to the correct page (via the guest scanner registration) immediately released Xorg from the RM memory-manager wait and the queued GSP status records drained. Changes: - svc_scrub_pass(): resolve hsem/fin through svc_walk_vaspaces() first, fall back to the pair map only when no VAS maps the VA. - Struct svc_scrub gains authored_gen; a new pa_gen (fresh scanner registration or a corrected derivation) forces one authoring pass even when the scrubber's PUT did not advance, so an already-waiting guest is released without a new submission.
* vgsp-sema: derive and register the guest scrubber finish-payload wordsArthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | The X DDX's NV_ESC_RM_VID_HEAP_CONTROL (ioctl 0x4a) allocates scrubbed pages through the guest PMA's CeUtils scrubber channel; it waits on the channel buffer's finish payload (channelWaitForFinishPayload), which the host's svc_scrub_pass was supposed to author but never did because the guest scanner had not registered fin_pa/hsem_pa (pa_ok=0 in every run). The channel buffer is pb + GPFIFO + sema + finish, and the scrubber's GPFIFO VA is pb + pbSize, so the host semaphore is gpfifo_va + entries*8 and the finish payload is that +4. Resolve that VA through the learned map or the VAS walk at the first pass and register the PAs in place (SYS aperture only). r1665: `scrub geometry hsem_va=0x12006c000 fin_va=0x12006c004 -> hsem_pa=0x10f46a000 fin_pa=0x10f46a004`, then `scrub author put=1..11` and the X server left the kernel scrub spin entirely: perf on Xorg is now 100 % in nvidia_drv.so+0xaee70 (a DDX userspace loop, next wall) with no _nv018351rm/_nv015102rm samples.
* vgsp-sema: capture the X DDX kick arm without a USERD and author its completionArthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | The X server's class2d kick channel (bfef0002) has a 2-entry ring at a page end (0x1203cfff0) and an FB userd offset the guest never writes; the pump's USERD-miss path returned before the entry-0 arm decode, so the class2d SET_NOTIFY target was never captured and every kick push had no address. Decode the ring head directly when the USERD is missing (the ring PA still resolves) and author the zeroed NvNotification at the captured target. r1664: the first bfef0002 instance still missed, but the re-registered one adopted its USERD on the PUT step (put 1 -> 2) at pa=0x10fecc000, decoded its pushes at 0x1203c0000 (len 32/64, have_rel=1), and the notify2d writes fire at va=0x12000d0b0. Xorg's spin moved off the control wait (_nv015102rm 66 % -> 0) and now sits in _nv018351rm (30 %); GZDoom still spins in glcore.
* vgsp-sema: discover direct-GL CE userd pages; complete kick slots; ↵Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | post-reboot diagnostics The direct-GL GL client's CE channels (beef0101/0102) declare a pool-relative FB control page (0x244f800 / 0x244f400 in r1656) while their GPFIFO ring is mapped in guest RAM, and their ring publishes from slot 2 (entry 0 stays zero). The entry-0 layout gate could never fire, the BAR0 fallback rejects offsets past its 16 MB shadow, and the GR-only VRAM shape scan never ran for them, so the channels retired with submissions=0 and the client's CE releases were never applied. r1661/r1663 evidence: enabling the VRAM shape scan for the beef CE family (hole-tolerant entry validation, newest-slot required, a GET bounded to one ring) finds the real control page (fb 0xa00000, put=1) and the CE push at 0x40e0000 decodes; beef0101 now retires submissions=1 with its semaphore releases applied. Also: - resolve the non-pool direct-GL semaphore window (0x4000000..0x4300000) through every published VAS translation (the general resolver can name a stale page while the client polls the beef0300 walk page); - author 0xffffffff in the beef channel's 128 kick-slot records (the glcore 570.144 kick wait polls exactly that payload; r1662 writes are visible in the guest page, but this is not yet the X-server wall); - one-shot nonzero-word dump of the beef0100 push (r1663 proved the GR init push's host semaphore is a true 32-bit VA 0x4238000 payload 1 with hi=0 in v1, so that release is correct); - name CE/GR in the VRAM-scan adoption line. Next wall (r1663): the X server spins in _nv015102rm/os_schedule (66 %) and _nv018351rm (30 %) after the GL client's GLX request; GZDoom blocks in _xcb_wait_for_reply. The display UPDATE completion event was posted and re-posted at 12:12:20, so this is the flip/GLX-sync path, not the lost UPDATE event.
* vgsp-sema: scope GR release deferral to the push's own candidate; fan ↵Arthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | direct-GL completions The GL client's direct-GL init push (beef0100, va=0x4000000) decoded its release (rel=0x4238000 pay=1) but never applied it: svc_fwd_defer_arm() is global over the cross-pass GR candidate ring, so stale unoffered CUDA/RC candidates made any later push "defer" its release. The record was then wiped by the next decode pass (the r824 failure mode) - no sema-sw, pending or deferred line, and the client's fence never advanced. Apply the r824 rule already used by the C56F site to the SET_REPORT_SEMAPHORE and LAUNCH_DMA sites: defer only when the candidate ring entry belongs to this push (push_va match). A release whose push owns no candidate applies inline. Also queue svc_rel_apply_906f() releases on a translation miss instead of dropping them, add a bounded low-VA sema-sw provenance window, and fan direct-GL semaphore completions (0x4000000..0x4300000) through every published VAS translation (the general resolver can name a stale page while the client polls the beef0300 walk page). Evidence: backups/evidence-20261002-victory/r1656 (beef0100 release decoded, never applied) and r1657 (sema-sw va=0x4238000 rb_ok=1 after the fix).
* vgsp-sema: carry/decode the class2d kick notification targetArthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | | The GL client arms its class2d kick channel with SET_NOTIFY_A/B + NOTIFY in the first GPFIFO entry, then submits short kick pushes (NOTIFY only) that rely on the target staying programmed in the channel context. Two host gaps left the short NOTIFY with no address, so no completion was authored and the client spun in its kick/fence wait: - a same-handle channel re-registration memset() erased notify2d_va even though the guest kept using the target from the previous incarnation; - the pump's walk seed consumes only the newest entries ending at the live PUT, so entry 0 (the arm) could be skipped forever. Preserve notify2d_va across a same-vgpu, same-handle, same-session re-registration; fall back to it in the GL kick executor when the section did not re-arm; decode the skipped head entries (bounded, up to 8) on discovery and from the pump when the kick-family channel still has no target; and name a NOTIFY that arrives with no target instead of dropping it silently. Evidence: backups/evidence-20261002-victory/r1652..r1655 (kick channel 0xbfef0002, short NOTIFY without SET_NOTIFY, walk seed last_get skipping entry 0). Not yet observed clearing the GL client's glcore spin.
* vgsp: retry deferred display completions; escalate the UVM init-slot releaseArthur Hanson Rasmusson4 days
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Two live walls from the r1649/r1650 windowed-GZDoom runs: 1. Display completion wake-up. All NV01_EVENT registrations carry hSrcResource=0, so gsp_rm_post_channel_event() always takes the shotgun fallback, which skips events posted within the 250 ms hint dedup. When the display UPDATE is the channel's last push, the pump's retry was gated on new work (put != consumed) and never ran, so the X server's flip wait spun in _nv018351rm/os_schedule forever. Add gsp_rm_post_channel_event_force() (bypasses only the hint dedup; the event burst cap and status-ring free-space discipline still apply), a per-channel event_retry_at, and an idle-pass retry every 250 ms that logs "re-posted after deferral". Also move event_burst_at after the cap check so refused retries cannot keep the window fresh. 2. UVM channel init slot. r1651 gdb proved the channel's tracker entry waits for value 2 while the authored pool word reads 1; a manual write of 2 cleared uvm_push_end_and_wait. The channel's control-entry + init pushes are boot-time configuration, so keep the rank slot moving for 10 s after first submission: one attempt per 250 ms per rank, escalating 1->2->3->4 through every published VAS translation. Values beyond that need the real CE push decode. Evidence: backups/evidence-20261002-victory/r1649/ (X spin perf, event journal), r1650/ (re-post lines), r1651/ (tracker entry value=2, manual write clears the spin).