diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2018-10-19 14:36:43 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2018-10-31 12:16:30 +0000 |
commit | e09de0a20d42e5e76e91ffc7f9f4787e225e1ec2 (patch) | |
tree | 8619f49edf4361b8fe33f44db5efb8fb9defe23a /accel/tcg | |
parent | f8144c6c1e7574a8f2da05709a81bfc8b9215d77 (diff) |
cputlb: Count "partial" and "elided" tlb flushes
Our only statistic so far was "full" tlb flushes, where all mmu_idx
are flushed at the same time.
Now count "partial" tlb flushes where sets of mmu_idx are flushed,
but the set is not maximal. Account one per mmu_idx flushed, as
that is the unit of work performed.
We don't actually count elided flushes yet, but go ahead and change
the interface presented to the monitor all at once.
Tested-by: Emilio G. Cota <cota@braap.org>
Reviewed-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'accel/tcg')
-rw-r--r-- | accel/tcg/cputlb.c | 18 | ||||
-rw-r--r-- | accel/tcg/translate-all.c | 8 |
2 files changed, 19 insertions, 7 deletions
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index 1f7764de94..e60628c350 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -100,17 +100,21 @@ static void flush_all_helper(CPUState *src, run_on_cpu_func fn, } } -size_t tlb_flush_count(void) +void tlb_flush_counts(size_t *pfull, size_t *ppart, size_t *pelide) { CPUState *cpu; - size_t count = 0; + size_t full = 0, part = 0, elide = 0; CPU_FOREACH(cpu) { CPUArchState *env = cpu->env_ptr; - count += atomic_read(&env->tlb_flush_count); + full += atomic_read(&env->tlb_c.full_flush_count); + part += atomic_read(&env->tlb_c.part_flush_count); + elide += atomic_read(&env->tlb_c.elide_flush_count); } - return count; + *pfull = full; + *ppart = part; + *pelide = elide; } static void tlb_flush_one_mmuidx_locked(CPUArchState *env, int mmu_idx) @@ -145,7 +149,11 @@ static void tlb_flush_by_mmuidx_async_work(CPUState *cpu, run_on_cpu_data data) cpu_tb_jmp_cache_clear(cpu); if (mmu_idx_bitmask == ALL_MMUIDX_BITS) { - atomic_set(&env->tlb_flush_count, env->tlb_flush_count + 1); + atomic_set(&env->tlb_c.full_flush_count, + env->tlb_c.full_flush_count + 1); + } else { + atomic_set(&env->tlb_c.part_flush_count, + env->tlb_c.part_flush_count + ctpop16(mmu_idx_bitmask)); } } diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 356dcd0948..639f0b2728 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -2290,7 +2290,7 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf) { struct tb_tree_stats tst = {}; struct qht_stats hst; - size_t nb_tbs; + size_t nb_tbs, flush_full, flush_part, flush_elide; tcg_tb_foreach(tb_tree_stats_iter, &tst); nb_tbs = tst.nb_tbs; @@ -2326,7 +2326,11 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf) cpu_fprintf(f, "TB flush count %u\n", atomic_read(&tb_ctx.tb_flush_count)); cpu_fprintf(f, "TB invalidate count %zu\n", tcg_tb_phys_invalidate_count()); - cpu_fprintf(f, "TLB flush count %zu\n", tlb_flush_count()); + + tlb_flush_counts(&flush_full, &flush_part, &flush_elide); + cpu_fprintf(f, "TLB full flushes %zu\n", flush_full); + cpu_fprintf(f, "TLB partial flushes %zu\n", flush_part); + cpu_fprintf(f, "TLB elided flushes %zu\n", flush_elide); tcg_dump_info(f, cpu_fprintf); } |