summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_rm_emulation.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-27 06:36:00 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-27 06:36:00 -0400
commit8898bd00b7c2e6385ceb7238f29d3672308b949a (patch)
tree79dc6fa714d22749134dcd8073a18f1585ae9ebb /kernel/gsp_rm_emulation.c
parentfffae7b19383373a95032645c583ccf76add23df (diff)
downloadopen-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.c27
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;