diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-29 14:41:14 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-29 14:41:14 -0400 |
| commit | a83a42df71c235c5f9f8eaeb3b62053a75fe30c7 (patch) | |
| tree | abeb5c7676a100050e28ca7c8a95c1bce33dbf92 /kernel | |
| parent | ca944b45ba35f3c0dc63fa9f722067af13e97ab4 (diff) | |
| download | open-iov-a83a42df71c235c5f9f8eaeb3b62053a75fe30c7.tar.gz open-iov-a83a42df71c235c5f9f8eaeb3b62053a75fe30c7.zip | |
kernel: grace window for untranslatable GR entries; tools: coalesce window pin output
The first GR window pin landed ~2 s after the pump consumed the freshly
created channels' GPFIFO entries on the first failed read, so the pushes
(and the tracking-semaphore releases they carry) were lost. GR entries with
an unresolvable push page now stay pending for sema_gr_grace_ms (default
8 s) before the stale-entry consume; a pin landing in that window makes the
entry readable and it executes normally. The completion counter is still
published from put at the end of every pass, so the client's counter wait
is not delayed.
guest_pmap_win.py coalesces contiguous VA+PA pages into run lines, so a
15k-page window transfers as ~200 lines instead of ~15k and the pin batch
lands within a second of the pages appearing.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 53 | ||||
| -rw-r--r-- | kernel/gsp_sema_service.h | 8 | ||||
| -rw-r--r-- | kernel/main.c | 7 |
3 files changed, 60 insertions, 8 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 1296f81..ce2e0c9 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -143,6 +143,10 @@ struct svc_channel { u32 logged_expected; /* last pool value logged (rate limit) */ unsigned long rescue_last; /* rate limit for the full-RAM rescue scan */ u32 rescue_fail; /* consecutive failed rescues for the entry */ + unsigned long defer_since; /* first failure of the pending GR entry + * (0 = none): the entry is left pending + * for the GR grace window so a late + * window pin can still make it readable */ u64 counter_pa; /* guest PA of the u32 GPU completion counter * (registered via the sema_counter debug param); * 0 = not registered */ @@ -3255,6 +3259,14 @@ static int svc_chan_entry0(struct nv_vgpu_device *vgpu, struct svc_channel *ch, #define SVC_GR_USERD_OFF 0x2000ULL bool gsp_sema_gr_rings = true; +/* + * GR (compute) entries whose push page is not translatable are left pending + * for this long before the pump consumes them as stale. The push pages are + * mapped and pinned by a host watcher from guest truth a moment after the + * channels appear; without the grace the first entries are consumed before + * the pin lands and the releases they carry are lost. + */ +unsigned gsp_sema_gr_grace_ms = 8000; /* * CE release fallback: when a push carrying a tracking-semaphore release @@ -4029,7 +4041,12 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) kfree(pb); break; } else if (++ch->rescue_fail >= - (ch->engine_type ? 2 : 1)) { + (ch->engine_type ? 2 : 1) && + (ch->engine_type || + (ch->defer_since && + time_after(jiffies, + ch->defer_since + + msecs_to_jiffies(gsp_sema_gr_grace_ms))))) { /* * The slot no longer holds this * push (overwritten buffer): the @@ -4045,18 +4062,20 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) * cannot validate - and their * completion signal is the * per-channel counter we publish - * from `put`. Consume on the - * first failed attempt: a slow - * skip delays GPGet and the - * counter long enough for the - * client's submission wait to - * expire (observed at ~12 s with - * the 3-attempt path). + * from `put`. The entry is left + * pending for a grace window + * first: the push pages are + * pinned from guest truth a + * moment after the channels + * appear, and only a readable + * push carries the releases the + * client waits on. */ pr_info("sema-chan: skipping stale entry h=0x%x va=0x%llx len=%u after %u failed rescues\n", ch->h_object, va, len, ch->rescue_fail); ch->rescue_fail = 0; + ch->defer_since = 0; if (gsp_sema_fake_rel) svc_fake_release(vgpu, ch); @@ -4071,6 +4090,21 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) kfree(pb); continue; } else { + /* + * First failure (CE) or + * inside the GR grace window: + * leave the entry pending so + * a translation that lands + * shortly still gets the push + * executed. The completion + * counter is published from + * `put` at the end of the pass + * either way. + */ + if (!ch->engine_type && + !ch->defer_since) + ch->defer_since = + jiffies; svc.gpfifo_nomap++; kfree(pb); break; @@ -4081,6 +4115,8 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) } ch->last_get = (idx + 1) % ch->gpfifo_entries; + ch->rescue_fail = 0; + ch->defer_since = 0; /* Publish progress the way the GPU would. */ g = ch->last_get; @@ -4118,6 +4154,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) svc.chan[k].last_rel_va = ch->last_rel_va; svc.chan[k].rescue_last = ch->rescue_last; svc.chan[k].rescue_fail = ch->rescue_fail; + svc.chan[k].defer_since = ch->defer_since; break; } } diff --git a/kernel/gsp_sema_service.h b/kernel/gsp_sema_service.h index 3b85591..8cd9e61 100644 --- a/kernel/gsp_sema_service.h +++ b/kernel/gsp_sema_service.h @@ -77,4 +77,12 @@ extern bool gsp_sema_gr_rings; */ extern bool gsp_sema_fake_rel; +/* + * Grace window (ms) an untranslatable GR GPFIFO entry is left pending before + * the pump consumes it as stale. The GR push pages are pinned from guest + * truth a moment after the channels appear; the window lets those pins land + * so the releases inside the pushes are applied. + */ +extern unsigned gsp_sema_gr_grace_ms; + #endif /* _GSP_SEMA_SERVICE_H_ */ diff --git a/kernel/main.c b/kernel/main.c index 726b4bf..952daf1 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -2441,6 +2441,13 @@ module_param_named(sema_fake_rel, gsp_sema_fake_rel, bool, 0644); MODULE_PARM_DESC(sema_fake_rel, "Acknowledge unreadable CE releases directly (default 0)"); /* + * Grace window (ms) an untranslatable GR entry stays pending before the pump + * consumes it as stale, so a late push-buffer pin can still make it readable. + */ +module_param_named(sema_gr_grace_ms, gsp_sema_gr_grace_ms, uint, 0644); +MODULE_PARM_DESC(sema_gr_grace_ms, "GR pending-entry grace window in ms (default 8000)"); + +/* * Debug: inject a verified {GPU VA -> guest PA} translation into the * semaphore service (used when the client's mapping cannot be discovered * from guest structures): |
