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 | 828479d2aa9f668ececc866dc9cf00ee74662ebc (patch) | |
| tree | aceada74c618c3dc6e6f063415d129fd6e714985 | |
| parent | 06deaccd97b69f0beffe7d98ff9bfc1b0428591e (diff) | |
| download | open-iov-828479d2aa9f668ececc866dc9cf00ee74662ebc.tar.gz open-iov-828479d2aa9f668ececc866dc9cf00ee74662ebc.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.
| -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); /* |
