summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
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,