diff options
| -rw-r--r-- | kernel/gsp_phys_booter.c | 83 |
1 files changed, 74 insertions, 9 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index af7befc..f603c10 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -16619,9 +16619,34 @@ gsp_phys_gr_output_retire_wait(const struct gsp_phys_gr_submit *req, u64 out_base = 0; u32 out_pages = 0, di; - for (di = 0; di < req->n_data; di++) + /* + * The output footprint is the contiguous descending reloc run from + * the highest reloc_va that belongs to a kernel OPERAND. The fill + * also relocates the launch's own param/bank pages (they appear as + * high-VA candidates in the push), and those would otherwise make + * out_base the top of the window and out_pages the whole budget - + * the r147 first cut waited the full 1.5 s on every launch because + * of it. Exclude any data entry whose guest VA is one of the + * forwarded launch pages (qmd_word pages; 0xffffffff marks the + * non-QMD forwarded pages). + */ + for (di = 0; di < req->n_data; di++) { + u32 pj; + bool launch_page = false; + + for (pj = 0; pj < req->n_pages; pj++) { + if (req->pages[pj].qmd_word == 0xffffffffu) + continue; + if (req->pages[pj].guest_va == req->data[di].va) { + launch_page = true; + break; + } + } + if (launch_page) + continue; if (req->data[di].reloc_va > out_base) out_base = req->data[di].reloc_va; + } if (out_base) { for (;;) { u64 want = out_base - @@ -16629,11 +16654,30 @@ gsp_phys_gr_output_retire_wait(const struct gsp_phys_gr_submit *req, u32 k; bool hit = false; - for (k = 0; k < req->n_data; k++) - if (req->data[k].reloc_va == want) { - hit = true; - break; + for (k = 0; k < req->n_data; k++) { + if (req->data[k].reloc_va != want) + continue; + /* launch pages were excluded from out_base */ + { + u32 pj; + bool lp = false; + + for (pj = 0; pj < req->n_pages; pj++) { + if (req->pages[pj].qmd_word == + 0xffffffffu) + continue; + if (req->pages[pj].guest_va == + req->data[k].va) { + lp = true; + break; + } + } + if (lp) + continue; } + hit = true; + break; + } if (!hit || out_pages >= GSP_PHYS_RMCALL_GR_MAIL_SLOT) break; @@ -16646,7 +16690,8 @@ gsp_phys_gr_output_retire_wait(const struct gsp_phys_gr_submit *req, out_pages = GSP_PHYS_RMCALL_GR_MAIL_SLOT; if (out_pages >= 2u) { unsigned long wait_start = jiffies; - u32 changed = 0, iter; + u32 changed = 0, prev = 0xffffffffu, iter; + const char *why = " (TIMEOUT)"; for (iter = 0; iter < 300u; iter++) { u32 j; @@ -16669,14 +16714,34 @@ gsp_phys_gr_output_retire_wait(const struct gsp_phys_gr_submit *req, if (csum != csum_in[bi]) changed++; } - if (changed >= out_pages) + if (changed >= out_pages) { + why = ""; break; + } + /* + * Adaptive exits: no write at all after 60 ms means the + * engine either rewrote identical bytes (a repeated + * benchmark launch) or produced no output for this + * footprint; a partial count that stops growing for + * three polls means the stores have settled (masked / + * partial-output kernels). Both avoid paying the full + * 1.5 s on every launch while still catching genuinely + * late writes. + */ + if (iter >= 12u && changed == 0) { + why = " (no writes)"; + break; + } + if (changed > 0 && changed == prev && iter >= 24u) { + why = " (settled)"; + break; + } + prev = changed; usleep_range(4000, 6000); } pr_info("vgsp-gr: output retirement wait: %u/%u pages changed after %u ms%s\n", changed, out_pages, - jiffies_to_msecs(jiffies - wait_start), - (changed >= out_pages) ? "" : " (TIMEOUT)"); + jiffies_to_msecs(jiffies - wait_start), why); } } |
