[PATCH v1 15/15] accel/tcg: add heuristic to invalidate al TBs in a page [hack!]

Alex Bennée posted 15 patches 3 years, 10 months ago
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, "Alex Bennée" <alex.bennee@linaro.org>, Alexandre Iooss <erdnaxe@crans.org>, Mahmoud Mandour <ma.mandourr@gmail.com>, "Dr. David Alan Gilbert" <dgilbert@redhat.com>, Markus Armbruster <armbru@redhat.com>, Cleber Rosa <crosa@redhat.com>, "Philippe Mathieu-Daudé" <f4bug@amsat.org>, Wainer dos Santos Moschetta <wainersm@redhat.com>, Beraldo Leal <bleal@redhat.com>, Peter Maydell <peter.maydell@linaro.org>, Stefan Hajnoczi <stefanha@redhat.com>
[PATCH v1 15/15] accel/tcg: add heuristic to invalidate al TBs in a page [hack!]
Posted by Alex Bennée 3 years, 10 months ago
This is a dumb attempt to reduce to the execution time of UEFI booted
kernels and almost certainly not what the final solution should be.

The problem is if we have generated JIT code from running firmware we
can spend a lot of time carefully invalidating every TB in a page when
the kernel that eventually boots and clears all the pages in RAM.

This fix simply assumes any write to the start of the page should
invalidate everything in the page. Once that is done following writes
to the page should all follow the fast path.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 accel/tcg/translate-all.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 625c46dd9b..67884260fa 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1830,6 +1830,16 @@ void tb_invalidate_phys_page_fast(struct page_collection *pages,
                                   uintptr_t retaddr)
 {
     PageDesc *p = page_find(start >> TARGET_PAGE_BITS);
+    unsigned int nr = start & ~TARGET_PAGE_MASK;
+
+    /*
+     * Assume any write to the start of the page is start of clearing
+     * the whole page. To avoid coming back multiple times lets just
+     * invalidate everything first.
+     */
+    if (nr == 0) {
+        len = TARGET_PAGE_SIZE;
+    }
 
     if (trace_event_get_state_backends(TRACE_TB_INVALIDATE_PHYS_PAGE_FAST)) {
         TranslationBlock *tb = tcg_tb_lookup(retaddr);
@@ -1850,10 +1860,8 @@ void tb_invalidate_phys_page_fast(struct page_collection *pages,
         build_page_bitmap(p);
     }
     if (p->code_bitmap) {
-        unsigned int nr;
         unsigned long b;
 
-        nr = start & ~TARGET_PAGE_MASK;
         b = p->code_bitmap[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG - 1));
         if (b & ((1 << len) - 1)) {
             goto do_invalidate;
-- 
2.30.2