diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-09 15:15:02 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-09 15:15:02 -0400 |
| commit | 8d200b558b31eedcdaf996846cb2e7d618699011 (patch) | |
| tree | 4f0ede7e96c3752ed1dd052a216c691d70da99bf /kernel | |
| parent | f21a5e7b83c13ad0d7b9b23693fd0d122eace409 (diff) | |
| download | open-iov-8d200b558b31eedcdaf996846cb2e7d618699011.tar.gz open-iov-8d200b558b31eedcdaf996846cb2e7d618699011.zip | |
Revert "vgsp-sema: CE USERD is layout-only" for now (ISSUE-0002)
r43/r44 showed the strict CE branch never engaged for the second
session: no sema-chan/sema-put line for c2's CE channels at all (the
layout probe did not accept), so c2 stalled before any USERD was
selected. Restore the r42 validated-layout behaviour (c1 green, c2
progresses to the known crel=216 stall) until the layout probe's
failure in session 2 is instrumented. The next experiment must log the
CE branch's ring-validation and layout-probe rc/p/g per pass.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 95 |
1 files changed, 46 insertions, 49 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 07aa8fa..4cc1624 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -7715,59 +7715,56 @@ static int svc_chan_userd(struct nv_vgpu_device *vgpu, struct svc_channel *ch, : SVC_APERTURE_FB; /* - * ISSUE-0002 (r40/r42): CE USERD selection is layout-driven and must - * not fall back to the registered userdMem offset. That offset is - * pool-relative (see below) and in a second session it aliases a - * DIFFERENT rank's real USERD whose stale put/get from the previous - * session wins the coherent-pair probe while this channel's true - * block is still idle: c2 rank0 read rank3's stale 1/1 at FB 0xf0000 - * and the pump never followed rank0's own GP_PUT (r40/r42). The true - * CE USERD sits at ring + 0x10000 in the ring's aperture - confirmed - * by the guest CPU mapping of gpFifoGpuVa (GPU VA gpfifo+0x20000 maps - * to BAR offset ring+0x10000) and by every CE rank that resolved - * correctly. + * ISSUE-0002 (r40): prefer the layout-derived CE USERD and accept it + * while it is still idle. In a second session the registered userdMem + * offset (pool-relative, see below) aliases a DIFFERENT rank's real + * USERD whose stale put/get from the previous session won the + * coherent-pair probe while this channel's true block was still 0/0: + * c2 rank0 read rank3's stale 1/1 at FB 0xf0000 and the pump never + * followed rank0's own GP_PUT. The true CE USERD sits at + * ring + 0x10000 in the ring's aperture - confirmed by the guest + * CPU mapping of gpFifoGpuVa (GPU VA gpfifo+0x20000 maps to BAR + * offset ring+0x10000) and by every CE rank that resolved correctly. + * An idle (0/0) read is accepted here because the guest writes the + * block on the channel's first push; only unreadable or incoherent + * candidates fall through to the old list. * - * Ordering trap: this function is called on passes BEFORE the ring is - * pinned, and the old list then accepted the stale registered block. - * For CE channels therefore: no ring -> keep waiting; ring must - * validate (entry0 = a CE push VA + len, the same gate as - * svc_ring_autopin); then the layout USERD may be accepted while - * still idle (0/0) because the guest writes it on the first push. - * Any other outcome returns -ENOENT so the pump retries next pass - - * never the registered candidate. - */ - if (ch->engine_type != 0) { + * The ring itself must validate first (entry0 = a CE push VA + len, + * same gate as svc_ring_autopin): r41 showed svc_lookup can answer a + * fresh gpfifo VA with an unrelated FB offset (rank4 -> 0x90000), and + * an idle acceptance on that bogus base cemented the wrong USERD. + */ + if (ring_pa && ch->engine_type != 0) { u8 e[SVC_GPFIFO_ENTRY_SIZE]; - u32 e0, e1, len, p = 0, g = 0; + u32 e0, e1, len; u64 va; - int rc; + bool ring_ok = false; - if (!ring_pa) - return -ENOENT; - /* - * svc_lookup can answer a fresh gpfifo VA with an - * unrelated FB offset (r41 rank4 -> 0x90000); validate the - * ring content before deriving anything from it. - */ - if (svc_read_ap(vgpu, ring_pa, ring_ap, e, sizeof(e))) - return -ENOENT; - memcpy(&e0, e, 4); - memcpy(&e1, e + 4, 4); - va = ((u64)(e1 & 0xff) << 32) | (u64)(e0 & 0xfffffffc); - len = ((e1 >> 10) & 0x1fffff) << 2; - if ((va & 0xfffff) || va < 0x120000000ULL || - va >= 0x121000000ULL || len < 4 || len > 0x10000) - return -ENOENT; - rc = svc_userd_probe(vgpu, ring_pa + 0x10000, ring_ap, - ch->gpfifo_entries, &p, &g); - if (rc && rc != -EAGAIN) - return -ENOENT; - ch->userd_pa = ring_pa + 0x10000; - ch->userd_as = ring_ap; - ch->userd_ok = true; - *put = p; - *get = g; - return 0; + if (!svc_read_ap(vgpu, ring_pa, ring_ap, e, sizeof(e))) { + memcpy(&e0, e, 4); + memcpy(&e1, e + 4, 4); + va = ((u64)(e1 & 0xff) << 32) | + (u64)(e0 & 0xfffffffc); + len = ((e1 >> 10) & 0x1fffff) << 2; + ring_ok = !(va & 0xfffff) && + va >= 0x120000000ULL && va < 0x121000000ULL && + len >= 4 && len <= 0x10000; + } + if (ring_ok) { + u32 p = 0, g = 0; + int rc = svc_userd_probe(vgpu, ring_pa + 0x10000, + ring_ap, ch->gpfifo_entries, + &p, &g); + + if (rc == 0 || rc == -EAGAIN) { + ch->userd_pa = ring_pa + 0x10000; + ch->userd_as = ring_ap; + ch->userd_ok = true; + *put = p; + *get = g; + return 0; + } + } } if (ring_pa) { |
