diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-08 23:39:30 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-08 23:39:30 -0400 |
| commit | ac6734bac68c9f5495c5b895a4a724166e5f59ec (patch) | |
| tree | 68ef8470614e98fbbd588f0bb360c8238a04404e /kernel | |
| parent | ea3c9b8e85e67c4f6a4b8fa12fc708f3cc374f41 (diff) | |
| download | open-iov-ac6734bac68c9f5495c5b895a4a724166e5f59ec.tar.gz open-iov-ac6734bac68c9f5495c5b895a4a724166e5f59ec.zip | |
vgsp-sema: only a real session end may request the discovery flush (ISSUE-0002)
A redundant channel delete (a FREE for a handle that never registered, or
a repeated delete after the session already ended) found the channel set
empty while the next client was already starting and re-armed the flush,
which then executed mid-startup and wiped that client's discovery state
(and dropped its pending releases): the client spun at its first channel.
Track whether a session's channel has registered since the last flush and
request the flush only on the true existed->empty transition; redundant
deletes are inert.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 3b56c36..715e458 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -406,6 +406,7 @@ static u32 svc_ring_n; * rebuild start from the same empty state as a fresh boot. */ static u8 svc_sess_flush; +static u8 svc_sess_active; /* a channel of a session has registered (until flush) */ static unsigned long svc_ring_done; /* CE ranks whose ring is pinned (session state) */ static u8 svc_pb_passes; static u64 svc_pb_last; @@ -925,6 +926,7 @@ void gsp_sema_service_channel_add(const struct sema_channel_desc *desc) ch->gr_index = rank; } ch->valid = true; + svc_sess_active = 1; ch->h_object = desc->h_object; ch->engine_type = desc->engine_type; ch->cid = desc->cid; @@ -986,14 +988,21 @@ void gsp_sema_service_channel_del(u32 h_object) * session in a new UVM VA space; its discovery state must not inherit * this session's map/pins/page-directory latch. Request the flush * here; it executes at the next rebuild (the only writer of that - * state) just like a fresh boot would start empty. + * state) just like a fresh boot would start empty. Only the transition + * from "a session existed" to "empty" may request it: redundant + * deletes for handles that never registered would otherwise re-flush + * (and wipe) a session that started after the real one ended. */ - for (i = 0; i < SVC_MAX_CHANNELS; i++) { - if (svc.chan[i].valid) - break; + if (svc_sess_active) { + for (i = 0; i < SVC_MAX_CHANNELS; i++) { + if (svc.chan[i].valid) + break; + } + if (i == SVC_MAX_CHANNELS) { + svc_sess_active = 0; + svc_sess_flush = 1; + } } - if (i == SVC_MAX_CHANNELS) - svc_sess_flush = 1; spin_unlock_irqrestore(&svc.chan_lock, flags); /* |
