diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-07 13:19:09 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-07 13:19:09 -0500 |
| commit | 54ef117d77b2274a51b60524890078846f2823f6 (patch) | |
| tree | 4b8956147a4a5b2c0bd949537f3341acec1d5614 | |
| parent | 6b3601cc153cbad8ca73fe771b9786e423b4b6a2 (diff) | |
| download | open-iov-54ef117d77b2274a51b60524890078846f2823f6.tar.gz open-iov-54ef117d77b2274a51b60524890078846f2823f6.zip | |
vgsp-sema: ack the class-2d IMMD NOTIFY from the X DDX sync
The X server's nvFermiSync queues the class-2d completion as
IMMD_DATA methods (SET_NOTIFY_A/B + NOTIFY 0x10c WRITE_ONLY). The
run-shaped watchdog form was already handled; the IMMD form fell
into the default case, so the zeroed NvNotification was never
authored and the server spun in WAIT (0,8,0x8000,...) with the
status left IN_PROGRESS. Handle the IMMD form and treat the 0x8000
IN_PROGRESS status as armed in the keepalive scan. The mode-set
then completes and the 2D sync acks (verified on the emulated
vGPU: no WAIT, sema-notify2d zeroed). The A/B knob
sema_2d_notify_immd=0 restores the old dropped-NOTIFY behaviour.
| -rw-r--r-- | kernel/gsp_sema_service.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index e42e23d..6f0103b 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -18233,6 +18233,13 @@ static void svc_push_raw_dump(const u8 *buf, u32 len, u64 push_va, static u64 svc_notify2d_done; static u32 svc_notify2d_log; +/* + * r1608 A/B: the X DDX's IMMD class-2d NOTIFY ack (the nvFermiSync + * completion). Enabled by default; set 0 to reproduce the pre-r1608 + * dropped-NOTIFY behaviour (the Xorg mode-set WAIT) without a rebuild. + */ +static bool gsp_sema_2d_notify_immd = true; +module_param_named(sema_2d_notify_immd, gsp_sema_2d_notify_immd, bool, 0644); static bool svc_notify2d_write(struct nv_vgpu_device *vgpu, struct svc_channel *ch, bool completion) @@ -18509,6 +18516,29 @@ static void svc_twod_method(struct nv_vgpu_device *vgpu, case 0x2ac: tw->operation = v; break; + /* + * r1608: the X DDX's nvFermiSync (nvFermiXAASync) queues the + * class-2d completion as IMMD_DATA methods: SET_NOTIFY_A/B name + * the NvNotification VA and NOTIFY (0x10c, payload 0 = + * WRITE_ONLY) must author the zeroed 16-byte notification. The + * watchdog path below has handled the run-shaped form since r828; + * the IMMD form previously fell into the default case and was + * dropped, so the X server's post-selection 2D sync spun in + * "NVIDIA(GPU-0): WAIT (0, 8, 0x8000, ...)" forever (the status + * word stayed IN_PROGRESS 0x8000). The mode-set never completed, + * glsStartServer/glsDeviceHandle never ran, and the GL client's + * physical-device init (class/gpuGartSize/+0x18e0) stayed empty. + */ + case SVC_2D_SET_NOTIFY_A: + ch->notify2d_va = (u64)(v & 0x1ffffff) << 32; + break; + case SVC_2D_SET_NOTIFY_B: + ch->notify2d_va |= (u64)v; + break; + case SVC_2D_NOTIFY: + if (v == 0 && gsp_sema_2d_notify_immd) + svc_notify2d_write(vgpu, ch, true); + break; case 0x2a0: tw->rop = v; break; @@ -18622,7 +18652,13 @@ static void svc_notify2d_keepalive(struct nv_vgpu_device *vgpu, u16 st; memcpy(&st, slots + slot * 16 + 14, 2); - if (st != 0xffff) + /* + * r1608: the 2D completion notifier is armed with + * NV9097_NOTIFICATION_STATUS_IN_PROGRESS (0x8000) while the + * GPU works on it (the X DDX's nvFermiSync waits for it to + * become 0); the older watchdog slots use 0xffff. Ack both. + */ + if (st != 0xffff && !(st & 0x8000)) continue; /* not armed - nothing to ack */ if (svc_write_ap(vgpu, ch->notifier_pa + slot * 16, ch->notifier_as, zero, sizeof(zero))) |
