From: "Alex Bennée" <alex.bennee@linaro.org>
To: Richard Henderson <richard.henderson@linaro.org>
Cc: qemu-devel@nongnu.org, laurent@vivier.eu, pbonzini@redhat.com,
imp@bsdimp.com, f4bug@amsat.org
Subject: Re: [PATCH 15/24] accel/tcg: Use interval tree for TBs in user-only mode
Date: Tue, 25 Oct 2022 16:58:19 +0100 [thread overview]
Message-ID: <87wn8n6g1v.fsf@linaro.org> (raw)
In-Reply-To: <20221006031113.1139454-16-richard.henderson@linaro.org>
Richard Henderson <richard.henderson@linaro.org> writes:
> Begin weaning user-only away from PageDesc.
>
> Since, for user-only, all TB (and page) manipulation is done with
> a single mutex, and there is no virtual/physical discontinuity to
> split a TB across discontinuous pages, place all of the TBs into
> a single IntervalTree. This makes it trivial to find all of the
> TBs intersecting a range.
>
> Retain the existing PageDesc + linked list implementation for
> system mode. Move the portion of the implementation that overlaps
> the new user-only code behind the common ifdef.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> accel/tcg/internal.h | 16 +-
> include/exec/exec-all.h | 43 ++++-
> accel/tcg/tb-maint.c | 388 ++++++++++++++++++++++----------------
> accel/tcg/translate-all.c | 4 +-
> 4 files changed, 280 insertions(+), 171 deletions(-)
>
<snip>
> diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
> index c8e921089d..14e8e47a6a 100644
> --- a/accel/tcg/tb-maint.c
> +++ b/accel/tcg/tb-maint.c
> @@ -18,6 +18,7 @@
> */
>
> #include "qemu/osdep.h"
> +#include "qemu/interval-tree.h"
> #include "exec/cputlb.h"
> #include "exec/log.h"
> #include "exec/exec-all.h"
> @@ -50,6 +51,75 @@ void tb_htable_init(void)
> qht_init(&tb_ctx.htable, tb_cmp, CODE_GEN_HTABLE_SIZE, mode);
> }
I wonder for the sake of avoiding recompilation of units later on and
having a clean separation between user and system mode it would be worth
putting this stuff in a tb-maint-user.c?
>
> +#ifdef CONFIG_USER_ONLY
> +/*
> + * For user-only, since we are protecting all of memory with a single lock,
> + * and because the two pages of a TranslationBlock are always contiguous,
> + * use a single data structure to record all TranslationBlocks.
> + */
<snip>
> +
> +/*
> + * Called with mmap_lock held. If pc is not 0 then it indicates the
> + * host PC of the faulting store instruction that caused this invalidate.
> + * Returns true if the caller needs to abort execution of the current
> + * TB (because it was modified by this store and the guest CPU has
> + * precise-SMC semantics).
> + */
> +bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc)
> +{
> + assert(pc != 0);
> +#ifdef TARGET_HAS_PRECISE_SMC
> + assert_memory_lock();
Out of interest is this just because x86 has such a strong memory model
you can get away with this sort of patching without explicit flushes?
I'm curious why this is the only arch we jump through these hoops for?
> + {
> + TranslationBlock *current_tb = tcg_tb_lookup(pc);
> + bool current_tb_modified = false;
> + TranslationBlock *tb;
> + PageForEachNext n;
> +
> + addr &= TARGET_PAGE_MASK;
> +
> + PAGE_FOR_EACH_TB(addr, addr + TARGET_PAGE_SIZE, unused, tb, n) {
> + if (current_tb == tb &&
> + (tb_cflags(current_tb) & CF_COUNT_MASK) != 1) {
> + /*
> + * If we are modifying the current TB, we must stop its
> + * execution. We could be more precise by checking that
> + * the modification is after the current PC, but it would
> + * require a specialized function to partially restore
> + * the CPU state.
> + */
> + current_tb_modified = true;
> + cpu_restore_state_from_tb(current_cpu, current_tb, pc, true);
> + }
> + tb_phys_invalidate__locked(tb);
> + }
> +
> + if (current_tb_modified) {
> + /* Force execution of one insn next time. */
> + CPUState *cpu = current_cpu;
> + cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(current_cpu);
> + return true;
> + }
> + }
> +#else
> + tb_invalidate_phys_page(addr);
> +#endif /* TARGET_HAS_PRECISE_SMC */
> + return false;
> +}
> +#else
> /*
> * @p must be non-NULL.
> * user-mode: call with mmap_lock held.
> @@ -492,22 +637,17 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
> {
> TranslationBlock *tb;
> tb_page_addr_t tb_start, tb_end;
> - int n;
> + PageForEachNext n;
> #ifdef TARGET_HAS_PRECISE_SMC
> - CPUState *cpu = current_cpu;
> - bool current_tb_not_found = retaddr != 0;
> bool current_tb_modified = false;
> - TranslationBlock *current_tb = NULL;
> + TranslationBlock *current_tb = retaddr ? tcg_tb_lookup(retaddr) : NULL;
> #endif /* TARGET_HAS_PRECISE_SMC */
>
> - assert_page_locked(p);
> -
> /*
> * We remove all the TBs in the range [start, end[.
> * XXX: see if in some cases it could be faster to invalidate all the code
> */
I'm guessing this comment is quite stale now given we try quite hard to
avoid doing lots of code gen over and over again. The only case I can
think of is memory clear routines after we've had code which there might
be some heuristics we could use to detect but don't currently.
<snip>
Otherwise:
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
--
Alex Bennée
next prev parent reply other threads:[~2022-10-25 16:10 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-06 3:10 [PATCH 00/24] accel/tcg: Rewrite user-only vma tracking Richard Henderson
2022-10-06 3:10 ` [PATCH 01/24] util: Add interval-tree.c Richard Henderson
2022-10-25 8:40 ` Alex Bennée
2022-10-25 10:36 ` Richard Henderson
2022-10-06 3:10 ` [PATCH 02/24] accel/tcg: Make page_alloc_target_data allocation constant Richard Henderson
2022-10-25 8:45 ` Alex Bennée
2022-10-06 3:10 ` [PATCH 03/24] accel/tcg: Remove disabled debug in translate-all.c Richard Henderson
2022-10-25 8:46 ` Alex Bennée
2022-10-06 3:10 ` [PATCH 04/24] accel/tcg: Split out PageDesc to internal.h Richard Henderson
2022-10-25 8:47 ` Alex Bennée
2022-10-06 3:10 ` [PATCH 05/24] accel/tcg: Split out tb-maint.c Richard Henderson
2022-10-25 8:49 ` Alex Bennée
2022-10-06 3:10 ` [PATCH 06/24] accel/tcg: Move assert_no_pages_locked to internal.h Richard Henderson
2022-10-25 8:49 ` Alex Bennée
2022-10-06 3:10 ` [PATCH 07/24] accel/tcg: Drop cpu_get_tb_cpu_state from TARGET_HAS_PRECISE_SMC Richard Henderson
2022-10-25 8:50 ` Alex Bennée
2022-10-06 3:10 ` [PATCH 08/24] accel/tcg: Remove duplicate store to tb->page_addr[] Richard Henderson
2022-10-25 9:12 ` Alex Bennée
2022-10-06 3:10 ` [PATCH 09/24] accel/tcg: Introduce tb_{set_}page_addr{0,1} Richard Henderson
2022-10-25 9:47 ` Alex Bennée
2022-10-06 3:10 ` [PATCH 10/24] accel/tcg: Rename tb_invalidate_phys_page Richard Henderson
2022-10-25 9:49 ` Alex Bennée
2022-10-06 3:11 ` [PATCH 11/24] accel/tcg: Rename tb_invalidate_phys_page_range and drop end parameter Richard Henderson
2022-10-25 13:21 ` Alex Bennée
2022-10-06 3:11 ` [PATCH 12/24] accel/tcg: Unify declarations of tb_invalidate_phys_range Richard Henderson
2022-10-25 13:24 ` Alex Bennée
2022-10-06 3:11 ` [PATCH 13/24] accel/tcg: Use tb_invalidate_phys_page in page_set_flags Richard Henderson
2022-10-06 3:11 ` [PATCH 14/24] accel/tcg: Call tb_invalidate_phys_page for PAGE_RESET Richard Henderson
2022-10-25 15:42 ` Alex Bennée
2022-10-25 20:55 ` Richard Henderson
2022-10-06 3:11 ` [PATCH 15/24] accel/tcg: Use interval tree for TBs in user-only mode Richard Henderson
2022-10-25 15:58 ` Alex Bennée [this message]
2022-10-25 21:19 ` Richard Henderson
2022-10-06 3:11 ` [PATCH 16/24] accel/tcg: Use page_reset_target_data in page_set_flags Richard Henderson
2022-10-25 16:12 ` Alex Bennée
2022-10-06 3:11 ` [PATCH 17/24] accel/tcg: Use tb_invalidate_phys_range " Richard Henderson
2022-10-25 16:14 ` Alex Bennée
2022-10-06 3:11 ` [PATCH 18/24] accel/tcg: Move TARGET_PAGE_DATA_SIZE impl to user-exec.c Richard Henderson
2022-10-25 16:15 ` Alex Bennée
2022-10-06 3:11 ` [PATCH 19/24] accel/tcg: Simplify page_get/alloc_target_data Richard Henderson
2022-10-25 16:19 ` Alex Bennée
2022-10-06 3:11 ` [PATCH 20/24] accel/tcg: Use interval tree for TARGET_PAGE_DATA_SIZE Richard Henderson
2022-10-25 19:30 ` Alex Bennée
2022-10-25 21:29 ` Richard Henderson
2022-10-06 3:11 ` [PATCH 21/24] accel/tcg: Move page_{get,set}_flags to user-exec.c Richard Henderson
2022-10-26 12:35 ` [PATCH 21/24] accel/tcg: Move page_{get, set}_flags " Alex Bennée
2022-10-06 3:11 ` [PATCH 22/24] accel/tcg: Use interval tree for user-only page tracking Richard Henderson
2022-10-26 13:36 ` Alex Bennée
2022-10-27 10:20 ` Richard Henderson
2022-10-27 15:59 ` Alex Bennée
2022-10-27 21:38 ` Richard Henderson
2022-10-06 3:11 ` [PATCH 23/24] accel/tcg: Move PageDesc tree into tb-maint.c for system Richard Henderson
2022-10-06 3:11 ` [PATCH 24/24] accel/tcg: Move remainder of page locking to tb-maint.c Richard Henderson
2022-10-26 13:48 ` Alex Bennée
2022-10-24 23:05 ` [PATCH 00/24] accel/tcg: Rewrite user-only vma tracking Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87wn8n6g1v.fsf@linaro.org \
--to=alex.bennee@linaro.org \
--cc=f4bug@amsat.org \
--cc=imp@bsdimp.com \
--cc=laurent@vivier.eu \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.