diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-29 13:04:12 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-29 13:04:12 -0400 |
| commit | acebd5c83c25dc5d6a53613fc9a617ce97c43acb (patch) | |
| tree | b9ac319ca1b858f699fc14c1e5ab9751e0e8d656 /kernel/gsp_sema_service.c | |
| parent | 942a87ec02b551b5eb36d447d828666684081636 (diff) | |
| download | open-iov-acebd5c83c25dc5d6a53613fc9a617ce97c43acb.tar.gz open-iov-acebd5c83c25dc5d6a53613fc9a617ce97c43acb.zip | |
sema-svc: fake_rel applies releases immediately (skip multi-second CE rescue scans)
Diffstat (limited to 'kernel/gsp_sema_service.c')
| -rw-r--r-- | kernel/gsp_sema_service.c | 95 |
1 files changed, 54 insertions, 41 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 2127f38..7475ea7 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -3671,6 +3671,39 @@ static void svc_counter_publish(struct nv_vgpu_device *vgpu, ch->h_object, ch->counter_pa, val); } +/* + * Acknowledge a CE tracking-semaphore release without reading the push that + * carried it: write the expected payload into the semaphore the channel last + * released to (learned from a readable push; the pool index is allocated by + * UVM and does not match the channel rank). Returns false when there is + * nothing to fall back on. Caller owns expected_sem_payload bookkeeping. + */ +static bool svc_fake_release(struct nv_vgpu_device *vgpu, struct svc_channel *ch) +{ + u64 pool_va; + u64 spa = 0; + int sap = SVC_APERTURE_SYS; + u32 scur = 0; + + if (!ch->engine_type || !ch->expected_sem_payload) + return false; + + pool_va = ch->last_rel_va ? ch->last_rel_va : + 0x121000000ULL + 4ULL * ch->ce_index; + + if (!svc_lookup_trusted(vgpu, pool_va, &spa, &sap) && + !svc_read_ap(vgpu, spa, sap, &scur, sizeof(scur)) && + scur < ch->expected_sem_payload) { + u32 nv = ch->expected_sem_payload; + + if (!svc_write_ap(vgpu, spa, sap, &nv, sizeof(nv))) + svc.releases_applied++; + } + svc.releases_faked++; + ch->expected_sem_payload++; + return true; +} + static void svc_pump_channels(struct nv_vgpu_device *vgpu) { /* Only ever called from the service thread. */ @@ -3837,6 +3870,24 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) * its whole slot. */ svc_log_stalled_va(va); + /* + * With the fallback enabled the rescue + * is pointless for CE: it never + * executes the work anyway (only the + * release), and its multi-second RAM + * scan is what made the driver's + * progress waits expire. Acknowledge + * the release and move on. + */ + if (gsp_sema_fake_rel && + svc_fake_release(vgpu, ch)) { + ch->last_get = (idx + 1) % + ch->gpfifo_entries; + svc.gpfifo_skipped++; + stalled = true; + kfree(pb); + continue; + } if (svc.false_trans && svc.false_trans < 8) pr_info("sema-svc: false translation for push va=0x%llx (h=0x%x len=%u) - rescuing\n", va, ch->h_object, len); @@ -3915,47 +3966,9 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) ch->h_object, va, len, ch->rescue_fail); ch->rescue_fail = 0; - /* - * The entry carried a tracking- - * semaphore release we could not - * read. Acknowledge it the way the - * GPU would so the driver's wait - * clears in one pass. - */ - if (gsp_sema_fake_rel && - ch->engine_type && - ch->expected_sem_payload) { - u64 pool_va = - ch->last_rel_va ? - ch->last_rel_va : - 0x121000000ULL + - 4ULL * ch->ce_index; - u64 spa = 0; - int sap = - SVC_APERTURE_SYS; - u32 scur = 0; - - if (!svc_lookup_trusted( - vgpu, - pool_va, - &spa, - &sap) && - !svc_read_ap(vgpu, - spa, sap, - &scur, - sizeof(scur)) && - scur < ch->expected_sem_payload) { - u32 nv = - ch->expected_sem_payload; - - if (!svc_write_ap(vgpu, - spa, sap, - &nv, - sizeof(nv))) - svc.releases_applied++; - } - svc.releases_faked++; - } + if (gsp_sema_fake_rel) + svc_fake_release(vgpu, + ch); ch->last_get = (idx + 1) % ch->gpfifo_entries; svc.gpfifo_skipped++; |
