summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-06 12:15:50 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-06 12:15:50 -0400
commita1f9d3f7b77e954a1a9ee36c7f787fe2083b544a (patch)
treec0f3fe61bacb4b20478ddd5d0bf63041a3f1aea8 /kernel/gsp_sema_service.c
parent3f892b2924c0bdd15aaa04899b879601bd263981 (diff)
downloadopen-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.c77
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