diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-27 06:36:00 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-27 06:36:00 -0400 |
| commit | 8898bd00b7c2e6385ceb7238f29d3672308b949a (patch) | |
| tree | 79dc6fa714d22749134dcd8073a18f1585ae9ebb /kernel/gsp_rm_emulation.c | |
| parent | fffae7b19383373a95032645c583ccf76add23df (diff) | |
| download | open-iov-8898bd00b7c2e6385ceb7238f29d3672308b949a.tar.gz open-iov-8898bd00b7c2e6385ceb7238f29d3672308b949a.zip | |
vgsp: service the guest RC watchdog channel (Volta GPFIFO class + class2d notifier ack)
The guest kernel's krcWatchdog posts a notifier cycle on its own channel
(object 0x31415900) every second and declares 'GPU is probably locked'
when the zeroed notification never comes back within 7 s. Observed as
the sustained-GL-load wedge: once a GL client (GZDOOM) enabled robust
channels the errors started and Xorg eventually stalled on screen
readback.
- rm: register the Volta GPFIFO class 0xc36f (plus the later
generations) as a channel class. The watchdog's channel allocates
0xc36f on this device - the driver picks the first class the gpu
reports supported - and without it the channel never reached the
progress service. It now registers and latches (put visible, entries
walked).
- sema: decode the class2d notifier cycle on subchannel 3
(SET_NOTIFY_A/B name the notifier VA, NOTIFY WRITE_ONLY writes the
zeroed NvNotification) and author the write, like svc_notify_complete
does for the work-submit token. Proven live: 'sema-notify2d: va=...
zeroed (RC watchdog acked)'.
- sema: also ack on every pass that sees the channel's put != get, so
the ack does not depend on the ring reads (its VA is known from the
first decode); idempotent.
- sema: never consume a zero-length/zero-VA GPFIFO entry as empty work.
Two bogus zero entries consumed through a mis-resolved ring page
pushed the watchdog userd's GPGet past the driver's own GPPut and
every later userd probe then read get>put, permanently rejecting the
channel's real userd. Hold such entries (bounded, per-channel
counter persists through the pass snapshot).
- sema: a registered userd value that is a real guest PA (the
watchdog's own block) outranks the ring+0x2000 convention guess the
ring auto-pin applies for the CUDA GR layout.
- rm: log channel-class allocs whose params are too short for
registration instead of skipping silently.
Remaining (next): under heavy GL traffic the watchdog ring's
translation can go stale for stretches (content-scanned map answering
where a pin used to), which starves the ack; pin the push/notifier
pages when the first real decode delivers them. The frame capture
(xshm_pub -> XShmGetImage) still stalls while that starvation is
active.
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index d6412c3..fc08b9d 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -3052,8 +3052,21 @@ static bool gsp_rm_is_channel_class(u32 class_id) case 0x906f: /* MAXWELL_CHANNEL_GPFIFO_A */ case 0xa06f: /* KEPLER_CHANNEL_GPFIFO_A */ case 0xb06f: /* PASCAL_CHANNEL_GPFIFO_A */ - case 0xc06f: /* VOLTA_CHANNEL_GPFIFO_A */ + case 0xc06f: /* VOLTA_CHANNEL_GPFIFO_A (PRE-TURING NAME) */ + case 0xc36f: /* VOLTA_CHANNEL_GPFIFO_A */ + /* + * r828: the RC watchdog's channel allocates 0xc36f on this + * device (the driver's gpfifoMapping loop picks the first + * class the gpu reports supported) - without it in this set + * the channel never reaches the progress service, its class2d + * notifier cycle (SET_NOTIFY_A/B + NOTIFY) never executes and + * the guest's krcWatchdog declares the GPU locked after its + * 7 s timeout as soon as robust channels are in play. + */ case 0xc46f: /* TURING_CHANNEL_GPFIFO_A */ + case 0xc56f: /* AMPERE_CHANNEL_GPFIFO_A */ + case 0xc86f: /* HOPPER_CHANNEL_GPFIFO_A */ + case 0xc96f: /* BLACKWELL_CHANNEL_GPFIFO_A */ return true; default: return false; @@ -3075,8 +3088,18 @@ static void gsp_rm_register_channel(struct gsp_emu_context *ctx, u32 h_object, { struct sema_channel_desc desc; - if (params_size < GSPRM_CHAN_NOTIFIER_MEM + 8) + if (params_size < GSPRM_CHAN_NOTIFIER_MEM + 8) { + /* + * r828 diag: a channel-class alloc whose params are shorter + * than the notifier field is not registered, silently. The + * RC watchdog channel (hObject 0x31415900) never appeared in + * the sema table; name every such skip with its size so the + * shape question is answered by a log, not inference. + */ + pr_info("vgsp-rm: channel alloc hObject=0x%x params_size=%u too short (< %u); NOT registered\n", + h_object, params_size, GSPRM_CHAN_NOTIFIER_MEM + 8); return; + } memset(&desc, 0, sizeof(desc)); desc.vgpu = ctx->vgpu; |
