| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
| |
capture); push/verify fixes
mission-gz.sh runs the end-to-end guest pass in one shot (X bring-up with
ScreenInit retries, GPU GL probe via gl_frames, GZDoom offscreen + gz_pbuf +
sdl_cap under the tested wrapper, /tmp/mission-done result flag).
push_gl_tools.sh runs vgpu_vm.py under sudo (QGA needs root);
gl_verify.sh uses 'pkill -x Xorg' (the -f pattern self-matches the shell
when the command line contains the Xorg invocation).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
direct-GL stream frontier
Refresh STATE-CURRENT.md and the open-iov.org wiki pages with the 2026-11-12
state: stock-driver X + GLX green (glxinfo 4.6.0 direct rendering, glxgears
~520 FPS), the pbuffer frame path captured 500/500 non-black frames (50 s
640x480 h264) plus the earlier 45.4 s capture, and the named frontier
(direct-GL client command-stream delivery: setup push unreadable, CE ring
0xbeef0101 intermittent) alongside the guest-init/sizing fixes (RMInstLoc
modprobe single-source, FB info in KB, 256 MiB GART).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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/.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
- cycle-r1780.sh: load vfio modules one per modprobe (the multi-module
form was silently treating the extra names as parameters and never
loading mdev); auto-detect the vgpu mdev type and prefer the 2 GiB
type used by the campaign.
- sdl_cap.c: gate capture-file creation to processes that can actually
read GL pixels (a child was truncating the capture), and log the
capture pid/pointers.
- gz_pbuf.c: LD_PRELOAD shim that gives an SDL2 GL client a GLX pbuffer
context on the guest's NVIDIA X server (the proven gl_frames path),
with SDL_GL_GetDrawableSize/SwapWindow interception.
|
| | |
|
| |
|
|
| |
cycle tooling
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Record the three independent guest-visible values that broke stock-driver
bring-up: FB info kilobyte-vs-byte units (1024x framebuffer over-report),
multi-GiB GPU GART allocation, and odd shared nvClip modeNum (clears the GL
client's init bits so buffer maps fail). Each has a different diagnostic
signature; the note separates allocation-size, userspace mapping-gate, and
host VAS-translation failures.
Evidence: c15-c26 bring-up, commits 8c7bf295/d1dc85a2/91aa8d91 and
handoff-meta-plan.md CONT.435-CONT.441.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
| |
pdb_scan_gmmu walks the GP10X/VER2 GMMU page-table format (PD3/PD2/PD1/
PD0/PT, 16-byte dual PD0 entries, sys/vidmem apertures) and pdb_scan is
the x86-64 index cross-check. Both map the QEMU pc.ram file correctly
for the 2 GiB low + high-RAM q35 layout and are strictly read-only.
Used to prove the ring page/VA and pdb chains in CONT.435/436.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
BUS_GET_INFO_V2 GPU_GART_SIZE at 4096 MiB made the guest RM allocate a
4 GiB system-memory GART object during X/GL init. That single allocation
is the 1048576-page nv_alloc_pages spike that OOM-killed or crashed the
12 GiB guest in c15-c22; with the 4 GiB FB-info over-report fixed and
UseSysmemPixmapAccel off, the GART was the remaining source.
c23 with bus_gart_mb=256 and the guest X config UseSysmemPixmapAccel=false:
X starts, MemFree stays 11 GB, no 1M-page allocation, and glxgears renders
2601 frames in 5 s (520 FPS) on the emulated vGPU. The default should not
reintroduce the fatal allocation; 0 remains available for the historical
A/B.
Evidence: handoff-meta-plan.md CONT.436, c23 X/gzdoom/glxgears logs.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The FB info ABI documents RAM_SIZE/TOTAL_RAM_SIZE/USABLE_RAM_SIZE/HEAP_SIZE/
MAPPABLE_HEAP_SIZE/HEAP_FREE/BAR1_SIZE/BAR1_AVAIL_SIZE in kilobytes; the
emulation returned bytes, over-reporting the emulated framebuffer by 1024x
to the X DDX. COMPRESSION_SIZE and L2CACHE_SIZE remain in bytes.
KGR_GET_CONTEXT_BUFFERS_INFO reported NV_U32_MAX for buffer kinds Turing
does not support. kgraphics treats size==0 as unsupported (skip); an
NV_U32_MAX byte length rounds up to exactly 4 GiB in the page-count
computation, which is the shape of the transient guest sysmem allocations.
Report 0/0 instead.
Evidence: handoff-meta-plan.md CONT.435 (c15-c21 allocation traces, the
guest nvidia.ko disassembly of osAllocPagesInternal), kernel 570.144
ctrl2080fb.h units and kernel_graphics.c:1775-1800.
|
| |
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- 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.
|
| |
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
- 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
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
- 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).
|
| | |
|
| |
|
|
| |
direct-GL GR ring resolves; CE-ring/window walls (STATE-CURRENT too)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- 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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- 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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
| |
direct-GL/window walls
Refresh STATE-CURRENT, the Main Page and the status/frontier pages: the DDX
3D replay executes and a guest pbuffer glClear+glReadPixels returns a red
pixel (ff0000ff); the RM write-lock holder (Xorg in the DDX scrub wait) is
fixed in df6e71bb. The direct-GL client channel still emits only setup/notify
kicks (ops_runs=0), a window draw wedges X, and X startup/RM stability plus
the DDX 4 GB sysmem allocation remain. Published to open-iov.org.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
beef-ring/CB/RT walls
Refresh STATE-CURRENT, the Main Page and the status/frontier pages:
ebf3130f fixes the X DMA-init path and flips the GR pair-close/pair-safe
replay fixes default ON (X green on attempt 1 in three consecutive cycles,
backend_timeout=0, draws retire in 3-2400 ms); bb802909 is committed. The
replayed draw still writes 0 pages; the beef GR ring resolution, the
fixed-CB image's zero 0x80 MVP block and the render-target bind are the
named walls. Published to open-iov.org.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
- 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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
| |
Refresh STATE-CURRENT, the Main Page and the status/frontier pages: the GSP
event-IRQ fix completes swaps; the 2D path is green end-to-end; the guest's
real GL draws now forward and execute on the physical GPU (work_gr
backend_ok=9); the draw writes 0 pages because its constant-buffer (MVP)
page is unresolved and forced to the seed page; the MME front-end defer, GR
stale-wedge and the X DDX get-word/notifier completion remain. Published to
open-iov.org.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
wakes poll() waiters
The emulated GSP only signalled the MSI-X eventfd when it queued a status
record. The guest's primary ISR (nvidia_isr) decides pending from the
CPU_INTR leaf registers, which we never set for the GSP stall vector, so it
returned IRQ_NONE: IRQ 33 counted thousands of interrupts while the nvidia
event thread sat idle and a client blocked in poll() on /dev/nvidia0 (a GLX
swap) waited forever even though the event was already in the status queue.
Mirror what a real GSP-RM does when it queues an event:
- program RISC-V IRQMASK/IRQDEST for SWGEN0 (read-only to the guest; the
GSP firmware owns them),
- set SWGEN0 in the falcon IRQSTAT,
- latch GSP stall vector 155 in the CPU interrupt tree (LEAF[4] bit 27,
UVM_SHARED subtree 2 -> TOP[0] bit 2),
- signal MSI-X.
Raise it only for POST_EVENT records (replies are polled by the client).
Verified on r1680: the guest now writes IRQSCLR SWGEN0, kgspService_TU102
drains events, and glxgears renders (was a hard hang).
|
| |
|
|
|
|
|
|
|
|
|
|
| |
waits on kernel kick completion
Refresh STATE-CURRENT, the Main Page and the status/frontier pages: with
SDL_VIDEO_X11_FORCE_EGL=0 the windowed GL path selects libnvidia-glcore,
but the minimal glxgears hangs in the glcore kick wait (poll on the
per-slot /dev/nvidia-modeset fd) while the host completes the beef
notifier memory. The X DDX get-word/notifier completion, the DDX 4 GB
sysmem footprint and physical dispatch of the GL draws remain. Published
to open-iov.org.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
on llvmpipe
Refresh Project Status, Graphics Execution, OpenGL, Execution Frontier,
Execution Plane, Physical GPU Backend, Host Module, System Overview,
Project Goals, Project Plan and the FAQ, plus STATE-CURRENT and the Main
Page: the X DDX waits (class-aware display arm, 0x8000->0 notification
completion, decoded GL release) are fixed; GZDoom reaches MAP01 on Mesa
llvmpipe; the NVIDIA renderer path, the DDX get-word/notifier completion,
the DDX 4 GB sysmem footprint and physical dispatch of the GL draws are
the pixel walls. Published to open-iov.org.
|
| |
|
|
|
|
|
|
|
| |
Bring Project-Status, OpenGL, Graphics-Execution, Execution-Frontier,
Execution-Plane, Physical-GPU-Backend, Host-Module, System-Overview,
Project-Goals, Project-Plan and the FAQ in line with the current state:
display/KMS on the emulated vGPU is live, glxinfo reports OpenGL 4.6.0
with direct rendering, and the remaining graphics gate is the X GLX
context-creation completion plus the client kick-slot word.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The UPDATE path posted the channel completion event on every UPDATE,
including armed=0 updates where no notifier was written (r1665 journal:
armed=0 `-> none` still posts). Those events drive the DDX's NVKMS
FLIP_OCCURRED handler (nvidia_drv.so 0xaee70), which reaps the four
notifier slots of every layer and has a fixed-point retry when the
completed layer does not match the first DPY object's layer; with
non-flip updates raising the event, Xorg spun there at 100 %.
Gate the post on `wrote` (armed + notifier written + FINISHED). r1666:
the 0xaee70 spin is gone from perf; Xorg moved on to a bounded XAA
action-list scan (nvidia_drv.so 0x4dc9c0, nvXAAHandleActionList) plus
do_vfs_ioctl/schedule, i.e. the server main loop is no longer wedged in
the flip reaper.
|
| | |
|