summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_display_engine.c
Commit message (Collapse)AuthorAge
* vgsp: retry deferred display completions; escalate the UVM init-slot releaseArthur Hanson Rasmusson105 min.
| | | | | | | | | | | | | | | | | | | | | | | | | | | | 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).
* vgsp-disp: map class 0xc57b to its real control window (window-imm)Arthur Hanson Rasmusson16 hours
| | | | | | | | | | | | | The header labelled 0xc57b CURSOR and mapped it to the cursor-PIO block at 0x6d8000+n*0x1000, but 0xc57b is the immediate-mode window class whose control window is 0x690000+(n+32)*0x1000 = 0x6d0000+n*0x1000 (0xc57a is the PIO cursor channel, valid=0). The engine therefore polled the wrong window for every 0xc57b channel: their PUT was never seen, no UPDATE ever completed, and r1638's GZDoom-triggered mode set left X spinning in an RM ioctl after the window-imm flip. Rename the constants (WINDOW_IMM 0xc57b, CURSOR_PIO 0xc57a) and return the correct control offsets; cursor-PIO keeps 0x6d8000+n*0x1000.
* vgsp-disp: retry a lost UPDATE completion event from the pumpArthur Hanson Rasmusson17 hours
| | | | | | | | | r1636: the X-start mode set wrote FINISHED but the channel completion event was refused (event burst cap / transient status-queue state) and never retried, so NVKMS waited forever and X wedged in os_acquire_rwlock_write. Mark the channel event_pending on a failed post, retry it every pump pass (outside disp.lock), clear on success, and log the failure/recovery plus hObj in the UPDATE line.
* vgsp-disp: scan the BAR3 shadow for the display instance tableArthur Hanson Rasmusson17 hours
| | | | | | | | | r1635 live proof: the 32 MiB RM BAR2 aperture is the 64-bit PCI BAR2/3 pair and is enumerated as resource BAR3 (BAR2 empty), so the instance block lives in bars[3] (block base +0x3000 in the shadow; 0x10013 target=2 base=0x114103000, 0x10075 target=3 base=0x114138000). Scan bars[2] and bars[3] in the resolver and log the bar index; the BAR2-only scan found nothing (0 resolutions).
* vgsp-disp: resolve the display instance table in the guest BAR2 shadowArthur Hanson Rasmusson17 hours
| | | | | | | | | | | | | | | | | | The guest kernel RM builds the 64 KiB display instance block in FB but writes it through the guest's BAR2 virtual aperture (memdescMapInternal -> BAR2 with RMCFG_FEATURE_PLATFORM_GSP=0), while control 0x20800a49 hands only the FB PA to the display engine. The hash table therefore never appears in the FB shadow or guest RAM, which is why the notifier context-DMA handles 0x10013/0x10075 could not be resolved and FINISHED was never written (r1633). - add a BAR2-shadow hash/object-entry search (8-byte entry walk, 4 KiB block-base candidates, target/limit validation) to the resolution chain after FB/shadow/RAM; - fix the hash instance field mask to 11 bits (0x7ff); - carry the object target and route the notifier status through the FB shadow for target 1, guest PA for sysmem targets 2/3; - SET_NOTIFIER_CONTROL.OFFSET is in 16-byte units (was scaled by 4).
* vgsp-disp: find the instance block by the ctxDMA handle anywhereArthur Hanson Rasmusson27 hours
| | | | | | | | | | | | | | | The guest BAR1 is a 256 MB window over a 512 MB FB, so the RM writes vidmem through a shifted BAR1 block and the announced instance PA does not index the shadow (r1632: hash_nz=0 at 0x1fff0000; scan also empty where it looked). Resolve like the hardware does, but empirically: parse the announced block; if the handle is not there, search the FB shadow (then guest RAM for the coherent-mapping case) for the 64 KB block that contains an entry for the ctxDMA handle and _parses_ into a valid object entry; use that block's object entry for PA/limit. Cheap for the 56-per-boot notifier writes: a failed handle is not rescanned for 5 s.
* vgsp-disp: retry the instance block through guest RAM when the shadow copy ↵Arthur Hanson Rasmusson28 hours
| | | | | | | | | is empty The RM's vidmem writes may use the coherent CPU mapping rather than the BAR1 aperture, in which case the display instance block lands at the announced address in guest RAM. Log the source used (src=fb|ram) and fall back to vfio_dma_rw before reporting the hash table empty.
* vgsp-disp: never publish GET past PUT; bounded no-parse push dumpArthur Hanson Rasmusson28 hours
| | | | | | | | | | | | | | | r1630: the window channel's first push read returned unparseable bytes (0 methods) and the parser walked off the 4 KB ring, publishing GET=0x1000 while PUT stayed 0x4e4. nvidia-modeset then wedged in 'Error while waiting for GPU progress', Xorg never started and glxinfo/ GZDoom never reached the GL path. Only consume a segment that parses exactly to the driver's PUT. On a short/invalid read, leave consumed unchanged: the pump retries next pass (which also covers a ring the guest kicked before its content is visible) and GET can never move past PUT. Dump the head of an unparseable segment (bounded, disp_dbg) to name what the ring holds. Reset dump budgets per mdev cleanup so each boot keeps its diagnostics.
* vgsp-disp: locate where the instance hash table actually landsArthur Hanson Rasmusson29 hours
| | | | | | | | The 0x20800a49 announce says vidmem PA 0x1fff0000 but that block reads zero in the function RAM shadow. Bound a one-shot whole-shadow scan for hash-entry-shaped words (word1 = {chn[31:25], instance[24:14], client[13:0]}) and log BAR1_BLOCK (BAR0 0x1704) so the BAR1 aperture shift, if any, becomes visible.
* vgsp-disp: resolve the notifier via the announced display instance memoryArthur Hanson Rasmusson29 hours
| | | | | | | | | | | | The guest announces the display instance-memory block (8 KB context-DMA hash table + entries, vidmem PA 0x1fff0000 on r1627) via NV2080_CTRL_CMD_INTERNAL_DISPLAY_WRITE_INST_MEM (0x20800a49), but the engine ignored it and scanned its FB shadow blindly, never finding the hash entry - so SET_NOTIFIER_DMA handle 0x10013 resolved to pa=0 and UPDATE never wrote FINISHED (r1627: UPDATE armed=1 notifier=0x0/0). Handle 0xa49, record pa/size/address space per guest, read the block through the FB shadow (or guest RAM for sysmem), and parse the hash table from the announced location with bounded diagnostics.
* vgsp-disp: byte method addresses in the push parser (x4)Arthur Hanson Rasmusson29 hours
| | | | | | | | | The NV DMA METHOD_OFFSET field is a dword index; gsp_disp_method() compares against byte offsets (UPDATE 0x200, notifier 0x208/0x20c). The executor compared the raw index (0x82) against 0x200/0x208, so UPDATE and SET_NOTIFIER could never match and the FINISHED write never fired (exposed by the r1625 raw push dumps). Shift the decoded offset to bytes.
* vgsp-disp: bounded raw push dumps; 14-bit method offset decodeArthur Hanson Rasmusson30 hours
| | | | | | | | | | disp_dbg now dumps the head and tail of the first four executed push segments - the tail is where the core update completion lives (UPDATE 0x200 / SET_NOTIFIER 0x208/0x20c), and r1624's 16-byte second push carried neither parseable method. The NV DMA method offset field is 15:2 (14 bits), not 13:2; widen the parse mask so higher display method addresses are not truncated.
* vgsp-disp: fix disp.lock self-deadlock; backfill h_object from the allocArthur Hanson Rasmusson36 hours
| | | | | | | | | | | | | gsp_disp_engine_channel_add() took disp.lock and then called the self-locking gsp_disp_find_object(), deadlocking the RPC thread on the first display push-buffer control (r1621c: watchdog hard lockups in gsp_emu_0 channel_add+0x13b and gsp-sema-svc pump+0x88, R13=0xc57d). Use a caller-holds-lock helper instead. The push-buffer control arrives before the alloc (control, registration, alloc), so a channel registered from the control had h_object=0 and the completion-event post stayed inert. Backfill h_object when the alloc note lands for a registered channel.
* vgsp-disp: unconditional pushbuffer receipt log + NvBool valid fixArthur Hanson Rasmusson36 hours
| | | | | | | | | | | | | Log every NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER (0x20800a58) receipt with the decoded 56-byte params struct, and always log rejected channel registrations and SET_NOTIFIER_DMA - boot-only volume, settles whether the kernel RM ever programs the display push buffers through that control (r1621 follow-up). valid is an NvBool (1 byte); the previous u32 load could read the padding bytes and turn a PIO-channel valid=0 into a false positive. Raise the engine log budget to 4096.
* vgsp-disp: host-side EVO display engine (channels, push buffer, notifier, ↵Arthur Hanson Rasmusson40 hours
raster) The guest nvidia-modeset drives the display through per-channel NV-DMA push buffers kicked via the BAR0 UDISP control windows. Emulate that engine contract host-side, unmodified guest: - channel registration: display-channel RM objects (core 0xc57d, window 0xc57e, cursor 0xc57b, 0xc57a) are noted from the alloc stream, and the internal control NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER (0x20800a58) records each push buffer (guest PA, size, class, instance, validity); - PUT polling + GET publication in the channel control pages (core 0x680000, window 0x690000+n*0x1000, cursor 0x6D8000+n*0x1000); - NV-DMA method parser (METHOD/ONE_INC/NONINC/JUMP/SET_SUBDEVICE_MASK) with the wrap-JUMP follow; - completion: SET_CONTEXT_DMA_NOTIFIER / SET_NOTIFIER_CONTROL tracking, exact notifier-surface resolution through the display instance hash table (no heuristic writes), NV_DISP_NOTIFIER FINISHED on UPDATE (0x200), and the channel completion event post; - free-running 1080p60 raster line for NVC57E_GET_LINE. All effects are behind independent knobs (disp_engine, disp_finish, disp_vblank, disp_events, disp_notifier_pa) with verbose diagnostics (disp_dbg, disp_dump), so the previous behaviour stays one load away.