summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 6fa1813..bc21e95 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -2258,8 +2258,23 @@ static void svc_pd_discover(struct nv_vgpu_device *vgpu)
}
if (n < SVC_PD_MIN_HITS) {
n = 0;
- if (svc.map_n < SVC_PD_SAMPLES)
- return; /* no evidence yet: retry when pairs appear */
+ /*
+ * r510: a LARGE map is a mixed set of VA spaces cached over
+ * the whole guest boot (the comment above already names the
+ * consequence: no single directory reproduces a mixed set), so
+ * scanning with its stride subsample burns the attempts budget
+ * on evidence that cannot succeed - and by the time the
+ * push-buffer pairs (the strongest samples) exist, the budget
+ * is spent (r508/r509 witness: 'not found (base=0x0 ap=ram
+ * cands=39621 best=0/8)' during the first client, eight RAM
+ * walks consumed, every later client's high argument pointers
+ * unresolvable - the terminal class). Only a SMALL map, which
+ * is one session's own pairs, still falls back; otherwise wait
+ * for the push-buffer pairs and keep the attempts.
+ */
+ if (svc.map_n > (u32)(SVC_PD_SAMPLES * 2) ||
+ svc.map_n < SVC_PD_SAMPLES)
+ return; /* no coherent evidence yet: retry later */
step = svc.map_n / SVC_PD_SAMPLES;
for (i = 0; i < SVC_PD_SAMPLES; i++) {
sva[i] = svc.map[i * step].gpu_page;