summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 16:14:12 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 16:14:12 -0400
commit6b445171b4c50ed74f19272f5bff7c0f42887e6d (patch)
tree1b8296cc428d0a0bd0ac711ebb078a8370fe0121 /kernel
parent9a09a15cd816d5f579ec563227b031c188cdc875 (diff)
downloadopen-iov-6b445171b4c50ed74f19272f5bff7c0f42887e6d.tar.gz
open-iov-6b445171b4c50ed74f19272f5bff7c0f42887e6d.zip
sema-svc: persist GR counter slot per channel; stable slot layout; bulk pin queue 4k
- counter_pa autoreg result is written back to the channel table so later passes cannot re-target a different slot when the live GR count changes during teardown; re-registration of the same channel preserves the slot. - counter slot layout uses the max GR count ever seen in the generation instead of the shrinking live count. - sema_map_add queue 64 -> 4096 entries so a full-window pin burst drains without ENOSPC retries. - pin_gr_stream: one batched sudo pass per flush (was one process per run, ~4 s for 400 runs), retrying only queue-rejected runs. - semfix_uvmt: SEMFIX_SKIP_PB=1 skips the blocking push-buffer chain walk when the vsock window stream already supplies those pages.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index c46cbbb..5bff6ca 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -481,6 +481,21 @@ void gsp_sema_service_channel_add(const struct sema_channel_desc *desc)
}
if (ch) {
int k;
+ u64 keep_counter_pa = 0;
+ u8 keep_gr_index = 0, keep_ce_index = 0;
+ bool same = ch->valid && ch->h_object == desc->h_object;
+
+ /*
+ * A re-registration of the same channel must not lose the
+ * counter slot learned for it (the RM re-issues registration
+ * for an existing channel on some control paths, and the
+ * counter layout does not change).
+ */
+ if (same) {
+ keep_counter_pa = ch->counter_pa;
+ keep_gr_index = ch->gr_index;
+ keep_ce_index = ch->ce_index;
+ }
memset(ch, 0, sizeof(*ch));
/*
@@ -520,6 +535,11 @@ void gsp_sema_service_channel_add(const struct sema_channel_desc *desc)
ch->notifier_pa = desc->notifier_pa;
ch->notifier_as = desc->notifier_as ? desc->notifier_as
: SVC_APERTURE_SYS;
+ if (same) {
+ ch->counter_pa = keep_counter_pa;
+ ch->gr_index = keep_gr_index;
+ ch->ce_index = keep_ce_index;
+ }
}
spin_unlock_irqrestore(&svc.chan_lock, flags);
@@ -3987,6 +4007,13 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
{
/* Only ever called from the service thread. */
static struct svc_channel local[SVC_MAX_CHANNELS];
+ /*
+ * Total GR channels the client ever had in the current generation.
+ * The counter-slot layout is fixed when the client allocates all its
+ * channels, so the slot must not be recomputed with a shrinking live
+ * count (a teardown pass would re-target the wrong slot).
+ */
+ static int svc_gr_max;
unsigned long flags;
int i, k, n = 0, n_gr = 0;
bool stalled = false;
@@ -4001,6 +4028,12 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
}
spin_unlock_irqrestore(&svc.chan_lock, flags);
+ if (n_gr > svc_gr_max)
+ svc_gr_max = n_gr;
+ else if (!n_gr)
+ svc_gr_max = 0;
+ n_gr = svc_gr_max;
+
for (i = 0; i < n; i++) {
struct svc_channel *ch = &local[i];
u64 ring_pa = 0;
@@ -4354,6 +4387,14 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
svc.chan[k].rescue_last = ch->rescue_last;
svc.chan[k].rescue_fail = ch->rescue_fail;
svc.chan[k].defer_since = ch->defer_since;
+ /*
+ * Persist the counter slot autoreg resolved on the
+ * snapshot: without this the next pass re-derives
+ * it (with a different live GR count during
+ * teardown) and the publishes target the wrong
+ * slot.
+ */
+ svc.chan[k].counter_pa = ch->counter_pa;
break;
}
}
@@ -4620,7 +4661,7 @@ int gsp_sema_service_dump_channels(void)
* could not take a batch at all.
*/
#define SVC_PIN_REWIND 8
-#define SVC_MAP_ADD_MAX 64
+#define SVC_MAP_ADD_MAX 4096
struct svc_map_add_req {
u64 va;