From b86f9689ab8c5fbd997cd99bccd6bab829078079 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Tue, 29 Sep 2026 12:43:12 -0400 Subject: sema-svc: learn the tracking-sem VA from readable pushes for the release fallback --- kernel/gsp_sema_service.c | 56 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 14 deletions(-) (limited to 'kernel') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 343981c..2127f38 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -139,6 +139,7 @@ struct svc_channel { u32 last_get; /* next GPFIFO entry we have still to run */ u64 submissions; /* GPFIFO entries executed */ u32 expected_sem_payload; /* next semaphore payload we expect for this channel's tracking sem */ + u64 last_rel_va; /* last tracking-sem VA seen in a readable push */ u32 logged_expected; /* last pool value logged (rate limit) */ unsigned long rescue_last; /* rate limit for the full-RAM rescue scan */ u32 rescue_fail; /* consecutive failed rescues for the entry */ @@ -1728,8 +1729,7 @@ static void svc_rebuild(struct nv_vgpu_device *vgpu) /* push application */ /* ------------------------------------------------------------------ */ -/* C5B5 (TURING_DMA_COPY_A) methods, from the class interface. */ -#define CE_M_SET_SEMAPHORE_A 0x240 +/* C5B5 (TURING_DMA_COPY_A) methods, from the class interface. */#define CE_M_SET_SEMAPHORE_A 0x240 #define CE_M_SET_SEMAPHORE_B 0x244 #define CE_M_SET_SEMAPHORE_PAY 0x248 #define CE_M_SET_SRC_PHYS_MODE 0x260 @@ -1989,6 +1989,14 @@ static bool svc_method_stream_plausible(const u8 *buf, u32 len) * translation is executed at the push's release method (see below); pages * decoded from raw sweeps never execute work at all. */ +/* + * Last tracking-semaphore VA decoded from a readable push. The pump copies + * it into the channel so the unreadable-push fallback targets the semaphore + * the client actually waits on (its pool index is allocated by UVM and does + * not match the channel rank). + */ +static u64 svc_rel_va_seen; + static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, u32 len, u64 page_pa, bool allow_ops, u32 ch_h, u32 ch_eng, u64 push_va) @@ -2119,6 +2127,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, st.rel_va = va; st.rel_payload = payload; st.have_rel = 1; + svc_rel_va_seen = va; /* The push's work always runs; see the * REPORT_SEM comment below. */ if (allow_ops && n_ops) { @@ -2188,6 +2197,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, st.rel_va = va; st.rel_payload = st.rs_payload; st.have_rel = 1; + svc_rel_va_seen = va; /* * The push's collected work always runs on * real hardware; the semaphore release only @@ -3800,12 +3810,19 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) * need but their other methods may * alias CE encodings. */ - svc_decode_stream(vgpu, pb, - len, 0, - ch->engine_type != 0, - ch->h_object, - ch->engine_type, - va); + { + u64 rel_before = svc_rel_va_seen; + + svc_decode_stream(vgpu, pb, + len, 0, + ch->engine_type != 0, + ch->h_object, + ch->engine_type, + va); + if (svc_rel_va_seen != rel_before) + ch->last_rel_va = + svc_rel_va_seen; + } ch->submissions++; svc.gpfifo_entries_done++; /* Advance expected payload for this channel's tracking semaphore. */ @@ -3841,12 +3858,20 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) * fill vidmem with garbage). Only * the release is applied. */ - svc_decode_stream(vgpu, pb, - len, 0, - false, - ch->h_object, - ch->engine_type, - va); + { + u64 rel_before = + svc_rel_va_seen; + + svc_decode_stream(vgpu, pb, + len, 0, + false, + ch->h_object, + ch->engine_type, + va); + if (svc_rel_va_seen != rel_before) + ch->last_rel_va = + svc_rel_va_seen; + } ch->submissions++; svc.gpfifo_entries_done++; if (ch->engine_type && ch->expected_sem_payload) @@ -3901,6 +3926,8 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) 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; @@ -3984,6 +4011,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) */ svc.chan[k].expected_sem_payload = ch->expected_sem_payload; + svc.chan[k].last_rel_va = ch->last_rel_va; svc.chan[k].rescue_last = ch->rescue_last; svc.chan[k].rescue_fail = ch->rescue_fail; break; -- cgit v1.2.3