From acebd5c83c25dc5d6a53613fc9a617ce97c43acb Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Tue, 29 Sep 2026 13:04:12 -0400 Subject: sema-svc: fake_rel applies releases immediately (skip multi-second CE rescue scans) --- kernel/gsp_sema_service.c | 95 +++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 41 deletions(-) (limited to 'kernel') 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++; -- cgit v1.2.3