diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-06 12:15:50 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-06 12:15:50 -0400 |
| commit | a1f9d3f7b77e954a1a9ee36c7f787fe2083b544a (patch) | |
| tree | c0f3fe61bacb4b20478ddd5d0bf63041a3f1aea8 /kernel/gsp_sema_service.c | |
| parent | 3f892b2924c0bdd15aaa04899b879601bd263981 (diff) | |
| download | open-iov-a1f9d3f7b77e954a1a9ee36c7f787fe2083b544a.tar.gz open-iov-a1f9d3f7b77e954a1a9ee36c7f787fe2083b544a.zip | |
vgsp: PRIV VA-only booking bit + verify the exact slot before consuming unreadable CE entries
- fwclient mask bit 15 (0x8000): book the PRIV_ACCESS_MAP VA (the FWCLIENT
entry form is init-only; the golden9 form carries the VA at VA_GOLDEN9_PRIV).
Accepted on V6 (status 0), completing the maximal promoted context.
- gsp_sema_service: svc_entry_want_reached() verifies the exact tracking slot
against entry_want before the three unreadable-CE consume shortcuts treat the
entry as delivered; when the slot lags, re-seed the expectation and let
svc_fake_release author or queue the exact slot (UVM registration stall pair
with the pool-VA verified-resolver queue).
Diffstat (limited to 'kernel/gsp_sema_service.c')
| -rw-r--r-- | kernel/gsp_sema_service.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 2c6836f..83ca6bd 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -7957,6 +7957,38 @@ static bool svc_fake_release(struct nv_vgpu_device *vgpu, struct svc_channel *ch return true; } +/* + * True only when the exact tracking-semaphore slot this entry wants really + * reached entry_want. expected_sem_payload can move past entry_want through + * other entries' releases/fakes while this slot still lags; the consume + * shortcuts treat that as "already delivered" and strand the client's wait. + * A missing translation is "not proven reached": the caller re-seeds and + * lets svc_fake_release author or queue the exact slot. + */ +static bool svc_entry_want_reached(struct nv_vgpu_device *vgpu, + const struct svc_channel *ch) +{ + u64 spa = 0; + int sap = SVC_APERTURE_SYS; + u32 cur = 0; + + if (!ch->entry_want) + return true; + if (!ch->last_rel_va) + return false; + if (svc_pool_sem_va(ch->last_rel_va)) { + if (svc_pool_pa_resolve(vgpu, ch->h_object, ch->last_rel_va, + &spa, &sap, NULL) && + svc_lookup_trusted(vgpu, ch->last_rel_va, &spa, &sap)) + return false; + } else if (svc_lookup_trusted(vgpu, ch->last_rel_va, &spa, &sap)) { + return false; + } + if (svc_read_ap(vgpu, spa, svc_ap_of(sap), &cur, sizeof(cur))) + return false; + return cur >= ch->entry_want; +} + /* Mark a consumed GPFIFO slot for the current put epoch. */ static void svc_replay_note(struct svc_channel *ch, u32 idx, u32 put) { @@ -10617,6 +10649,21 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) if (ch->entry_want && ch->expected_sem_payload > ch->entry_want) { + /* + * The expectation can move past this entry without this + * slot ever being written (another entry's decoded + * release or fake advanced it). Verify the exact slot; + * re-seed and author it when the slot still lags, so + * consuming the entry never strands the client's wait. + */ + if (!svc_entry_want_reached(vgpu, ch)) { + pr_info_ratelimited("sema-chan: entry_want re-seed h=0x%x rank=%u want=%u expected=%u (slot lags)\n", + ch->h_object, ch->ce_index, ch->entry_want, + ch->expected_sem_payload); + ch->expected_sem_payload = ch->entry_want; + if (!svc_fake_release(vgpu, ch)) + svc.gpfifo_starved++; + } ch->defer_since = 0; ch->rescue_fail = 0; ch->unread_va = 0; @@ -10764,6 +10811,21 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) if (ch->entry_want && ch->expected_sem_payload > ch->entry_want) { + /* + * The expectation can move past this entry without this + * slot ever being written (another entry's decoded + * release or fake advanced it). Verify the exact slot; + * re-seed and author it when the slot still lags, so + * consuming the entry never strands the client's wait. + */ + if (!svc_entry_want_reached(vgpu, ch)) { + pr_info_ratelimited("sema-chan: entry_want re-seed h=0x%x rank=%u want=%u expected=%u (slot lags)\n", + ch->h_object, ch->ce_index, ch->entry_want, + ch->expected_sem_payload); + ch->expected_sem_payload = ch->entry_want; + if (!svc_fake_release(vgpu, ch)) + svc.gpfifo_starved++; + } ch->defer_since = 0; ch->rescue_fail = 0; ch->unread_va = 0; @@ -10864,6 +10926,21 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) ch->expected_sem_payload > ch->entry_want) { /* + * The expectation can move past this entry without this + * slot ever being written (another entry's decoded + * release or fake advanced it). Verify the exact slot; + * re-seed and author it when the slot still lags, so + * consuming the entry never strands the client's wait. + */ + if (!svc_entry_want_reached(vgpu, ch)) { + pr_info_ratelimited("sema-chan: entry_want re-seed h=0x%x rank=%u want=%u expected=%u (slot lags)\n", + ch->h_object, ch->ce_index, ch->entry_want, + ch->expected_sem_payload); + ch->expected_sem_payload = ch->entry_want; + if (!svc_fake_release(vgpu, ch)) + svc.gpfifo_starved++; + } + /* * Already delivered * (the content sweep * applied this entry's |
