summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-26 12:03:36 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-26 12:03:36 -0400
commit2735180adf067fff9a3bcb87fa34da7508e8b5ee (patch)
treebc5ab2624edcd534b1a003127483f14d44189758 /kernel
parent52ef3f9dfd44157058bd2a7833974752d049d7f0 (diff)
downloadopen-iov-2735180adf067fff9a3bcb87fa34da7508e8b5ee.tar.gz
open-iov-2735180adf067fff9a3bcb87fa34da7508e8b5ee.zip
vgsp-sema: SESSION 133b shadow ring scan - step 0x100 (the rings are unaligned: r767 USERD shape scan found the channel blocks at 0xfee00/0xff000/0xff200, so the rings sit at offsets like 0xefe00) and retry rate-limited (1.5s) instead of a consumed once-bit, because a first pass can run before the client has written the ring or its USERD
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index e60b6e0..8814a0a 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -788,6 +788,7 @@ static unsigned long svc_pb_done; /* CE ranks whose push buffer is pinned */
static unsigned long svc_gr_ring_done; /* GR ranks whose ring is pinned */
/* SESSION 133: ranks that already consumed their one shadow ring scan. */
static unsigned long svc_gr_ring_scan_done;
+static unsigned long svc_gr_ring_scan_last; /* rate limit for the scan */
static bool svc_pb_first_push(const u8 *buf)
{
@@ -16300,16 +16301,28 @@ static void svc_gr_ring_autopin(struct nv_vgpu_device *vgpu,
* bounded scan per rank per boot; a false candidate still costs
* only a failed probe.
*/
- if (!test_and_set_bit(ch->gr_index, &svc_gr_ring_scan_done)) {
+ if (!test_bit(ch->gr_index, &svc_gr_ring_scan_done)) {
u8 *sbase = vgpu->bars[1].vaddr;
u64 lim = min_t(u64, svc_fb_shadow_size(vgpu), 0x4000000ULL);
u64 off;
+ /*
+ * SESSION 133b: the rings are NOT page-aligned (r767: the
+ * USERD shape scan found the channel blocks at 0xfee00/
+ * 0xff000/0xff200, so the rings sit at unaligned offsets like
+ * 0xefe00); step by 0x100 and RETRY (rate-limited) - a first
+ * pass can run before the client has written the ring or the
+ * USERD, and a consumed once-bit would never rescan.
+ */
+ if (time_before(jiffies, (unsigned long)svc_gr_ring_scan_last +
+ msecs_to_jiffies(1500)))
+ return;
+ svc_gr_ring_scan_last = jiffies;
if (sbase && lim > 0x1000) {
static const u64 udeltas[] = { 0x10000, SVC_GR_USERD_OFF,
0x1000 };
- for (off = 0; off + 8 <= lim; off += 0x1000) {
+ for (off = 0; off + 8 <= lim; off += 0x100) {
u32 h0, h1;
u64 hva;
u32 hlen;
@@ -16347,6 +16360,8 @@ static void svc_gr_ring_autopin(struct nv_vgpu_device *vgpu,
svc_gr_ring_base = off;
set_bit(ch->gr_index,
&svc_gr_ring_done);
+ set_bit(ch->gr_index,
+ &svc_gr_ring_scan_done);
svc_ring_n++;
pr_info("sema-chan: auto-pinned GR ring h=0x%x rank=%u va=0x%llx -> fb 0x%llx (shadow scan d=0x%llx; entry0 va=0x%llx len=%u put=%u get=%u)\n",
ch->h_object, ch->gr_index,