summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-08 23:39:30 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-08 23:39:30 -0400
commit828479d2aa9f668ececc866dc9cf00ee74662ebc (patch)
treeaceada74c618c3dc6e6f063415d129fd6e714985 /kernel
parent06deaccd97b69f0beffe7d98ff9bfc1b0428591e (diff)
downloadopen-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.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c21
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);
/*