From patchwork Wed Jun 7 12:24:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Wu, Fei" X-Patchwork-Id: 13270623 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 797CBC7EE25 for ; Wed, 7 Jun 2023 12:23:12 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q6sAf-0001sB-IY; Wed, 07 Jun 2023 08:21:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAc-0001rl-LO for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:21:46 -0400 Received: from mga06b.intel.com ([134.134.136.31] helo=mga06.intel.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAZ-0004hp-Q4 for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:21:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686140503; x=1717676503; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=B7l8tj5Rd30EkME/WBUkWnn0CUgSGdgmmYlbdGuWG2Q=; b=D5aHYsUYW0N2ZHSqrz4osf+yWHD8T8X0QHMIUlVno08ZDFA1TMZ2+/kB IV8HZ8wviZYB66IZ266UtR0jUJHKlBetfktsHeYk5INeMG8CZybRL3fsz sJajI7+hhwzw4OcYIRrpxbO9l0D6hKl+tyyCUBGVJGvcSbuV/J+oFP/xC h2MBlCPmSUGX9TmO9rvJs1m39NzQ5QPpZIEwp6Qd3XY0yfmQ3hU1AUXI2 GBJbUbQN5SfMGLm5WSPsOvgzs3Z0DIB9mpydaaEcdoTJDcvXuY4Vxkrlx TuLptNkFFYIDuO7Q9vgWs88yG4CNR8SuDGCEdMf5BRf54YJ6MAkfG2BqW Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="420527893" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="420527893" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Jun 2023 05:21:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="686969993" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="686969993" Received: from wufei-optiplex-7090.sh.intel.com ([10.238.200.247]) by orsmga006.jf.intel.com with ESMTP; 07 Jun 2023 05:21:36 -0700 From: Fei Wu To: richard.henderson@linaro.org, alex.bennee@linaro.org, qemu-devel@nongnu.org Cc: Fei Wu , "Vanderson M . do Rosario" , Paolo Bonzini , "Dr. David Alan Gilbert" , =?utf-8?q?Marc-Andr=C3=A9_Lure?= =?utf-8?q?au?= , =?utf-8?q?Daniel_P=2E_Berrang?= =?utf-8?q?=C3=A9?= , Thomas Huth , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Eduardo Habkost , Marcel Apfelbaum , Yanan Wang , Eric Blake , Markus Armbruster , Laurent Vivier Subject: [PATCH v15 01/10] accel/tcg: remove CONFIG_PROFILER Date: Wed, 7 Jun 2023 20:24:02 +0800 Message-Id: <20230607122411.3394702-2-fei2.wu@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230607122411.3394702-1-fei2.wu@intel.com> References: <20230607122411.3394702-1-fei2.wu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.31; envelope-from=fei2.wu@intel.com; helo=mga06.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org TBStats will be introduced to replace CONFIG_PROFILER totally, here remove all CONFIG_PROFILER related stuffs first. Signed-off-by: Vanderson M. do Rosario Signed-off-by: Alex Bennée Signed-off-by: Fei Wu Reviewed-by: Richard Henderson --- accel/tcg/monitor.c | 31 ----- accel/tcg/tcg-accel-ops.c | 10 -- accel/tcg/translate-all.c | 33 ------ hmp-commands-info.hx | 15 --- include/qemu/timer.h | 9 -- include/tcg/tcg.h | 26 ----- meson.build | 2 - meson_options.txt | 2 - qapi/machine.json | 18 --- scripts/meson-buildoptions.sh | 3 - softmmu/runstate.c | 9 -- tcg/tcg.c | 214 ---------------------------------- tests/qtest/qmp-cmd-test.c | 3 - 13 files changed, 375 deletions(-) diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c index 92fce580f1..39d8260428 100644 --- a/accel/tcg/monitor.c +++ b/accel/tcg/monitor.c @@ -80,37 +80,6 @@ HumanReadableText *qmp_x_query_opcount(Error **errp) return human_readable_text_from_str(buf); } -#ifdef CONFIG_PROFILER - -int64_t dev_time; - -HumanReadableText *qmp_x_query_profile(Error **errp) -{ - g_autoptr(GString) buf = g_string_new(""); - static int64_t last_cpu_exec_time; - int64_t cpu_exec_time; - int64_t delta; - - cpu_exec_time = tcg_cpu_exec_time(); - delta = cpu_exec_time - last_cpu_exec_time; - - g_string_append_printf(buf, "async time %" PRId64 " (%0.3f)\n", - dev_time, dev_time / (double)NANOSECONDS_PER_SECOND); - g_string_append_printf(buf, "qemu time %" PRId64 " (%0.3f)\n", - delta, delta / (double)NANOSECONDS_PER_SECOND); - last_cpu_exec_time = cpu_exec_time; - dev_time = 0; - - return human_readable_text_from_str(buf); -} -#else -HumanReadableText *qmp_x_query_profile(Error **errp) -{ - error_setg(errp, "Internal profiler not compiled"); - return NULL; -} -#endif - static void hmp_tcg_register(void) { monitor_register_hmp_info_hrt("jit", qmp_x_query_jit); diff --git a/accel/tcg/tcg-accel-ops.c b/accel/tcg/tcg-accel-ops.c index 58c8e64096..3973591508 100644 --- a/accel/tcg/tcg-accel-ops.c +++ b/accel/tcg/tcg-accel-ops.c @@ -70,20 +70,10 @@ void tcg_cpus_destroy(CPUState *cpu) int tcg_cpus_exec(CPUState *cpu) { int ret; -#ifdef CONFIG_PROFILER - int64_t ti; -#endif assert(tcg_enabled()); -#ifdef CONFIG_PROFILER - ti = profile_getclock(); -#endif cpu_exec_start(cpu); ret = cpu_exec(cpu); cpu_exec_end(cpu); -#ifdef CONFIG_PROFILER - qatomic_set(&tcg_ctx->prof.cpu_exec_time, - tcg_ctx->prof.cpu_exec_time + profile_getclock() - ti); -#endif return ret; } diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index c87648b99e..4e035e0f79 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -203,10 +203,6 @@ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, uintptr_t host_pc) { uint64_t data[TARGET_INSN_START_WORDS]; -#ifdef CONFIG_PROFILER - TCGProfile *prof = &tcg_ctx->prof; - int64_t ti = profile_getclock(); -#endif int insns_left = cpu_unwind_data_from_tb(tb, host_pc, data); if (insns_left < 0) { @@ -223,12 +219,6 @@ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, } cpu->cc->tcg_ops->restore_state_to_opc(cpu, tb, data); - -#ifdef CONFIG_PROFILER - qatomic_set(&prof->restore_time, - prof->restore_time + profile_getclock() - ti); - qatomic_set(&prof->restore_count, prof->restore_count + 1); -#endif } bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc) @@ -291,13 +281,6 @@ static int setjmp_gen_code(CPUArchState *env, TranslationBlock *tb, tcg_ctx->cpu = NULL; *max_insns = tb->icount; -#ifdef CONFIG_PROFILER - qatomic_set(&tcg_ctx->prof.tb_count, tcg_ctx->prof.tb_count + 1); - qatomic_set(&tcg_ctx->prof.interm_time, - tcg_ctx->prof.interm_time + profile_getclock() - *ti); - *ti = profile_getclock(); -#endif - return tcg_gen_code(tcg_ctx, tb, pc); } @@ -311,9 +294,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu, tb_page_addr_t phys_pc; tcg_insn_unit *gen_code_buf; int gen_code_size, search_size, max_insns; -#ifdef CONFIG_PROFILER - TCGProfile *prof = &tcg_ctx->prof; -#endif int64_t ti; void *host_pc; @@ -365,12 +345,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu, tb_overflow: -#ifdef CONFIG_PROFILER - /* includes aborted translations because of exceptions */ - qatomic_set(&prof->tb_count1, prof->tb_count1 + 1); - ti = profile_getclock(); -#endif - trace_translate_block(tb, pc, tb->tc.ptr); gen_code_size = setjmp_gen_code(env, tb, pc, host_pc, &max_insns, &ti); @@ -425,13 +399,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu, */ perf_report_code(pc, tb, tcg_splitwx_to_rx(gen_code_buf)); -#ifdef CONFIG_PROFILER - qatomic_set(&prof->code_time, prof->code_time + profile_getclock() - ti); - qatomic_set(&prof->code_in_len, prof->code_in_len + tb->size); - qatomic_set(&prof->code_out_len, prof->code_out_len + gen_code_size); - qatomic_set(&prof->search_out_len, prof->search_out_len + search_size); -#endif - if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) && qemu_log_in_addr_range(pc)) { FILE *logfile = qemu_log_trylock(); diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index 47d63d26db..f5b37eb74a 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -360,21 +360,6 @@ SRST Show host USB devices. ERST -#if defined(CONFIG_TCG) - { - .name = "profile", - .args_type = "", - .params = "", - .help = "show profiling information", - .cmd_info_hrt = qmp_x_query_profile, - }, -#endif - -SRST - ``info profile`` - Show profiling information. -ERST - { .name = "capture", .args_type = "", diff --git a/include/qemu/timer.h b/include/qemu/timer.h index ee071e07d1..9a91cb1248 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -989,13 +989,4 @@ static inline int64_t cpu_get_host_ticks(void) } #endif -#ifdef CONFIG_PROFILER -static inline int64_t profile_getclock(void) -{ - return get_clock(); -} - -extern int64_t dev_time; -#endif - #endif diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index 072c35f7f5..da1c8fa3b5 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -522,27 +522,6 @@ static inline TCGRegSet output_pref(const TCGOp *op, unsigned i) return i < ARRAY_SIZE(op->output_pref) ? op->output_pref[i] : 0; } -typedef struct TCGProfile { - int64_t cpu_exec_time; - int64_t tb_count1; - int64_t tb_count; - int64_t op_count; /* total insn count */ - int op_count_max; /* max insn per TB */ - int temp_count_max; - int64_t temp_count; - int64_t del_op_count; - int64_t code_in_len; - int64_t code_out_len; - int64_t search_out_len; - int64_t interm_time; - int64_t code_time; - int64_t la_time; - int64_t opt_time; - int64_t restore_count; - int64_t restore_time; - int64_t table_op_count[NB_OPS]; -} TCGProfile; - struct TCGContext { uint8_t *pool_cur, *pool_end; TCGPool *pool_first, *pool_current, *pool_first_large; @@ -569,10 +548,6 @@ struct TCGContext { tcg_insn_unit *code_buf; /* pointer for start of tb */ tcg_insn_unit *code_ptr; /* pointer for running end of tb */ -#ifdef CONFIG_PROFILER - TCGProfile prof; -#endif - #ifdef CONFIG_DEBUG_TCG int goto_tb_issue_mask; const TCGOpcode *vecop_list; @@ -910,7 +885,6 @@ static inline TCGv_ptr tcg_temp_new_ptr(void) return temp_tcgv_ptr(t); } -int64_t tcg_cpu_exec_time(void); void tcg_dump_info(GString *buf); void tcg_dump_op_count(GString *buf); diff --git a/meson.build b/meson.build index ef181ff2df..7da252cc81 100644 --- a/meson.build +++ b/meson.build @@ -2134,7 +2134,6 @@ if numa.found() dependencies: numa)) endif config_host_data.set('CONFIG_OPENGL', opengl.found()) -config_host_data.set('CONFIG_PROFILER', get_option('profiler')) config_host_data.set('CONFIG_RBD', rbd.found()) config_host_data.set('CONFIG_RDMA', rdma.found()) config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack')) @@ -4117,7 +4116,6 @@ if 'objc' in all_languages summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)} endif summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} -summary_info += {'profiler': get_option('profiler')} summary_info += {'link-time optimization (LTO)': get_option('b_lto')} summary_info += {'PIE': get_option('b_pie')} summary_info += {'static build': config_host.has_key('CONFIG_STATIC')} diff --git a/meson_options.txt b/meson_options.txt index 90237389e2..bbb5c7e886 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -345,8 +345,6 @@ option('qom_cast_debug', type: 'boolean', value: true, option('gprof', type: 'boolean', value: false, description: 'QEMU profiling with gprof', deprecated: true) -option('profiler', type: 'boolean', value: false, - description: 'profiler support') option('slirp_smbd', type : 'feature', value : 'auto', description: 'use smbd (at path --smbd=*) in slirp networking') diff --git a/qapi/machine.json b/qapi/machine.json index 37660d8f2a..a08b6576ca 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -1575,24 +1575,6 @@ 'if': 'CONFIG_TCG', 'features': [ 'unstable' ] } -## -# @x-query-profile: -# -# Query TCG profiling information -# -# Features: -# -# @unstable: This command is meant for debugging. -# -# Returns: profile information -# -# Since: 6.2 -## -{ 'command': 'x-query-profile', - 'returns': 'HumanReadableText', - 'if': 'CONFIG_TCG', - 'features': [ 'unstable' ] } - ## # @x-query-ramblock: # diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh index 5714fd93d9..7dd5709ef4 100644 --- a/scripts/meson-buildoptions.sh +++ b/scripts/meson-buildoptions.sh @@ -39,7 +39,6 @@ meson_options_help() { printf "%s\n" ' jemalloc/system/tcmalloc)' printf "%s\n" ' --enable-module-upgrades try to load modules from alternate paths for' printf "%s\n" ' upgrades' - printf "%s\n" ' --enable-profiler profiler support' printf "%s\n" ' --enable-rng-none dummy RNG, avoid using /dev/(u)random and' printf "%s\n" ' getrandom()' printf "%s\n" ' --enable-safe-stack SafeStack Stack Smash Protection (requires' @@ -401,8 +400,6 @@ _meson_option_parse() { --with-pkgversion=*) quote_sh "-Dpkgversion=$2" ;; --enable-png) printf "%s" -Dpng=enabled ;; --disable-png) printf "%s" -Dpng=disabled ;; - --enable-profiler) printf "%s" -Dprofiler=true ;; - --disable-profiler) printf "%s" -Dprofiler=false ;; --enable-pvrdma) printf "%s" -Dpvrdma=enabled ;; --disable-pvrdma) printf "%s" -Dpvrdma=disabled ;; --enable-qcow1) printf "%s" -Dqcow1=enabled ;; diff --git a/softmmu/runstate.c b/softmmu/runstate.c index 2f2396c819..bd50062ed0 100644 --- a/softmmu/runstate.c +++ b/softmmu/runstate.c @@ -728,18 +728,9 @@ static bool main_loop_should_exit(int *status) int qemu_main_loop(void) { int status = EXIT_SUCCESS; -#ifdef CONFIG_PROFILER - int64_t ti; -#endif while (!main_loop_should_exit(&status)) { -#ifdef CONFIG_PROFILER - ti = profile_getclock(); -#endif main_loop_wait(false); -#ifdef CONFIG_PROFILER - dev_time += profile_getclock() - ti; -#endif } return status; diff --git a/tcg/tcg.c b/tcg/tcg.c index ac30d484f5..4c569294db 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -2983,10 +2983,6 @@ void tcg_op_remove(TCGContext *s, TCGOp *op) QTAILQ_REMOVE(&s->ops, op, link); QTAILQ_INSERT_TAIL(&s->free_ops, op, link); s->nb_ops--; - -#ifdef CONFIG_PROFILER - qatomic_set(&s->prof.del_op_count, s->prof.del_op_count + 1); -#endif } void tcg_remove_ops_after(TCGOp *op) @@ -5856,143 +5852,16 @@ static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst, tcg_out_helper_load_common_args(s, ldst, parm, info, next_arg); } -#ifdef CONFIG_PROFILER - -/* avoid copy/paste errors */ -#define PROF_ADD(to, from, field) \ - do { \ - (to)->field += qatomic_read(&((from)->field)); \ - } while (0) - -#define PROF_MAX(to, from, field) \ - do { \ - typeof((from)->field) val__ = qatomic_read(&((from)->field)); \ - if (val__ > (to)->field) { \ - (to)->field = val__; \ - } \ - } while (0) - -/* Pass in a zero'ed @prof */ -static inline -void tcg_profile_snapshot(TCGProfile *prof, bool counters, bool table) -{ - unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs); - unsigned int i; - - for (i = 0; i < n_ctxs; i++) { - TCGContext *s = qatomic_read(&tcg_ctxs[i]); - const TCGProfile *orig = &s->prof; - - if (counters) { - PROF_ADD(prof, orig, cpu_exec_time); - PROF_ADD(prof, orig, tb_count1); - PROF_ADD(prof, orig, tb_count); - PROF_ADD(prof, orig, op_count); - PROF_MAX(prof, orig, op_count_max); - PROF_ADD(prof, orig, temp_count); - PROF_MAX(prof, orig, temp_count_max); - PROF_ADD(prof, orig, del_op_count); - PROF_ADD(prof, orig, code_in_len); - PROF_ADD(prof, orig, code_out_len); - PROF_ADD(prof, orig, search_out_len); - PROF_ADD(prof, orig, interm_time); - PROF_ADD(prof, orig, code_time); - PROF_ADD(prof, orig, la_time); - PROF_ADD(prof, orig, opt_time); - PROF_ADD(prof, orig, restore_count); - PROF_ADD(prof, orig, restore_time); - } - if (table) { - int i; - - for (i = 0; i < NB_OPS; i++) { - PROF_ADD(prof, orig, table_op_count[i]); - } - } - } -} - -#undef PROF_ADD -#undef PROF_MAX - -static void tcg_profile_snapshot_counters(TCGProfile *prof) -{ - tcg_profile_snapshot(prof, true, false); -} - -static void tcg_profile_snapshot_table(TCGProfile *prof) -{ - tcg_profile_snapshot(prof, false, true); -} - -void tcg_dump_op_count(GString *buf) -{ - TCGProfile prof = {}; - int i; - - tcg_profile_snapshot_table(&prof); - for (i = 0; i < NB_OPS; i++) { - g_string_append_printf(buf, "%s %" PRId64 "\n", tcg_op_defs[i].name, - prof.table_op_count[i]); - } -} - -int64_t tcg_cpu_exec_time(void) -{ - unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs); - unsigned int i; - int64_t ret = 0; - - for (i = 0; i < n_ctxs; i++) { - const TCGContext *s = qatomic_read(&tcg_ctxs[i]); - const TCGProfile *prof = &s->prof; - - ret += qatomic_read(&prof->cpu_exec_time); - } - return ret; -} -#else void tcg_dump_op_count(GString *buf) { g_string_append_printf(buf, "[TCG profiler not compiled]\n"); } -int64_t tcg_cpu_exec_time(void) -{ - error_report("%s: TCG profiler not compiled", __func__); - exit(EXIT_FAILURE); -} -#endif - - int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) { -#ifdef CONFIG_PROFILER - TCGProfile *prof = &s->prof; -#endif int i, num_insns; TCGOp *op; -#ifdef CONFIG_PROFILER - { - int n = 0; - - QTAILQ_FOREACH(op, &s->ops, link) { - n++; - } - qatomic_set(&prof->op_count, prof->op_count + n); - if (n > prof->op_count_max) { - qatomic_set(&prof->op_count_max, n); - } - - n = s->nb_temps; - qatomic_set(&prof->temp_count, prof->temp_count + n); - if (n > prof->temp_count_max) { - qatomic_set(&prof->temp_count_max, n); - } - } -#endif - if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP) && qemu_log_in_addr_range(pc_start))) { FILE *logfile = qemu_log_trylock(); @@ -6021,17 +5890,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) } #endif -#ifdef CONFIG_PROFILER - qatomic_set(&prof->opt_time, prof->opt_time - profile_getclock()); -#endif - tcg_optimize(s); -#ifdef CONFIG_PROFILER - qatomic_set(&prof->opt_time, prof->opt_time + profile_getclock()); - qatomic_set(&prof->la_time, prof->la_time - profile_getclock()); -#endif - reachable_code_pass(s); liveness_pass_0(s); liveness_pass_1(s); @@ -6055,10 +5915,6 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) } } -#ifdef CONFIG_PROFILER - qatomic_set(&prof->la_time, prof->la_time + profile_getclock()); -#endif - if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT) && qemu_log_in_addr_range(pc_start))) { FILE *logfile = qemu_log_trylock(); @@ -6097,10 +5953,6 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) QTAILQ_FOREACH(op, &s->ops, link) { TCGOpcode opc = op->opc; -#ifdef CONFIG_PROFILER - qatomic_set(&prof->table_op_count[opc], prof->table_op_count[opc] + 1); -#endif - switch (opc) { case INDEX_op_mov_i32: case INDEX_op_mov_i64: @@ -6195,76 +6047,10 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) return tcg_current_code_size(s); } -#ifdef CONFIG_PROFILER -void tcg_dump_info(GString *buf) -{ - TCGProfile prof = {}; - const TCGProfile *s; - int64_t tb_count; - int64_t tb_div_count; - int64_t tot; - - tcg_profile_snapshot_counters(&prof); - s = &prof; - tb_count = s->tb_count; - tb_div_count = tb_count ? tb_count : 1; - tot = s->interm_time + s->code_time; - - g_string_append_printf(buf, "JIT cycles %" PRId64 - " (%0.3f s at 2.4 GHz)\n", - tot, tot / 2.4e9); - g_string_append_printf(buf, "translated TBs %" PRId64 - " (aborted=%" PRId64 " %0.1f%%)\n", - tb_count, s->tb_count1 - tb_count, - (double)(s->tb_count1 - s->tb_count) - / (s->tb_count1 ? s->tb_count1 : 1) * 100.0); - g_string_append_printf(buf, "avg ops/TB %0.1f max=%d\n", - (double)s->op_count / tb_div_count, s->op_count_max); - g_string_append_printf(buf, "deleted ops/TB %0.2f\n", - (double)s->del_op_count / tb_div_count); - g_string_append_printf(buf, "avg temps/TB %0.2f max=%d\n", - (double)s->temp_count / tb_div_count, - s->temp_count_max); - g_string_append_printf(buf, "avg host code/TB %0.1f\n", - (double)s->code_out_len / tb_div_count); - g_string_append_printf(buf, "avg search data/TB %0.1f\n", - (double)s->search_out_len / tb_div_count); - - g_string_append_printf(buf, "cycles/op %0.1f\n", - s->op_count ? (double)tot / s->op_count : 0); - g_string_append_printf(buf, "cycles/in byte %0.1f\n", - s->code_in_len ? (double)tot / s->code_in_len : 0); - g_string_append_printf(buf, "cycles/out byte %0.1f\n", - s->code_out_len ? (double)tot / s->code_out_len : 0); - g_string_append_printf(buf, "cycles/search byte %0.1f\n", - s->search_out_len ? - (double)tot / s->search_out_len : 0); - if (tot == 0) { - tot = 1; - } - g_string_append_printf(buf, " gen_interm time %0.1f%%\n", - (double)s->interm_time / tot * 100.0); - g_string_append_printf(buf, " gen_code time %0.1f%%\n", - (double)s->code_time / tot * 100.0); - g_string_append_printf(buf, "optim./code time %0.1f%%\n", - (double)s->opt_time / (s->code_time ? - s->code_time : 1) - * 100.0); - g_string_append_printf(buf, "liveness/code time %0.1f%%\n", - (double)s->la_time / (s->code_time ? - s->code_time : 1) * 100.0); - g_string_append_printf(buf, "cpu_restore count %" PRId64 "\n", - s->restore_count); - g_string_append_printf(buf, " avg cycles %0.1f\n", - s->restore_count ? - (double)s->restore_time / s->restore_count : 0); -} -#else void tcg_dump_info(GString *buf) { g_string_append_printf(buf, "[TCG profiler not compiled]\n"); } -#endif #ifdef ELF_HOST_MACHINE /* In order to use this feature, the backend needs to do three things: diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c index a58de48d2a..73a670e8fa 100644 --- a/tests/qtest/qmp-cmd-test.c +++ b/tests/qtest/qmp-cmd-test.c @@ -46,9 +46,6 @@ static int query_error_class(const char *cmd) { "query-balloon", ERROR_CLASS_DEVICE_NOT_ACTIVE }, { "query-hotpluggable-cpus", ERROR_CLASS_GENERIC_ERROR }, { "query-vm-generation-id", ERROR_CLASS_GENERIC_ERROR }, -#ifndef CONFIG_PROFILER - { "x-query-profile", ERROR_CLASS_GENERIC_ERROR }, -#endif /* Only valid with a USB bus added */ { "x-query-usb", ERROR_CLASS_GENERIC_ERROR }, /* Only valid with accel=tcg */ From patchwork Wed Jun 7 12:24:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Wu, Fei" X-Patchwork-Id: 13270621 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C89F6C7EE2F for ; Wed, 7 Jun 2023 12:22:26 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q6sAh-0001t4-K1; Wed, 07 Jun 2023 08:21:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAf-0001sC-Ji for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:21:49 -0400 Received: from mga06b.intel.com ([134.134.136.31] helo=mga06.intel.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAb-0004k3-Is for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:21:47 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686140505; x=1717676505; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=d/odDr6kGhFRKQvMFhD7n3Tfn1yXekSykbxyn84UZd8=; b=EGL/WwiQYTjgx4LpmSRyoALIR400ZjxEWmrfzm+aoL43VSl8+kr7+CV5 Kvm8rccg/ssJYqcjFDuYd5SEAyyIpgcqGHKCLgA4LyLCvqVct8CEws6eW DsCpNX1ixHGG8G5om0h7iL1w3sXihHWPn7isoBTcyJwrZTLIdxkGGP9zM GVkYcAfbtjfP+dkxnXDLPwtPLRuG5zl/FZ1U9vaf83ysbellnZNUm0T6h E0BXCgf5n8ernucFELI3HKGUsjdPq416uCUlw6p/ZaNOPFbaLWP5ozRTv zaekAfFvf330IXxIFndjG3/sIc3aNPtsLbweqfLy4rQvo77zuiEotbH8H w==; X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="420527903" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="420527903" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Jun 2023 05:21:44 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="686970003" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="686970003" Received: from wufei-optiplex-7090.sh.intel.com ([10.238.200.247]) by orsmga006.jf.intel.com with ESMTP; 07 Jun 2023 05:21:42 -0700 From: Fei Wu To: richard.henderson@linaro.org, alex.bennee@linaro.org, qemu-devel@nongnu.org Cc: "Vanderson M. do Rosario" , Fei Wu , Paolo Bonzini Subject: [PATCH v15 02/10] accel/tcg: introduce TBStatistics structure Date: Wed, 7 Jun 2023 20:24:03 +0800 Message-Id: <20230607122411.3394702-3-fei2.wu@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230607122411.3394702-1-fei2.wu@intel.com> References: <20230607122411.3394702-1-fei2.wu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.31; envelope-from=fei2.wu@intel.com; helo=mga06.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: "Vanderson M. do Rosario" To store statistics for each TB, we created a TBStatistics structure which is linked with the TBs. TBStatistics can stay alive after tb_flush and be relinked to a regenerated TB. So the statistics can be accumulated even through flushes. The goal is to have all present and future qemu/tcg statistics and meta-data stored in this new structure. Reviewed-by: Alex Bennée Signed-off-by: Vanderson M. do Rosario Message-Id: <20190829173437.5926-2-vandersonmr2@gmail.com> [AJB: fix git author, review comments] Signed-off-by: Alex Bennée Signed-off-by: Fei Wu --- MAINTAINERS | 1 + accel/tcg/meson.build | 1 + accel/tcg/tb-context.h | 1 + accel/tcg/tb-hash.h | 7 +++++ accel/tcg/tb-maint.c | 19 ++++++++++++ accel/tcg/tb-stats.c | 46 ++++++++++++++++++++++++++++ accel/tcg/translate-all.c | 44 +++++++++++++++++++++++++++ include/exec/exec-all.h | 3 ++ include/exec/tb-stats-flags.h | 19 ++++++++++++ include/exec/tb-stats.h | 56 +++++++++++++++++++++++++++++++++++ 10 files changed, 197 insertions(+) create mode 100644 accel/tcg/tb-stats.c create mode 100644 include/exec/tb-stats-flags.h create mode 100644 include/exec/tb-stats.h diff --git a/MAINTAINERS b/MAINTAINERS index 1c93ab0ee5..2077889efd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -153,6 +153,7 @@ F: include/exec/cpu*.h F: include/exec/exec-all.h F: include/exec/tb-flush.h F: include/exec/target_long.h +F: include/exec/tb-stats*.h F: include/exec/helper*.h F: include/sysemu/cpus.h F: include/sysemu/tcg.h diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build index aeb20a6ef0..9263bdde11 100644 --- a/accel/tcg/meson.build +++ b/accel/tcg/meson.build @@ -4,6 +4,7 @@ tcg_ss.add(files( 'cpu-exec-common.c', 'cpu-exec.c', 'tb-maint.c', + 'tb-stats.c', 'tcg-runtime-gvec.c', 'tcg-runtime.c', 'translate-all.c', diff --git a/accel/tcg/tb-context.h b/accel/tcg/tb-context.h index cac62d9749..d7910d586b 100644 --- a/accel/tcg/tb-context.h +++ b/accel/tcg/tb-context.h @@ -35,6 +35,7 @@ struct TBContext { /* statistics */ unsigned tb_flush_count; unsigned tb_phys_invalidate_count; + struct qht tb_stats; }; extern TBContext tb_ctx; diff --git a/accel/tcg/tb-hash.h b/accel/tcg/tb-hash.h index 83dc610e4c..87d657a1c6 100644 --- a/accel/tcg/tb-hash.h +++ b/accel/tcg/tb-hash.h @@ -67,4 +67,11 @@ uint32_t tb_hash_func(tb_page_addr_t phys_pc, target_ulong pc, uint32_t flags, return qemu_xxhash7(phys_pc, pc, flags, cf_mask, trace_vcpu_dstate); } +static inline +uint32_t tb_stats_hash_func(tb_page_addr_t phys_pc, target_ulong pc, + uint32_t flags) +{ + return qemu_xxhash5(phys_pc, pc, flags); +} + #endif diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index 991746f80f..0980fca358 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -24,6 +24,7 @@ #include "exec/log.h" #include "exec/exec-all.h" #include "exec/tb-flush.h" +#include "exec/tb-stats.h" #include "exec/translate-all.h" #include "sysemu/tcg.h" #include "tcg/tcg.h" @@ -41,6 +42,23 @@ #define TB_FOR_EACH_JMP(head_tb, tb, n) \ TB_FOR_EACH_TAGGED((head_tb)->jmp_list_head, tb, n, jmp_list_next) +/* + * This is the more or less the same compare as tb_cmp(), but the + * data persists over tb_flush. We also aggregate the various + * variations of cflags under one record and ignore the details of + * page overlap (although we can count it). + */ +bool tb_stats_cmp(const void *ap, const void *bp) +{ + const TBStatistics *a = ap; + const TBStatistics *b = bp; + + return a->phys_pc == b->phys_pc && + a->pc == b->pc && + a->cs_base == b->cs_base && + a->flags == b->flags; +} + static bool tb_cmp(const void *ap, const void *bp) { const TranslationBlock *a = ap; @@ -60,6 +78,7 @@ void tb_htable_init(void) unsigned int mode = QHT_MODE_AUTO_RESIZE; qht_init(&tb_ctx.htable, tb_cmp, CODE_GEN_HTABLE_SIZE, mode); + init_tb_stats_htable(); } typedef struct PageDesc PageDesc; diff --git a/accel/tcg/tb-stats.c b/accel/tcg/tb-stats.c new file mode 100644 index 0000000000..2b6be943ef --- /dev/null +++ b/accel/tcg/tb-stats.c @@ -0,0 +1,46 @@ +/* + * QEMU System Emulator, Code Quality Monitor System + * + * Copyright (c) 2019 Vanderson M. do Rosario + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" + +#include "disas/disas.h" + +#include "exec/tb-stats.h" +#include "tb-context.h" + +/* TBStatistic collection controls */ +enum TBStatsStatus { + TB_STATS_STOPPED = 0, + TB_STATS_RUNNING +}; + +static enum TBStatsStatus tcg_collect_tb_stats; + +void init_tb_stats_htable(void) +{ + if (!tb_ctx.tb_stats.map && tb_stats_collection_enabled()) { + qht_init(&tb_ctx.tb_stats, tb_stats_cmp, + CODE_GEN_HTABLE_SIZE, QHT_MODE_AUTO_RESIZE); + } +} + +void enable_collect_tb_stats(void) +{ + tcg_collect_tb_stats = TB_STATS_RUNNING; + init_tb_stats_htable(); +} + +void disable_collect_tb_stats(void) +{ + tcg_collect_tb_stats = TB_STATS_STOPPED; +} + +bool tb_stats_collection_enabled(void) +{ + return tcg_collect_tb_stats == TB_STATS_RUNNING; +} diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 4e035e0f79..4fc41a63b5 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -54,6 +54,7 @@ #include "qemu/cacheinfo.h" #include "qemu/timer.h" #include "exec/log.h" +#include "exec/tb-stats.h" #include "sysemu/cpus.h" #include "sysemu/cpu-timers.h" #include "sysemu/tcg.h" @@ -284,6 +285,37 @@ static int setjmp_gen_code(CPUArchState *env, TranslationBlock *tb, return tcg_gen_code(tcg_ctx, tb, pc); } +static TBStatistics *tb_get_stats(tb_page_addr_t phys_pc, target_ulong pc, + target_ulong cs_base, uint32_t flags) +{ + TBStatistics *new_stats = g_new0(TBStatistics, 1); + uint32_t hash = tb_stats_hash_func(phys_pc, pc, flags); + void *existing_stats = NULL; + new_stats->phys_pc = phys_pc; + new_stats->pc = pc; + new_stats->cs_base = cs_base; + new_stats->flags = flags; + + /* + * All initialisation must be complete before we insert into qht + * table otherwise another thread might get a partially created + * structure. + */ + qht_insert(&tb_ctx.tb_stats, new_stats, hash, &existing_stats); + + if (unlikely(existing_stats)) { + /* + * If there is already a TBStatistic for this TB from a previous flush + * then just make the new TB point to the older TBStatistic + */ + g_free(new_stats); + return existing_stats; + } else { + return new_stats; + } +} + + /* Called with mmap_lock held for user mode emulation. */ TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc, target_ulong cs_base, @@ -347,6 +379,18 @@ TranslationBlock *tb_gen_code(CPUState *cpu, trace_translate_block(tb, pc, tb->tc.ptr); + /* + * We want to fetch the stats structure before we start code + * generation so we can count interesting things about this + * generation. + */ + if (tb_stats_collection_enabled()) { + tb->tb_stats = tb_get_stats(phys_pc, cflags & CF_PCREL ? 0 : pc, + cs_base, flags); + } else { + tb->tb_stats = NULL; + } + gen_code_size = setjmp_gen_code(env, tb, pc, host_pc, &max_insns, &ti); if (unlikely(gen_code_size < 0)) { switch (gen_code_size) { diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 4d2b151986..f8a80f63d3 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -608,6 +608,9 @@ struct TranslationBlock { uintptr_t jmp_list_head; uintptr_t jmp_list_next[2]; uintptr_t jmp_dest[2]; + + /* Pointer to a struct where statistics from the TB is stored */ + struct TBStatistics *tb_stats; }; /* Hide the qatomic_read to make code a little easier on the eyes */ diff --git a/include/exec/tb-stats-flags.h b/include/exec/tb-stats-flags.h new file mode 100644 index 0000000000..c994cf3b9d --- /dev/null +++ b/include/exec/tb-stats-flags.h @@ -0,0 +1,19 @@ +/* + * QEMU System Emulator, Code Quality Monitor System + * + * We define the flags and control bits here to avoid complications of + * including TCG/CPU information in common code. + * + * Copyright (c) 2019 Vanderson M. do Rosario + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef TB_STATS_FLAGS +#define TB_STATS_FLAGS + +/* TBStatistic collection controls */ +void enable_collect_tb_stats(void); +void disable_collect_tb_stats(void); +bool tb_stats_collection_enabled(void); + +#endif diff --git a/include/exec/tb-stats.h b/include/exec/tb-stats.h new file mode 100644 index 0000000000..b519465665 --- /dev/null +++ b/include/exec/tb-stats.h @@ -0,0 +1,56 @@ +/* + * QEMU System Emulator, Code Quality Monitor System + * + * Copyright (c) 2019 Vanderson M. do Rosario + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef TB_STATS_H + +#define TB_STATS_H + +#include "exec/cpu-common.h" +#include "exec/exec-all.h" +#include "exec/tb-stats-flags.h" +#include "tcg/tcg.h" + +typedef struct TBStatistics TBStatistics; + +/* + * This struct stores statistics such as execution count of the + * TranslationBlocks. Each sets of TBs for a given phys_pc/pc/flags + * has its own TBStatistics which will persist over tb_flush. + * + * We include additional counters to track number of translations as + * well as variants for compile flags. + */ +struct TBStatistics { + tb_page_addr_t phys_pc; + target_ulong pc; + uint32_t flags; + /* cs_base isn't included in the hash but we do check for matches */ + target_ulong cs_base; +}; + +bool tb_stats_cmp(const void *ap, const void *bp); + +void init_tb_stats_htable(void); + +#endif From patchwork Wed Jun 7 12:24:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Wu, Fei" X-Patchwork-Id: 13270619 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5E7DEC7EE25 for ; Wed, 7 Jun 2023 12:22:24 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q6sAk-0001tl-W8; Wed, 07 Jun 2023 08:21:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAg-0001su-SV for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:21:50 -0400 Received: from mga06b.intel.com ([134.134.136.31] helo=mga06.intel.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAd-0004hp-IZ for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:21:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686140507; x=1717676507; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=22bPqZniORfbwP80DXRIlKxrommfl/Onji2JNX5oNKo=; b=bqMEqhpJzbkeFjah6TJondKwoP4DuEXBFT/soSJBuZbiaBzuOhWz0i/t 9iHdSo2u52SLC7VRDHgaPxRsOAGfoNklI5X1EsrWxpsW8miW2XD5bKeHw bIuE4JJFfRHZqaidIdsq3MmJiF8PV03p+FUUwh6oBlbN7tQEGF9V16coi WMfJ+Mlznn7maloj3RASU9oZriM+4GgoxoaxeDRIDAxTS9cRho7gdW+6s WZPh+ic4wkrAzbSF2Wsvx4dwiaqF2yxGGy1x2Cj//vTsZxY9QnrYXPw9w ZB5ZRqUTgGlT3yAd4RN7DHJTkLJcrdKtteveZ3f5aYGNr/sjBZ+ifzuMq g==; X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="420527913" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="420527913" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Jun 2023 05:21:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="686970017" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="686970017" Received: from wufei-optiplex-7090.sh.intel.com ([10.238.200.247]) by orsmga006.jf.intel.com with ESMTP; 07 Jun 2023 05:21:44 -0700 From: Fei Wu To: richard.henderson@linaro.org, alex.bennee@linaro.org, qemu-devel@nongnu.org Cc: "Vanderson M. do Rosario" , Fei Wu , Paolo Bonzini Subject: [PATCH v15 03/10] accel: collecting TB execution count Date: Wed, 7 Jun 2023 20:24:04 +0800 Message-Id: <20230607122411.3394702-4-fei2.wu@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230607122411.3394702-1-fei2.wu@intel.com> References: <20230607122411.3394702-1-fei2.wu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.31; envelope-from=fei2.wu@intel.com; helo=mga06.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: "Vanderson M. do Rosario" If a TB has a TBS (TBStatistics) with the TB_EXEC_STATS enabled, then we instrument the start code of this TB to atomically count the number of times it is executed. We count both the number of "normal" executions and atomic executions of a TB. The execution count of the TB is stored in its respective TBS. All TBStatistics are created by default with the flags from default_tbstats_flag. [Richard Henderson created the inline gen_tb_exec_count] Signed-off-by: Vanderson M. do Rosario Message-Id: <20190829173437.5926-3-vandersonmr2@gmail.com> [AJB: Fix author] Signed-off-by: Alex Bennée Signed-off-by: Fei Wu --- accel/tcg/cpu-exec.c | 6 ++++++ accel/tcg/tb-stats.c | 18 ++++++++++++++++++ accel/tcg/tcg-runtime.c | 1 + accel/tcg/translate-all.c | 6 ++++-- accel/tcg/translator.c | 25 +++++++++++++++++++++++++ include/exec/gen-icount.h | 1 + include/exec/tb-stats-flags.h | 6 ++++++ include/exec/tb-stats.h | 8 ++++++++ 8 files changed, 69 insertions(+), 2 deletions(-) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 0e741960da..c0d8f26237 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -25,6 +25,7 @@ #include "trace.h" #include "disas/disas.h" #include "exec/exec-all.h" +#include "exec/tb-stats.h" #include "tcg/tcg.h" #include "qemu/atomic.h" #include "qemu/rcu.h" @@ -562,7 +563,12 @@ void cpu_exec_step_atomic(CPUState *cpu) mmap_unlock(); } + if (tb_stats_enabled(tb, TB_EXEC_STATS)) { + tb->tb_stats->executions.atomic++; + } + cpu_exec_enter(cpu); + /* execute the generated code */ trace_exec_tb(tb, pc); cpu_tb_exec(cpu, tb, &tb_exit); diff --git a/accel/tcg/tb-stats.c b/accel/tcg/tb-stats.c index 2b6be943ef..2b7321b548 100644 --- a/accel/tcg/tb-stats.c +++ b/accel/tcg/tb-stats.c @@ -20,6 +20,7 @@ enum TBStatsStatus { }; static enum TBStatsStatus tcg_collect_tb_stats; +static uint32_t tbstats_flag; void init_tb_stats_htable(void) { @@ -44,3 +45,20 @@ bool tb_stats_collection_enabled(void) { return tcg_collect_tb_stats == TB_STATS_RUNNING; } + +uint32_t get_tbstats_flag(void) +{ + return tbstats_flag; +} + +void set_tbstats_flag(uint32_t flag) +{ + tbstats_flag = flag; +} + +bool tb_stats_enabled(TranslationBlock *tb, uint32_t flag) +{ + return tb_stats_collection_enabled() && + tb->tb_stats && + (tbstats_flag & flag); +} diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c index e4e030043f..11c6192064 100644 --- a/accel/tcg/tcg-runtime.c +++ b/accel/tcg/tcg-runtime.c @@ -27,6 +27,7 @@ #include "exec/helper-proto.h" #include "exec/cpu_ldst.h" #include "exec/exec-all.h" +#include "exec/tb-stats.h" #include "disas/disas.h" #include "exec/log.h" #include "tcg/tcg.h" diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 4fc41a63b5..5963cd6fe4 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -382,9 +382,11 @@ TranslationBlock *tb_gen_code(CPUState *cpu, /* * We want to fetch the stats structure before we start code * generation so we can count interesting things about this - * generation. + * generation. If dfilter is in effect we will only collect stats + * for the specified range. */ - if (tb_stats_collection_enabled()) { + if (tb_stats_collection_enabled() && + qemu_log_in_addr_range(tb->pc)) { tb->tb_stats = tb_get_stats(phys_pc, cflags & CF_PCREL ? 0 : pc, cs_base, flags); } else { diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index 6120ef2a92..80ffbfb455 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -11,6 +11,7 @@ #include "qemu/error-report.h" #include "tcg/tcg.h" #include "tcg/tcg-op.h" +#include "tcg/tcg-temp-internal.h" #include "exec/exec-all.h" #include "exec/gen-icount.h" #include "exec/log.h" @@ -18,6 +19,29 @@ #include "exec/plugin-gen.h" #include "exec/replay-core.h" +static void gen_tb_exec_count(TranslationBlock *tb) +{ + if (tb_stats_enabled(tb, TB_EXEC_STATS)) { + TCGv_ptr ptr = tcg_temp_ebb_new_ptr(); + + tcg_gen_movi_ptr(ptr, (intptr_t)&tb->tb_stats->executions.normal); + if (sizeof(tb->tb_stats->executions.normal) == 4) { + TCGv_i32 t = tcg_temp_ebb_new_i32(); + tcg_gen_ld_i32(t, ptr, 0); + tcg_gen_addi_i32(t, t, 1); + tcg_gen_st_i32(t, ptr, 0); + tcg_temp_free_i32(t); + } else { + TCGv_i64 t = tcg_temp_ebb_new_i64(); + tcg_gen_ld_i64(t, ptr, 0); + tcg_gen_addi_i64(t, t, 1); + tcg_gen_st_i64(t, ptr, 0); + tcg_temp_free_i64(t); + } + tcg_temp_free_ptr(ptr); + } +} + bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest) { /* Suppress goto_tb if requested. */ @@ -56,6 +80,7 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns, /* Start translating. */ gen_tb_start(db->tb); + gen_tb_exec_count(tb); ops->tb_start(db, cpu); tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */ diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h index f6de79a6b4..20e7835ff0 100644 --- a/include/exec/gen-icount.h +++ b/include/exec/gen-icount.h @@ -2,6 +2,7 @@ #define GEN_ICOUNT_H #include "exec/exec-all.h" +#include "exec/tb-stats.h" /* Helpers for instruction counting code generation. */ diff --git a/include/exec/tb-stats-flags.h b/include/exec/tb-stats-flags.h index c994cf3b9d..c0e63408e2 100644 --- a/include/exec/tb-stats-flags.h +++ b/include/exec/tb-stats-flags.h @@ -11,9 +11,15 @@ #ifndef TB_STATS_FLAGS #define TB_STATS_FLAGS +#define TB_NONE_STATS (0) /* no stats */ +#define TB_EXEC_STATS (1 << 0) + /* TBStatistic collection controls */ void enable_collect_tb_stats(void); void disable_collect_tb_stats(void); bool tb_stats_collection_enabled(void); +uint32_t get_tbstats_flag(void); +void set_tbstats_flag(uint32_t flag); + #endif diff --git a/include/exec/tb-stats.h b/include/exec/tb-stats.h index b519465665..b935c3235a 100644 --- a/include/exec/tb-stats.h +++ b/include/exec/tb-stats.h @@ -47,10 +47,18 @@ struct TBStatistics { uint32_t flags; /* cs_base isn't included in the hash but we do check for matches */ target_ulong cs_base; + + /* Execution stats */ + struct { + unsigned long normal; + unsigned long atomic; + } executions; + }; bool tb_stats_cmp(const void *ap, const void *bp); void init_tb_stats_htable(void); +bool tb_stats_enabled(TranslationBlock *tb, uint32_t flag); #endif From patchwork Wed Jun 7 12:24:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Wu, Fei" X-Patchwork-Id: 13270624 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0D539C7EE23 for ; Wed, 7 Jun 2023 12:23:14 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q6sAq-0001wj-CH; Wed, 07 Jun 2023 08:22:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAi-0001tH-Fk for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:21:52 -0400 Received: from mga06b.intel.com ([134.134.136.31] helo=mga06.intel.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAf-0004k3-V9 for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:21:52 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686140509; x=1717676509; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EXwqY/9xp7lwt+xAEBiG6i2DgGLdfGQQo76Tvw/fVXw=; b=m7UOp8sTdEfesPgqh70V5glnjGKnSUk94v2CeZdVvGHIbPQetYmHXMtB dpbkYxyk9I7QKVtyDbPm6yjkTGmXk2c61Ld+VjNZtps8aLFZQL36dHNBa LyYYMg92ZRJLhAygvhZfHlgkx+shAPBRXBz7AzPkGFwXMcJEg9CsiFJvc ugsjafi4GCEbjHNJTk8NNfKzXFYR6K5XYdGcr9rRQeTQgfNp7MT7KGj8a sIX3MAJ3TtXTkg6X5zG0ajXpakBLmYMpTwAOw30jQG6UVjhVzE+2xaeYj Rw5c/hHEoCOjFEgsyra+wDUCdJ9+GeOJ5dg5nk0UsKHk3mf547tH6qcIJ Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="420527918" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="420527918" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Jun 2023 05:21:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="686970028" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="686970028" Received: from wufei-optiplex-7090.sh.intel.com ([10.238.200.247]) by orsmga006.jf.intel.com with ESMTP; 07 Jun 2023 05:21:47 -0700 From: Fei Wu To: richard.henderson@linaro.org, alex.bennee@linaro.org, qemu-devel@nongnu.org Cc: Fei Wu , "Vanderson M . do Rosario" , Paolo Bonzini Subject: [PATCH v15 04/10] accel/tcg: add jit stats to TBStatistics Date: Wed, 7 Jun 2023 20:24:05 +0800 Message-Id: <20230607122411.3394702-5-fei2.wu@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230607122411.3394702-1-fei2.wu@intel.com> References: <20230607122411.3394702-1-fei2.wu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.31; envelope-from=fei2.wu@intel.com; helo=mga06.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This collects all the statistics for TBStatistics, not only for the whole emulation but for each TB. Signed-off-by: Vanderson M. do Rosario Signed-off-by: Alex Bennée Signed-off-by: Fei Wu --- accel/tcg/monitor.c | 6 +++ accel/tcg/tb-stats.c | 69 +++++++++++++++++++++++++++++++++++ accel/tcg/translate-all.c | 31 ++++++++++++++-- accel/tcg/translator.c | 5 +++ include/exec/tb-stats-flags.h | 1 + include/exec/tb-stats.h | 29 +++++++++++++++ include/tcg/tcg.h | 10 +++++ tcg/tcg.c | 47 ++++++++++++++++++++++-- 8 files changed, 192 insertions(+), 6 deletions(-) diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c index 39d8260428..111ccbc4da 100644 --- a/accel/tcg/monitor.c +++ b/accel/tcg/monitor.c @@ -15,6 +15,7 @@ #include "sysemu/cpus.h" #include "sysemu/cpu-timers.h" #include "sysemu/tcg.h" +#include "exec/tb-stats.h" #include "internal.h" @@ -69,6 +70,11 @@ HumanReadableText *qmp_x_query_opcount(Error **errp) { g_autoptr(GString) buf = g_string_new(""); + if (!tb_stats_collection_enabled()) { + error_setg(errp, "TB information not being recorded"); + return NULL; + } + if (!tcg_enabled()) { error_setg(errp, "Opcode count information is only available with accel=tcg"); diff --git a/accel/tcg/tb-stats.c b/accel/tcg/tb-stats.c index 2b7321b548..11322359c7 100644 --- a/accel/tcg/tb-stats.c +++ b/accel/tcg/tb-stats.c @@ -9,6 +9,10 @@ #include "qemu/osdep.h" #include "disas/disas.h" +#include "exec/exec-all.h" +#include "tcg/tcg.h" + +#include "qemu/qemu-print.h" #include "exec/tb-stats.h" #include "tb-context.h" @@ -22,6 +26,71 @@ enum TBStatsStatus { static enum TBStatsStatus tcg_collect_tb_stats; static uint32_t tbstats_flag; +struct jit_profile_info { + uint64_t translations; + uint64_t aborted; + uint64_t ops; + unsigned ops_max; + uint64_t del_ops; + uint64_t temps; + unsigned temps_max; + uint64_t host; + uint64_t guest; + uint64_t search_data; +}; + +#define stat_per_translation(stat, name) \ + (stat->translations.total ? stat->name / stat->translations.total : 0) + +/* accumulate the statistics from all TBs */ +static void collect_jit_profile_info(void *p, uint32_t hash, void *userp) +{ + struct jit_profile_info *jpi = userp; + TBStatistics *tbs = p; + + jpi->translations += tbs->translations.total; + jpi->ops += tbs->code.num_tcg_ops; + if (stat_per_translation(tbs, code.num_tcg_ops) > jpi->ops_max) { + jpi->ops_max = stat_per_translation(tbs, code.num_tcg_ops); + } + jpi->del_ops += tbs->code.deleted_ops; + jpi->temps += tbs->code.temps; + if (stat_per_translation(tbs, code.temps) > jpi->temps_max) { + jpi->temps_max = stat_per_translation(tbs, code.temps); + } + jpi->host += tbs->code.out_len; + jpi->guest += tbs->code.in_len; + jpi->search_data += tbs->code.search_out_len; +} + +/* dump JIT statistics using TBStats */ +void dump_jit_profile_info(GString *buf) +{ + if (!tb_stats_collection_enabled()) { + return; + } + + struct jit_profile_info *jpi = g_new0(struct jit_profile_info, 1); + + qht_iter(&tb_ctx.tb_stats, collect_jit_profile_info, jpi); + + if (jpi->translations) { + g_string_append_printf(buf, "translated TBs %" PRId64 "\n", + jpi->translations); + g_string_append_printf(buf, "avg ops/TB %0.1f max=%d\n", + jpi->ops / (double) jpi->translations, jpi->ops_max); + g_string_append_printf(buf, "deleted ops/TB %0.2f\n", + jpi->del_ops / (double) jpi->translations); + g_string_append_printf(buf, "avg temps/TB %0.2f max=%d\n", + jpi->temps / (double) jpi->translations, jpi->temps_max); + g_string_append_printf(buf, "avg host code/TB %0.1f\n", + jpi->host / (double) jpi->translations); + g_string_append_printf(buf, "avg search data/TB %0.1f\n", + jpi->search_data / (double) jpi->translations); + } + g_free(jpi); +} + void init_tb_stats_htable(void) { if (!tb_ctx.tb_stats.map && tb_stats_collection_enabled()) { diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 5963cd6fe4..f795385aac 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -267,7 +267,7 @@ void page_init(void) */ static int setjmp_gen_code(CPUArchState *env, TranslationBlock *tb, target_ulong pc, void *host_pc, - int *max_insns, int64_t *ti) + int *max_insns) { int ret = sigsetjmp(tcg_ctx->jmp_trans, 0); if (unlikely(ret != 0)) { @@ -295,6 +295,8 @@ static TBStatistics *tb_get_stats(tb_page_addr_t phys_pc, target_ulong pc, new_stats->pc = pc; new_stats->cs_base = cs_base; new_stats->flags = flags; + new_stats->tbs = g_ptr_array_new(); + qemu_mutex_init(&new_stats->jit_stats_lock); /* * All initialisation must be complete before we insert into qht @@ -308,6 +310,7 @@ static TBStatistics *tb_get_stats(tb_page_addr_t phys_pc, target_ulong pc, * If there is already a TBStatistic for this TB from a previous flush * then just make the new TB point to the older TBStatistic */ + g_ptr_array_free(new_stats->tbs, true); g_free(new_stats); return existing_stats; } else { @@ -326,7 +329,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu, tb_page_addr_t phys_pc; tcg_insn_unit *gen_code_buf; int gen_code_size, search_size, max_insns; - int64_t ti; void *host_pc; assert_memory_lock(); @@ -393,7 +395,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, tb->tb_stats = NULL; } - gen_code_size = setjmp_gen_code(env, tb, pc, host_pc, &max_insns, &ti); + gen_code_size = setjmp_gen_code(env, tb, pc, host_pc, &max_insns); if (unlikely(gen_code_size < 0)) { switch (gen_code_size) { case -1: @@ -547,6 +549,29 @@ TranslationBlock *tb_gen_code(CPUState *cpu, return tb; } + /* + * Collect JIT stats when enabled. We batch them all up here to + * avoid spamming the cache with atomic accesses + */ + if (tb_stats_enabled(tb, TB_JIT_STATS)) { + TBStatistics *ts = tb->tb_stats; + qemu_mutex_lock(&ts->jit_stats_lock); + + ts->code.num_tcg_ops_opt += tcg_ctx->nb_ops; + ts->code.in_len += tb->size; + ts->code.out_len += tb->tc.size; + ts->code.search_out_len += search_size; + + ts->translations.total++; + if (tb_page_addr1(tb) != -1) { + ts->translations.spanning++; + } + + g_ptr_array_add(ts->tbs, tb); + + qemu_mutex_unlock(&ts->jit_stats_lock); + } + /* * Insert TB into the corresponding region tree before publishing it * through QHT. Otherwise rewinding happened in the TB might fail to diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index 80ffbfb455..2fcd8bba35 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -147,6 +147,11 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns, tb->size = db->pc_next - db->pc_first; tb->icount = db->num_insns; + /* Save number of guest instructions for TB_JIT_STATS */ + if (tb_stats_enabled(tb, TB_JIT_STATS)) { + tb->tb_stats->code.num_guest_inst += db->num_insns; + } + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(db->pc_first)) { FILE *logfile = qemu_log_trylock(); diff --git a/include/exec/tb-stats-flags.h b/include/exec/tb-stats-flags.h index c0e63408e2..286ca93bcc 100644 --- a/include/exec/tb-stats-flags.h +++ b/include/exec/tb-stats-flags.h @@ -13,6 +13,7 @@ #define TB_NONE_STATS (0) /* no stats */ #define TB_EXEC_STATS (1 << 0) +#define TB_JIT_STATS (1 << 1) /* TBStatistic collection controls */ void enable_collect_tb_stats(void); diff --git a/include/exec/tb-stats.h b/include/exec/tb-stats.h index b935c3235a..6ed767f490 100644 --- a/include/exec/tb-stats.h +++ b/include/exec/tb-stats.h @@ -54,6 +54,33 @@ struct TBStatistics { unsigned long atomic; } executions; + /* JIT Stats - protected by lock */ + QemuMutex jit_stats_lock; + + /* Sum of all operations for all translations */ + struct { + unsigned num_guest_inst; + unsigned num_tcg_ops; + unsigned num_tcg_ops_opt; + unsigned spills; + + unsigned temps; + unsigned deleted_ops; + unsigned in_len; + unsigned out_len; + unsigned search_out_len; + } code; + + struct { + unsigned long total; + unsigned long spanning; + } translations; + + /* + * All persistent (cached) TranslationBlocks using + * this TBStats structure. Has to be reset on a tb_flush. + */ + GPtrArray *tbs; }; bool tb_stats_cmp(const void *ap, const void *bp); @@ -61,4 +88,6 @@ bool tb_stats_cmp(const void *ap, const void *bp); void init_tb_stats_htable(void); bool tb_stats_enabled(TranslationBlock *tb, uint32_t flag); +void dump_jit_profile_info(GString *buf); + #endif diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index da1c8fa3b5..276a4b60ad 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -522,6 +522,14 @@ static inline TCGRegSet output_pref(const TCGOp *op, unsigned i) return i < ARRAY_SIZE(op->output_pref) ? op->output_pref[i] : 0; } +/* + * The TCGProfile structure holds data for the lifetime of the translator. + */ +typedef struct TCGProfile { + /* Lifetime count of TCGOps per TCGContext when tb_stats enabled */ + size_t table_op_count[NB_OPS]; +} TCGProfile; + struct TCGContext { uint8_t *pool_cur, *pool_end; TCGPool *pool_first, *pool_current, *pool_first_large; @@ -548,6 +556,8 @@ struct TCGContext { tcg_insn_unit *code_buf; /* pointer for start of tb */ tcg_insn_unit *code_ptr; /* pointer for running end of tb */ + TCGProfile prof; + #ifdef CONFIG_DEBUG_TCG int goto_tb_issue_mask; const TCGOpcode *vecop_list; diff --git a/tcg/tcg.c b/tcg/tcg.c index 4c569294db..e8c354e2f9 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -41,6 +41,7 @@ #define NO_CPU_IO_DEFS #include "exec/exec-all.h" +#include "exec/tb-stats.h" #include "tcg/tcg-op.h" #if UINTPTR_MAX == UINT32_MAX @@ -2983,6 +2984,9 @@ void tcg_op_remove(TCGContext *s, TCGOp *op) QTAILQ_REMOVE(&s->ops, op, link); QTAILQ_INSERT_TAIL(&s->free_ops, op, link); s->nb_ops--; + if (tb_stats_enabled(s->gen_tb, TB_JIT_STATS)) { + s->gen_tb->tb_stats->code.deleted_ops++; + } } void tcg_remove_ops_after(TCGOp *op) @@ -4148,6 +4152,10 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet required_regs, } /* We must spill something. */ + if (tb_stats_enabled(s->gen_tb, TB_JIT_STATS)) { + s->gen_tb->tb_stats->code.spills++; + } + for (j = f; j < 2; j++) { TCGRegSet set = reg_ct[j]; @@ -5852,9 +5860,17 @@ static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst, tcg_out_helper_load_common_args(s, ldst, parm, info, next_arg); } -void tcg_dump_op_count(GString *buf) +static void collect_tcg_profiler(TCGProfile *prof) { - g_string_append_printf(buf, "[TCG profiler not compiled]\n"); + unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs); + unsigned int i; + + for (i = 0; i < n_ctxs; i++) { + TCGContext *s = qatomic_read(&tcg_ctxs[i]); + for (i = 0; i < NB_OPS; i++) { + prof->table_op_count[i] += s->prof.table_op_count[i]; + } + } } int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) @@ -5862,6 +5878,12 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) int i, num_insns; TCGOp *op; + /* save pre-optimisation op count */ + if (tb_stats_enabled(tb, TB_JIT_STATS)) { + tb->tb_stats->code.num_tcg_ops += s->nb_ops; + tb->tb_stats->code.temps += s->nb_temps; + } + if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP) && qemu_log_in_addr_range(pc_start))) { FILE *logfile = qemu_log_trylock(); @@ -5949,6 +5971,13 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) s->pool_labels = NULL; #endif + if (tb_stats_collection_enabled()) { + QTAILQ_FOREACH(op, &s->ops, link) { + TCGOpcode opc = op->opc; + s->prof.table_op_count[opc]++; + } + } + num_insns = -1; QTAILQ_FOREACH(op, &s->ops, link) { TCGOpcode opc = op->opc; @@ -6047,9 +6076,21 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) return tcg_current_code_size(s); } +void tcg_dump_op_count(GString *buf) +{ + TCGProfile prof = {}; + int i; + + collect_tcg_profiler(&prof); + for (i = 0; i < NB_OPS; i++) { + g_string_append_printf(buf, "%s %" PRId64 "\n", + tcg_op_defs[i].name, prof.table_op_count[i]); + } +} + void tcg_dump_info(GString *buf) { - g_string_append_printf(buf, "[TCG profiler not compiled]\n"); + dump_jit_profile_info(buf); } #ifdef ELF_HOST_MACHINE From patchwork Wed Jun 7 12:24:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Wu, Fei" X-Patchwork-Id: 13270628 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0925BC7EE25 for ; Wed, 7 Jun 2023 12:23:45 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q6sAr-000216-9z; Wed, 07 Jun 2023 08:22:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAk-0001tj-QN for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:21:54 -0400 Received: from mga06b.intel.com ([134.134.136.31] helo=mga06.intel.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAi-0004k3-OW for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:21:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686140512; x=1717676512; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jznP1xJjYmCC6NNJmCQGTW4MZEZdhSSqYxOW9kQsn6I=; b=IYnd3E0H3eDbhMgyw1wyN4b3daiV4YAZuIT1venvN7oPJuFOGb3ExzRr KLcrtk2mG/h4h19Y3ide4Oz4xttJvxY33Mh2OLluc6mKmRNo069rQpAW5 hbs8Y0mNopDeSBrHQ1BfHFTn+VDZx0B6VIEpCZVMBcQkR0V9m4io50vZw kTMsJqaExgRq2gKVbYuWgCwhQY69/z2vMdisHL8QBxtOxCT+mjgo/wtnA u1Aw/kfenc3dxjXoVmMiYprrZNFlEVaarQ6rG3a9lq2sfJUylJ9R42GO0 5yTOUv9lMK0/8d/Xftef8fjWGVTLZsfM7O6KZETt2g5ziEMFjgjr2WDbt g==; X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="420527930" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="420527930" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Jun 2023 05:21:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="686970038" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="686970038" Received: from wufei-optiplex-7090.sh.intel.com ([10.238.200.247]) by orsmga006.jf.intel.com with ESMTP; 07 Jun 2023 05:21:49 -0700 From: Fei Wu To: richard.henderson@linaro.org, alex.bennee@linaro.org, qemu-devel@nongnu.org Cc: "Vanderson M. do Rosario" , "Dr . David Alan Gilbert" , Fei Wu , Paolo Bonzini , "Dr. David Alan Gilbert" Subject: [PATCH v15 05/10] monitor: adding tb_stats hmp command Date: Wed, 7 Jun 2023 20:24:06 +0800 Message-Id: <20230607122411.3394702-6-fei2.wu@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230607122411.3394702-1-fei2.wu@intel.com> References: <20230607122411.3394702-1-fei2.wu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.31; envelope-from=fei2.wu@intel.com; helo=mga06.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: "Vanderson M. do Rosario" Adding tb_stats [start|stop|status] command to hmp. This allows controlling the collection of statistics. It is also possible to set the flag of collection: all, jit, or exec. The goal of this command is to allow the dynamic exploration of the TCG behavior and quality. Therefore, for now, a corresponding QMP command is not worthwhile. Acked-by: Dr. David Alan Gilbert Signed-off-by: Vanderson M. do Rosario Message-Id: <20190829173437.5926-8-vandersonmr2@gmail.com> Message-Id: <20190829173437.5926-9-vandersonmr2@gmail.com> [AJB: fix authorship] Signed-off-by: Alex Bennée Signed-off-by: Fei Wu --- accel/tcg/monitor.c | 100 ++++++++++++++++++++++++++++++++++ accel/tcg/tb-stats.c | 17 ++++++ hmp-commands.hx | 16 ++++++ include/exec/tb-stats-flags.h | 1 + include/exec/tb-stats.h | 4 ++ include/monitor/hmp.h | 1 + 6 files changed, 139 insertions(+) diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c index 111ccbc4da..094150e4af 100644 --- a/accel/tcg/monitor.c +++ b/accel/tcg/monitor.c @@ -11,13 +11,18 @@ #include "qapi/error.h" #include "qapi/type-helpers.h" #include "qapi/qapi-commands-machine.h" +#include "qapi/qmp/qdict.h" #include "monitor/monitor.h" +#include "monitor/hmp.h" #include "sysemu/cpus.h" #include "sysemu/cpu-timers.h" #include "sysemu/tcg.h" #include "exec/tb-stats.h" +#include "exec/tb-flush.h" #include "internal.h" +#include "tb-context.h" +enum TbstatsCmd { TBS_CMD_START, TBS_CMD_STOP, TBS_CMD_STATUS }; static void dump_drift_info(GString *buf) { @@ -86,6 +91,101 @@ HumanReadableText *qmp_x_query_opcount(Error **errp) return human_readable_text_from_str(buf); } +struct TbstatsCommand { + enum TbstatsCmd cmd; + uint32_t flag; + Monitor *mon; +}; + +static void do_hmp_tbstats_safe(CPUState *cpu, run_on_cpu_data icmd) +{ + struct TbstatsCommand *cmdinfo = icmd.host_ptr; + int cmd = cmdinfo->cmd; + uint32_t flag = cmdinfo->flag; + Monitor *mon = cmdinfo->mon; + + switch (cmd) { + case TBS_CMD_START: + if (tb_stats_collection_enabled()) { + monitor_printf(mon, "TB information already being recorded\n"); + return; + } + + qht_init(&tb_ctx.tb_stats, tb_stats_cmp, CODE_GEN_HTABLE_SIZE, + QHT_MODE_AUTO_RESIZE); + set_tbstats_flag(flag); + enable_collect_tb_stats(); + tb_flush(cpu); + break; + case TBS_CMD_STOP: + if (tb_stats_collection_disabled()) { + monitor_printf(mon, "TB information not being recorded\n"); + return; + } + + /* Dissalloc all TBStatistics structures and stop creating new ones */ + disable_collect_tb_stats(); + clean_tbstats(); + tb_flush(cpu); + break; + case TBS_CMD_STATUS: + if (tb_stats_collection_enabled()) { + uint32_t flag = get_tbstats_flag(); + monitor_printf(mon, "tb_stats is enabled with flag:\n"); + monitor_printf(mon, " EXEC: %d\n", !!(flag & TB_EXEC_STATS)); + monitor_printf(mon, " JIT: %d\n", !!(flag & TB_JIT_STATS)); + } else { + monitor_printf(mon, "tb_stats is disabled\n"); + } + break; + default: /* INVALID */ + g_assert_not_reached(); + break; + } + + g_free(cmdinfo); +} + +void hmp_tbstats(Monitor *mon, const QDict *qdict) +{ + if (!tcg_enabled()) { + monitor_printf(mon, "Only available with accel=tcg\n"); + return; + } + + char *cmd = (char *) qdict_get_try_str(qdict, "command"); + enum TbstatsCmd icmd = -1; + + if (strcmp(cmd, "start") == 0) { + icmd = TBS_CMD_START; + } else if (strcmp(cmd, "stop") == 0) { + icmd = TBS_CMD_STOP; + } else if (strcmp(cmd, "status") == 0) { + icmd = TBS_CMD_STATUS; + } else { + monitor_printf(mon, "Invalid command\n"); + return; + } + + char *sflag = (char *) qdict_get_try_str(qdict, "flag"); + uint32_t flag = TB_EXEC_STATS | TB_JIT_STATS; + if (sflag) { + if (strcmp(sflag, "jit") == 0) { + flag = TB_JIT_STATS; + } else if (strcmp(sflag, "exec") == 0) { + flag = TB_EXEC_STATS; + } + } + + struct TbstatsCommand *tbscommand = g_new0(struct TbstatsCommand, 1); + tbscommand->cmd = icmd; + tbscommand->flag = flag; + tbscommand->mon = mon; + async_safe_run_on_cpu(first_cpu, do_hmp_tbstats_safe, + RUN_ON_CPU_HOST_PTR(tbscommand)); + +} + static void hmp_tcg_register(void) { monitor_register_hmp_info_hrt("jit", qmp_x_query_jit); diff --git a/accel/tcg/tb-stats.c b/accel/tcg/tb-stats.c index 11322359c7..c90dde37d0 100644 --- a/accel/tcg/tb-stats.c +++ b/accel/tcg/tb-stats.c @@ -91,6 +91,18 @@ void dump_jit_profile_info(GString *buf) g_free(jpi); } +static void free_tbstats(void *p, uint32_t hash, void *userp) +{ + g_free(p); +} + +void clean_tbstats(void) +{ + /* remove all tb_stats */ + qht_iter(&tb_ctx.tb_stats, free_tbstats, NULL); + qht_destroy(&tb_ctx.tb_stats); +} + void init_tb_stats_htable(void) { if (!tb_ctx.tb_stats.map && tb_stats_collection_enabled()) { @@ -115,6 +127,11 @@ bool tb_stats_collection_enabled(void) return tcg_collect_tb_stats == TB_STATS_RUNNING; } +bool tb_stats_collection_disabled(void) +{ + return tcg_collect_tb_stats == TB_STATS_STOPPED; +} + uint32_t get_tbstats_flag(void) { return tbstats_flag; diff --git a/hmp-commands.hx b/hmp-commands.hx index 2cbd0f77a0..639e9d9e53 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1670,6 +1670,22 @@ SRST Executes a qemu-io command on the given block device. ERST +#if defined(CONFIG_TCG) + { + .name = "tb_stats", + .args_type = "command:s,flag:s?", + .params = "command [flag]", + .help = "Control tb statistics collection:" + "tb_stats (start|stop|status) [all|jit|exec]", + .cmd = hmp_tbstats, + }, +#endif + +SRST +``tb_stats`` *command* *flag* + Control recording tb statistics +ERST + { .name = "qom-list", .args_type = "path:s?", diff --git a/include/exec/tb-stats-flags.h b/include/exec/tb-stats-flags.h index 286ca93bcc..d8b844be99 100644 --- a/include/exec/tb-stats-flags.h +++ b/include/exec/tb-stats-flags.h @@ -19,6 +19,7 @@ void enable_collect_tb_stats(void); void disable_collect_tb_stats(void); bool tb_stats_collection_enabled(void); +bool tb_stats_collection_disabled(void); uint32_t get_tbstats_flag(void); void set_tbstats_flag(uint32_t flag); diff --git a/include/exec/tb-stats.h b/include/exec/tb-stats.h index 6ed767f490..e16f947410 100644 --- a/include/exec/tb-stats.h +++ b/include/exec/tb-stats.h @@ -31,6 +31,8 @@ #include "exec/tb-stats-flags.h" #include "tcg/tcg.h" +enum SortBy { SORT_BY_HOTNESS, SORT_BY_HG /* Host/Guest */, SORT_BY_SPILLS }; + typedef struct TBStatistics TBStatistics; /* @@ -90,4 +92,6 @@ bool tb_stats_enabled(TranslationBlock *tb, uint32_t flag); void dump_jit_profile_info(GString *buf); +void clean_tbstats(void); + #endif diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index 13f9a2dedb..2e7f141754 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -181,5 +181,6 @@ void hmp_ioport_write(Monitor *mon, const QDict *qdict); void hmp_boot_set(Monitor *mon, const QDict *qdict); void hmp_info_mtree(Monitor *mon, const QDict *qdict); void hmp_info_cryptodev(Monitor *mon, const QDict *qdict); +void hmp_tbstats(Monitor *mon, const QDict *qdict); #endif From patchwork Wed Jun 7 12:24:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Wu, Fei" X-Patchwork-Id: 13270626 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C53EFC7EE25 for ; Wed, 7 Jun 2023 12:23:38 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q6sAt-000240-EX; Wed, 07 Jun 2023 08:22:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAm-0001wY-PL for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:21:58 -0400 Received: from mga06b.intel.com ([134.134.136.31] helo=mga06.intel.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAk-0004lg-Qy for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:21:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686140514; x=1717676514; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=wWEbnMjFxLq0Q9nk/AfcqcGD8PPSWas/6sCddvwHO6c=; b=daAkQ4RaFSOhXemlwraAJqmjJqvRZr/KPioPzWUyptQRqnoyk8blLE3D 5DeiaNZdkcTkhG9Cd2m5G0LWk34a49j9LWRikm4p7XrzMAU80tqyWBv/G 3uvbF5THBN5ZX10mfpOj3PZlSA0wUgjQDL/chLBB83Uu71SCZtuZ3/PXv dKOjyyoN+7ZdfeDQFGNQs/wp/pPVb7upOs3dMPOqy15nrdOYr1aurfgQF m/RvfX3k8YsZEWD/vr5WQCHHNjjbYOwbeXwDw8ACaJeF7p4gcgDzc30/W JftCJWpSbbJtTVyQ1r98DJWLgNa0cETmtf4TI02zkv7GS4uDkqaPXAAyY w==; X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="420527939" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="420527939" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Jun 2023 05:21:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="686970045" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="686970045" Received: from wufei-optiplex-7090.sh.intel.com ([10.238.200.247]) by orsmga006.jf.intel.com with ESMTP; 07 Jun 2023 05:21:51 -0700 From: Fei Wu To: richard.henderson@linaro.org, alex.bennee@linaro.org, qemu-devel@nongnu.org Cc: Fei Wu , Paolo Bonzini Subject: [PATCH v15 06/10] tb-stats: reset the tracked TBs on a tb_flush Date: Wed, 7 Jun 2023 20:24:07 +0800 Message-Id: <20230607122411.3394702-7-fei2.wu@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230607122411.3394702-1-fei2.wu@intel.com> References: <20230607122411.3394702-1-fei2.wu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.31; envelope-from=fei2.wu@intel.com; helo=mga06.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Alex Bennée We keep track of translations but can only do so up until the translation cache is flushed. At that point we really have no idea if we can re-create a translation because all the active tracking information has been reset. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson Signed-off-by: Fei Wu --- accel/tcg/tb-maint.c | 1 + accel/tcg/tb-stats.c | 18 ++++++++++++++++++ include/exec/tb-stats.h | 8 ++++++++ 3 files changed, 27 insertions(+) diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index 0980fca358..11ff0ddd90 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -763,6 +763,7 @@ static void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count) qht_reset_size(&tb_ctx.htable, CODE_GEN_HTABLE_SIZE); tb_remove_all(); + tbstats_reset_tbs(); tcg_region_reset_all(); /* XXX: flush processor icache at this point if cache flush is expensive */ qatomic_inc(&tb_ctx.tb_flush_count); diff --git a/accel/tcg/tb-stats.c b/accel/tcg/tb-stats.c index c90dde37d0..7c7f700c89 100644 --- a/accel/tcg/tb-stats.c +++ b/accel/tcg/tb-stats.c @@ -103,6 +103,24 @@ void clean_tbstats(void) qht_destroy(&tb_ctx.tb_stats); } +/* + * We have to reset the tbs array on a tb_flush as those + * TranslationBlocks no longer exist. + */ + +static void reset_tbs_array(void *p, uint32_t hash, void *userp) +{ + TBStatistics *tbs = p; + g_ptr_array_set_size(tbs->tbs, 0); +} + +void tbstats_reset_tbs(void) +{ + if (tb_ctx.tb_stats.map) { + qht_iter(&tb_ctx.tb_stats, reset_tbs_array, NULL); + } +} + void init_tb_stats_htable(void) { if (!tb_ctx.tb_stats.map && tb_stats_collection_enabled()) { diff --git a/include/exec/tb-stats.h b/include/exec/tb-stats.h index e16f947410..77974b4b7f 100644 --- a/include/exec/tb-stats.h +++ b/include/exec/tb-stats.h @@ -94,4 +94,12 @@ void dump_jit_profile_info(GString *buf); void clean_tbstats(void); +/** + * tbstats_reset_tbs: reset the linked array of TBs + * + * Reset the list of tbs for a given array. Should be called from + * safe work during tb_flush. + */ +void tbstats_reset_tbs(void); + #endif From patchwork Wed Jun 7 12:24:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Wu, Fei" X-Patchwork-Id: 13270622 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D9903C8300C for ; Wed, 7 Jun 2023 12:22:54 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q6sAs-000222-LR; Wed, 07 Jun 2023 08:22:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAp-0001y8-Bk for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:22:00 -0400 Received: from mga06b.intel.com ([134.134.136.31] helo=mga06.intel.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAm-0004k3-PX for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:21:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686140516; x=1717676516; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EvNnE2JlHC6w0AbLKllJVqnnOmmBY03QPzdV1p6pRlE=; b=HYDfwA76hL9VAcBNmVes8LhztXNiHWHVZcftTjX5PoqmqGzIMSJGPUQX PvZaxSR1z9wTS3EOU2Ng4lJxAimEpQtNlA5IOJbw3zbgUXv0QOurRybUw yIv0jmptd6pEh/XFOEb46Soh5bwdyvo2G9dukjLX7SC7Ewbqo4/Cz3NPr 4c69diEYpahWK1zy8Ugds4XrDisY4AmBpvxp85akBB+diFaAHCwDiKixT o9m+omwS/vYk8OfAjtrIvZFOBOCuOwRizIKejw15U7WYjPynjKHAWHCNf 1/jPkMoeKJSkogEt0/4kXem43j1/EI0SE9X6DaN9NF9YInw/ZA/Nu65FW Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="420527951" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="420527951" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Jun 2023 05:21:55 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="686970058" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="686970058" Received: from wufei-optiplex-7090.sh.intel.com ([10.238.200.247]) by orsmga006.jf.intel.com with ESMTP; 07 Jun 2023 05:21:53 -0700 From: Fei Wu To: richard.henderson@linaro.org, alex.bennee@linaro.org, qemu-devel@nongnu.org Cc: "Vanderson M. do Rosario" , "Dr . David Alan Gilbert" , Fei Wu , Paolo Bonzini , "Dr. David Alan Gilbert" Subject: [PATCH v15 07/10] tb-stats: Adding info [tb-list|tb] commands to HMP (WIP) Date: Wed, 7 Jun 2023 20:24:08 +0800 Message-Id: <20230607122411.3394702-8-fei2.wu@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230607122411.3394702-1-fei2.wu@intel.com> References: <20230607122411.3394702-1-fei2.wu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.31; envelope-from=fei2.wu@intel.com; helo=mga06.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: "Vanderson M. do Rosario" These commands allow the exploration of TBs generated by the TCG. Understand which one hotter, with more guest/host instructions... and examine their guest, host and IR code. The goal of this command is to allow the dynamic exploration of TCG behavior and code quality. Therefore, for now, a corresponding QMP command is not worthwhile. [AJB: WIP - we still can't be safely sure a translation will succeed] Example of output: TB id:0 | phys:0x34d54 virt:0x0000000000034d54 flags:0x0000f0 | exec:4828932/0 guest inst cov:16.38% | trans:1 ints: g:3 op:82 op_opt:34 spills:3 | h/g (host bytes / guest insts): 90.666664 TB id:1 | phys:0x34d0d virt:0x0000000000034d0d flags:0x0000f0 | exec:4825842/0 guest inst cov:21.82% | trans:1 ints: g:4 op:80 op_opt:38 spills:2 | h/g (host bytes / guest insts): 84.000000 ---------------- 0x00034d0d: 89 de movl %ebx, %esi 0x00034d0f: 26 8b 0e movl %es:(%esi), %ecx 0x00034d12: 26 f6 46 08 80 testb $0x80, %es:8(%esi) 0x00034d17: 75 3b jne 0x34d54 ------------------------------ Acked-by: Dr. David Alan Gilbert Signed-off-by: Vanderson M. do Rosario Message-Id: <20190829173437.5926-10-vandersonmr2@gmail.com> [AJB: fix authorship, dropped coverset] Signed-off-by: Alex Bennée Signed-off-by: Fei Wu --- accel/tcg/monitor.c | 69 ++++++++++++++++ accel/tcg/tb-stats.c | 176 ++++++++++++++++++++++++++++++++++++++++ disas/disas.c | 2 + hmp-commands-info.hx | 16 ++++ include/exec/tb-stats.h | 25 ++++++ include/monitor/hmp.h | 2 + 6 files changed, 290 insertions(+) diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c index 094150e4af..d43c62b248 100644 --- a/accel/tcg/monitor.c +++ b/accel/tcg/monitor.c @@ -8,17 +8,21 @@ #include "qemu/osdep.h" #include "qemu/accel.h" +#include "qemu/log.h" #include "qapi/error.h" #include "qapi/type-helpers.h" #include "qapi/qapi-commands-machine.h" #include "qapi/qmp/qdict.h" #include "monitor/monitor.h" #include "monitor/hmp.h" +#include "monitor/hmp-target.h" #include "sysemu/cpus.h" #include "sysemu/cpu-timers.h" #include "sysemu/tcg.h" #include "exec/tb-stats.h" #include "exec/tb-flush.h" +#include "disas/disas.h" +#include "tb-context.h" #include "internal.h" #include "tb-context.h" @@ -186,6 +190,71 @@ void hmp_tbstats(Monitor *mon, const QDict *qdict) } +void hmp_info_tblist(Monitor *mon, const QDict *qdict) +{ + int number_int; + const char *sortedby_str = NULL; + g_autoptr(GString) buf = g_string_new(""); + + if (!tcg_enabled()) { + monitor_printf(mon, "Only available with accel=tcg\n"); + return; + } + if (!tb_ctx.tb_stats.map) { + monitor_printf(mon, "no TB information recorded\n"); + return; + } + + number_int = qdict_get_try_int(qdict, "number", 10); + sortedby_str = qdict_get_try_str(qdict, "sortedby"); + + int sortedby = SORT_BY_HOTNESS; + if (sortedby_str == NULL || strcmp(sortedby_str, "hotness") == 0) { + sortedby = SORT_BY_HOTNESS; + } else if (strcmp(sortedby_str, "hg") == 0) { + sortedby = SORT_BY_HG; + } else if (strcmp(sortedby_str, "spills") == 0) { + sortedby = SORT_BY_SPILLS; + } else { + monitor_printf(mon, "valid sort options are: hotness hg spills\n"); + return; + } + + dump_tblist_info(buf, number_int, sortedby); + monitor_printf(mon, "%s", buf->str); +} + +void hmp_info_tb(Monitor *mon, const QDict *qdict) +{ + const int id = qdict_get_int(qdict, "id"); + g_autoptr(GString) buf = g_string_new(""); + + if (!tcg_enabled()) { + monitor_printf(mon, "Only available with accel=tcg\n"); + return; + } + + TBStatistics *tbs = get_tbstats_by_id(id); + if (tbs == NULL) { + monitor_printf(mon, "TB %d information is not recorded\n", id); + return; + } + + monitor_printf(mon, "\n------------------------------\n\n"); + + int valid_tb_num = dump_tb_info(buf, tbs, id); + monitor_printf(mon, "%s", buf->str); + + if (valid_tb_num > 0) { + unsigned num_inst = tbs->code.num_guest_inst / tbs->translations.total; + + monitor_printf(mon, "\n----------------n\n"); + // FIXME: cannot disas + monitor_disas(mon, mon_get_cpu(mon), tbs->phys_pc, num_inst, true); + monitor_printf(mon, "\n------------------------------\n\n"); + } +} + static void hmp_tcg_register(void) { monitor_register_hmp_info_hrt("jit", qmp_x_query_jit); diff --git a/accel/tcg/tb-stats.c b/accel/tcg/tb-stats.c index 7c7f700c89..53a4f448dc 100644 --- a/accel/tcg/tb-stats.c +++ b/accel/tcg/tb-stats.c @@ -11,12 +11,16 @@ #include "disas/disas.h" #include "exec/exec-all.h" #include "tcg/tcg.h" +#include "qapi/error.h" #include "qemu/qemu-print.h" +#include "qemu/log.h" #include "exec/tb-stats.h" #include "tb-context.h" +#include "internal.h" + /* TBStatistic collection controls */ enum TBStatsStatus { TB_STATS_STOPPED = 0, @@ -26,6 +30,8 @@ enum TBStatsStatus { static enum TBStatsStatus tcg_collect_tb_stats; static uint32_t tbstats_flag; +static GPtrArray *last_search; + struct jit_profile_info { uint64_t translations; uint64_t aborted; @@ -42,6 +48,18 @@ struct jit_profile_info { #define stat_per_translation(stat, name) \ (stat->translations.total ? stat->name / stat->translations.total : 0) +TBStatistics *get_tbstats_by_id(int id) +{ + if (!last_search) { + return NULL; + } + + if (id < 0 || id >= last_search->len) { + return NULL; + } + return g_ptr_array_index(last_search, id); +} + /* accumulate the statistics from all TBs */ static void collect_jit_profile_info(void *p, uint32_t hash, void *userp) { @@ -98,6 +116,10 @@ static void free_tbstats(void *p, uint32_t hash, void *userp) void clean_tbstats(void) { + if (last_search) { + g_ptr_array_free(last_search, true); + } + /* remove all tb_stats */ qht_iter(&tb_ctx.tb_stats, free_tbstats, NULL); qht_destroy(&tb_ctx.tb_stats); @@ -129,6 +151,154 @@ void init_tb_stats_htable(void) } } +static void collect_tb_stats(void *p, uint32_t hash, void *userp) +{ + int *count = userp; + + g_ptr_array_add(last_search, p); + (*count)++; +} + +static void count_invalid_tbs(gpointer data, gpointer user_data) +{ + TranslationBlock *tb = (TranslationBlock *) data; + unsigned *counter = (unsigned *) user_data; + if (tb->cflags & CF_INVALID) { + *counter = *counter + 1; + } +} + +int dump_tb_info(GString *buf, TBStatistics *tbs, int id) +{ + unsigned g = stat_per_translation(tbs, code.num_guest_inst); + unsigned ops = stat_per_translation(tbs, code.num_tcg_ops); + unsigned ops_opt = stat_per_translation(tbs, code.num_tcg_ops_opt); + unsigned spills = stat_per_translation(tbs, code.spills); + unsigned h = stat_per_translation(tbs, code.out_len); + unsigned act = tbs->tbs->len; + unsigned invalid = 0; + + float guest_host_prop = g ? ((float) h / g) : 0; + + g_ptr_array_foreach(tbs->tbs, &count_invalid_tbs, &invalid); + + g_string_append_printf(buf, + "TB id:%d | phys:0x"TB_PAGE_ADDR_FMT" virt:0x"TARGET_FMT_lx + " flags:0x%08x %d inv/%d\n", + id, tbs->phys_pc, tbs->pc, tbs->flags, invalid, act); + + if (tbs_stats_enabled(tbs, TB_EXEC_STATS)) { + g_string_append_printf(buf, + "\t| exec:%lu/%lu guest inst cov:%.2f%%\n", + tbs->executions.normal, + tbs->executions.atomic, tbs->executions.coverage / 100.0f); + } + + if (tbs_stats_enabled(tbs, TB_JIT_STATS)) { + g_string_append_printf(buf, + "\t| trans:%lu ints: g:%u op:%u op_opt:%u spills:%d" + "\n\t| h/g (host bytes / guest insts): %f\n", + tbs->translations.total, g, ops, ops_opt, spills, + guest_host_prop); + } + + g_string_append_printf(buf, "\n"); + + return act - invalid; +} + +static gint +inverse_sort_tbs_spills(gconstpointer p1, gconstpointer p2) +{ + const TBStatistics *tbs1 = *(TBStatistics **) p1; + const TBStatistics *tbs2 = *(TBStatistics **) p2; + unsigned long c1 = stat_per_translation(tbs1, code.spills); + unsigned long c2 = stat_per_translation(tbs2, code.spills); + return c1 < c2 ? 1 : c1 == c2 ? 0 : -1; +} + +static gint +inverse_sort_tbs_hotness(gconstpointer p1, gconstpointer p2) +{ + const TBStatistics *tbs1 = *(TBStatistics **) p1; + const TBStatistics *tbs2 = *(TBStatistics **) p2; + unsigned long c1 = stat_per_translation(tbs1, executions.normal); + unsigned long c2 = stat_per_translation(tbs2, executions.normal); + return c1 < c2 ? 1 : c1 == c2 ? 0 : -1; +} + +static gint +inverse_sort_tbs_hg(gconstpointer p1, gconstpointer p2) +{ + const TBStatistics *tbs1 = *(TBStatistics **) p1; + const TBStatistics *tbs2 = *(TBStatistics **) p2; + + if (tbs1->code.num_guest_inst == 0) { + return -1; + } + if (tbs2->code.num_guest_inst == 0) { + return 1; + } + + unsigned long c1 = tbs1->code.out_len / tbs1->code.num_guest_inst; + unsigned long c2 = tbs2->code.out_len / tbs2->code.num_guest_inst; + return c1 < c2 ? 1 : c1 == c2 ? 0 : -1; +} + +static void calculate_last_search_coverages(void) +{ + uint64_t total_exec_count = 0; + + /* Compute total execution count for all tbs */ + for (int i = 0; i < last_search->len; ++i) { + TBStatistics *tbs = g_ptr_array_index(last_search, i); + total_exec_count += + (tbs->executions.atomic + tbs->executions.normal) + * stat_per_translation(tbs, code.num_guest_inst); + } + + for (int i = 0; i < last_search->len; ++i) { + TBStatistics *tbs = g_ptr_array_index(last_search, i); + uint64_t tb_total_execs = + (tbs->executions.atomic + tbs->executions.normal) + * stat_per_translation(tbs, code.num_guest_inst); + tbs->executions.coverage = + (10000 * tb_total_execs) / (total_exec_count + 1); + } +} + +void dump_tblist_info(GString *buf, int total, int sort_by) +{ + int array_size = 0; + + if (last_search) { + g_ptr_array_free(last_search, true); + } + last_search = g_ptr_array_new(); + + qht_iter(&tb_ctx.tb_stats, collect_tb_stats, &array_size); + + calculate_last_search_coverages(); + + if (sort_by == SORT_BY_HOTNESS) { + g_ptr_array_sort(last_search, (GCompareFunc)inverse_sort_tbs_hotness); + } else if (sort_by == SORT_BY_SPILLS) { + g_ptr_array_sort(last_search, (GCompareFunc)inverse_sort_tbs_spills); + } else if (sort_by == SORT_BY_HG) { + g_ptr_array_sort(last_search, (GCompareFunc)inverse_sort_tbs_hg); + } else { + return; + } + + array_size = (array_size > total) ? total : array_size; + g_ptr_array_set_size(last_search, array_size); + + for (int i = 0; i < last_search->len; ++i) { + TBStatistics *tbs = g_ptr_array_index(last_search, i); + dump_tb_info(buf, tbs, i); + } +} + void enable_collect_tb_stats(void) { tcg_collect_tb_stats = TB_STATS_RUNNING; @@ -166,3 +336,9 @@ bool tb_stats_enabled(TranslationBlock *tb, uint32_t flag) tb->tb_stats && (tbstats_flag & flag); } + +bool tbs_stats_enabled(struct TBStatistics *tbs, uint32_t flag) +{ + return tb_stats_collection_enabled() && + (tbstats_flag & flag); +} diff --git a/disas/disas.c b/disas/disas.c index 0d2d06c2ec..3b19b51fca 100644 --- a/disas/disas.c +++ b/disas/disas.c @@ -8,6 +8,8 @@ #include "hw/core/cpu.h" #include "exec/memory.h" +#include "qemu/log-for-trace.h" + /* Filled in by elfload.c. Simplistic, but will do for now. */ struct syminfo *syminfos = NULL; diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index f5b37eb74a..ace1ecc3c5 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -262,6 +262,22 @@ ERST .params = "", .help = "show dynamic compiler info", }, + { + .name = "tb-list", + .args_type = "number:i?,sortedby:s?", + .params = "[number sortedby]", + .help = "show a [number] translated blocks sorted by [sortedby]" + "sortedby opts: hotness hg spills", + .cmd = hmp_info_tblist, + }, + { + .name = "tb", + .args_type = "id:i,flags:s?", + .params = "id [flag1,flag2,...]", + .help = "show information about one translated block by id." + "dump flags can be used to set dump code level: out_asm in_asm op", + .cmd = hmp_info_tb, + }, #endif SRST diff --git a/include/exec/tb-stats.h b/include/exec/tb-stats.h index 77974b4b7f..4cdf41af6c 100644 --- a/include/exec/tb-stats.h +++ b/include/exec/tb-stats.h @@ -54,6 +54,8 @@ struct TBStatistics { struct { unsigned long normal; unsigned long atomic; + /* filled only when dumping x% cover set */ + uint16_t coverage; } executions; /* JIT Stats - protected by lock */ @@ -89,6 +91,7 @@ bool tb_stats_cmp(const void *ap, const void *bp); void init_tb_stats_htable(void); bool tb_stats_enabled(TranslationBlock *tb, uint32_t flag); +bool tbs_stats_enabled(struct TBStatistics *tbs, uint32_t flag); void dump_jit_profile_info(GString *buf); @@ -102,4 +105,26 @@ void clean_tbstats(void); */ void tbstats_reset_tbs(void); +/** + * dump_tbs_info: report the hottest blocks + * + * @buf: output buffer + * @total: the limit of hotblocks + * @sort_by: property in which the dump will be sorted + * + * Report the hottest blocks to either the log or monitor + */ +void dump_tblist_info(GString *buf, int total, int sort_by); + +/** + * dump_tb_info: dump information about one TB + * + * @buf: output buffer + * @tbs: the tbs to dump + * @id: the display id of the block (from previous search) + */ +int dump_tb_info(GString *buf, TBStatistics *tbs, int id); + +TBStatistics *get_tbstats_by_id(int id); + #endif diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index 2e7f141754..acdd6f1561 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -182,5 +182,7 @@ void hmp_boot_set(Monitor *mon, const QDict *qdict); void hmp_info_mtree(Monitor *mon, const QDict *qdict); void hmp_info_cryptodev(Monitor *mon, const QDict *qdict); void hmp_tbstats(Monitor *mon, const QDict *qdict); +void hmp_info_tblist(Monitor *mon, const QDict *qdict); +void hmp_info_tb(Monitor *mon, const QDict *qdict); #endif From patchwork Wed Jun 7 12:24:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Wu, Fei" X-Patchwork-Id: 13270629 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id ACDA6C7EE25 for ; Wed, 7 Jun 2023 12:23:49 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q6sAr-00021Y-UJ; Wed, 07 Jun 2023 08:22:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAq-0001yF-9o for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:22:00 -0400 Received: from mga06b.intel.com ([134.134.136.31] helo=mga06.intel.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAo-0004lg-FE for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:22:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686140518; x=1717676518; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=LtkaMVeUbijqlyekLbrz4vTEno4QkWFSacCof7mrn8U=; b=H02rchx99afMnrcfALhPSfAle/Z3SwJEby5xdIplp7wZ3J2YNXu4OQDQ eUv1g7PAs+k19btjVY/8BQNAw2EI3qTSebJnHPX9pDrzjR+Ttss0Pmqqh kt0v1Z7+ptkjSTlkDn2wvehjPMw+Ac5xU4RmbMvTB7ZrNNaSzryUNJJN1 PgwG+FRGu2ygQAF+HyBfLRmW4hJjoClROOgVJH52RAvRR3mQcRnto6jUM lHfJaefB7/evfbmxL87a6a5ZGwYxepmBm747UZSGTcLT3F68Qup6ZfaIW sy0eX4TlP58y+YeQ7HYH30+HBoPDLAR9JW4AptkzRMJyRm5eN31yiDyvB g==; X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="420527960" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="420527960" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Jun 2023 05:21:57 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="686970065" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="686970065" Received: from wufei-optiplex-7090.sh.intel.com ([10.238.200.247]) by orsmga006.jf.intel.com with ESMTP; 07 Jun 2023 05:21:55 -0700 From: Fei Wu To: richard.henderson@linaro.org, alex.bennee@linaro.org, qemu-devel@nongnu.org Cc: Fei Wu , "Vanderson M . do Rosario" , Paolo Bonzini Subject: [PATCH v15 08/10] debug: add -d tb_stats to control TBStatistics Date: Wed, 7 Jun 2023 20:24:09 +0800 Message-Id: <20230607122411.3394702-9-fei2.wu@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230607122411.3394702-1-fei2.wu@intel.com> References: <20230607122411.3394702-1-fei2.wu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.31; envelope-from=fei2.wu@intel.com; helo=mga06.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Capture TBS at startup instead of an explicit 'tb_stats start' command. Signed-off-by: Vanderson M. do Rosario Signed-off-by: Alex Bennée Signed-off-by: Fei Wu --- include/exec/tb-stats-flags.h | 1 + include/qemu/log.h | 1 + stubs/meson.build | 1 + stubs/tb-stats.c | 32 ++++++++++++++++++++++++++++++++ util/log.c | 18 ++++++++++++++++++ 5 files changed, 53 insertions(+) create mode 100644 stubs/tb-stats.c diff --git a/include/exec/tb-stats-flags.h b/include/exec/tb-stats-flags.h index d8b844be99..936bd35707 100644 --- a/include/exec/tb-stats-flags.h +++ b/include/exec/tb-stats-flags.h @@ -14,6 +14,7 @@ #define TB_NONE_STATS (0) /* no stats */ #define TB_EXEC_STATS (1 << 0) #define TB_JIT_STATS (1 << 1) +#define TB_ALL_STATS (TB_EXEC_STATS | TB_JIT_STATS) /* TBStatistic collection controls */ void enable_collect_tb_stats(void); diff --git a/include/qemu/log.h b/include/qemu/log.h index c5643d8dd5..6f3b8091cd 100644 --- a/include/qemu/log.h +++ b/include/qemu/log.h @@ -35,6 +35,7 @@ bool qemu_log_separate(void); /* LOG_STRACE is used for user-mode strace logging. */ #define LOG_STRACE (1 << 19) #define LOG_PER_THREAD (1 << 20) +#define CPU_LOG_TB_STATS (1 << 21) /* Lock/unlock output. */ diff --git a/stubs/meson.build b/stubs/meson.build index a56645e2f7..e926649d40 100644 --- a/stubs/meson.build +++ b/stubs/meson.build @@ -65,3 +65,4 @@ else endif stub_ss.add(files('semihost-all.c')) stub_ss.add(when: 'CONFIG_VFIO_USER_SERVER', if_false: files('vfio-user-obj.c')) +stub_ss.add(files('tb-stats.c')) diff --git a/stubs/tb-stats.c b/stubs/tb-stats.c new file mode 100644 index 0000000000..38ee12313e --- /dev/null +++ b/stubs/tb-stats.c @@ -0,0 +1,32 @@ +/* + * TB Stats Stubs + * + * Copyright (c) 2019 + * Written by Alex Bennée + * + * This code is licensed under the GNU GPL v2, or later. + */ + + +#include "qemu/osdep.h" +#include "exec/tb-stats-flags.h" + +void enable_collect_tb_stats(void) +{ + return; +} + +void disable_collect_tb_stats(void) +{ + return; +} + +bool tb_stats_collection_enabled(void) +{ + return false; +} + +void set_tbstats_flag(uint32_t flag) +{ + return; +} diff --git a/util/log.c b/util/log.c index 53b4f6c58e..419f02c380 100644 --- a/util/log.c +++ b/util/log.c @@ -27,6 +27,7 @@ #include "qemu/thread.h" #include "qemu/lockable.h" #include "qemu/rcu.h" +#include "exec/tb-stats-flags.h" #ifdef CONFIG_LINUX #include #endif @@ -495,6 +496,8 @@ const QEMULogItem qemu_log_items[] = { "log every user-mode syscall, its input, and its result" }, { LOG_PER_THREAD, "tid", "open a separate log file per thread; filename must contain '%d'" }, + { CPU_LOG_TB_STATS, "tb_stats_{all,jit,exec}", + "enable collection of TBs statistics at startup" }, { 0, NULL, NULL }, }; @@ -516,6 +519,21 @@ int qemu_str_to_log_mask(const char *str) trace_enable_events((*tmp) + 6); mask |= LOG_TRACE; #endif + } else if (g_str_has_prefix(*tmp, "tb_stats_")) { + char *p = *tmp + 9; + uint32_t flag = TB_NONE_STATS; + if (g_str_has_prefix(p, "all")) { + flag = TB_ALL_STATS; + } else if (g_str_has_prefix(p, "jit")) { + flag = TB_JIT_STATS; + } else if (g_str_has_prefix(p, "exec")) { + flag = TB_EXEC_STATS; + } + if (flag != TB_NONE_STATS) { + mask |= CPU_LOG_TB_STATS; + set_tbstats_flag(flag); + enable_collect_tb_stats(); + } } else { for (item = qemu_log_items; item->mask != 0; item++) { if (g_str_equal(*tmp, item->name)) { From patchwork Wed Jun 7 12:24:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wu, Fei" X-Patchwork-Id: 13270625 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 779CBC83005 for ; Wed, 7 Jun 2023 12:23:32 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q6sAt-00022K-7z; Wed, 07 Jun 2023 08:22:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAs-00021b-6t for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:22:02 -0400 Received: from mga06b.intel.com ([134.134.136.31] helo=mga06.intel.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAq-0004k3-9G for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:22:01 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686140520; x=1717676520; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=q5iH+Tfo5L9hxjb5SO1flH4zlFhX22DRAOIOfK22jFc=; b=Pq3AIhDglWrF+xKdtd0yeD3l/EAm15tlAEgfJaKHx3xLFskrXsD2Sva8 APFMN1dqQ+44aDdGiODuHh6sy5576Lwai8MUvL8TxTWbYkDX40Nh2IX5G Deb8zpp5DvM/Ajtpe60q9e5ZVN2Ux9mNRtwLIaTawQefhcgkLKN+H8Wdn x9cXDGMRnRiqRtsy/CXTWuR8gD7ANtXdlnxUTgryjma4WhAqA6+6Z3Xjl GyUfjBZdPD8YrDQRtaM7+zTO0oyESQaMJm/dgVMixd1vUfglfltgrS1Kx NEbjRHdI9kPEedmZPL2s4KtzuyZu2pO17KteqkSdhbMeSqm0vTdwP4zBe g==; X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="420527969" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="420527969" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Jun 2023 05:21:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="686970078" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="686970078" Received: from wufei-optiplex-7090.sh.intel.com ([10.238.200.247]) by orsmga006.jf.intel.com with ESMTP; 07 Jun 2023 05:21:57 -0700 From: Fei Wu To: richard.henderson@linaro.org, alex.bennee@linaro.org, qemu-devel@nongnu.org Cc: Fei Wu , Paolo Bonzini , Laurent Vivier Subject: [PATCH v15 09/10] tb-stats: dump hot TBs at the end of the execution Date: Wed, 7 Jun 2023 20:24:10 +0800 Message-Id: <20230607122411.3394702-10-fei2.wu@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230607122411.3394702-1-fei2.wu@intel.com> References: <20230607122411.3394702-1-fei2.wu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.31; envelope-from=fei2.wu@intel.com; helo=mga06.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Dump the hottest TBs if -d tb_stats_{all,jit,exec}[:dump_num_at_exit] --- accel/tcg/tb-stats.c | 21 +++++++++++++++++++++ include/exec/tb-stats-dump.h | 21 +++++++++++++++++++++ include/exec/tb-stats-flags.h | 1 + linux-user/exit.c | 2 ++ softmmu/runstate.c | 2 ++ stubs/tb-stats.c | 4 ++++ util/log.c | 12 ++++++++++-- 7 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 include/exec/tb-stats-dump.h diff --git a/accel/tcg/tb-stats.c b/accel/tcg/tb-stats.c index 53a4f448dc..a5fc3c1c74 100644 --- a/accel/tcg/tb-stats.c +++ b/accel/tcg/tb-stats.c @@ -17,6 +17,7 @@ #include "qemu/log.h" #include "exec/tb-stats.h" +#include "exec/tb-stats-dump.h" #include "tb-context.h" #include "internal.h" @@ -29,6 +30,7 @@ enum TBStatsStatus { static enum TBStatsStatus tcg_collect_tb_stats; static uint32_t tbstats_flag; +static int max_dump_tbs; static GPtrArray *last_search; @@ -299,6 +301,20 @@ void dump_tblist_info(GString *buf, int total, int sort_by) } } +/* + * Dump the final stats + */ +void tb_stats_dump(void) +{ + if (!tb_stats_collection_enabled()) { + return; + } + + g_autoptr(GString) buf = g_string_new(""); + dump_tblist_info(buf, max_dump_tbs, SORT_BY_HOTNESS); + qemu_printf("%s", buf->str); +} + void enable_collect_tb_stats(void) { tcg_collect_tb_stats = TB_STATS_RUNNING; @@ -342,3 +358,8 @@ bool tbs_stats_enabled(struct TBStatistics *tbs, uint32_t flag) return tb_stats_collection_enabled() && (tbstats_flag & flag); } + +void set_tbstats_max_tbs(int max) +{ + max_dump_tbs = max; +} diff --git a/include/exec/tb-stats-dump.h b/include/exec/tb-stats-dump.h new file mode 100644 index 0000000000..197c6148e9 --- /dev/null +++ b/include/exec/tb-stats-dump.h @@ -0,0 +1,21 @@ +/* + * TB Stats common dump functions across sysemu/linux-user + * + * Copyright (c) 2019 Linaro + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#ifndef _TB_STATS_DUMP_H_ +#define _TB_STATS_DUMP_H_ + +/** + * tb_stats_dump: dump final tb_stats at end of execution + */ +#ifdef CONFIG_TCG +void tb_stats_dump(void); +#else +static inline void tb_stats_dump(void) { /* do nothing */ }; +#endif + +#endif /* _TB_STATS_DUMP_H_ */ diff --git a/include/exec/tb-stats-flags.h b/include/exec/tb-stats-flags.h index 936bd35707..52d0429eeb 100644 --- a/include/exec/tb-stats-flags.h +++ b/include/exec/tb-stats-flags.h @@ -24,5 +24,6 @@ bool tb_stats_collection_disabled(void); uint32_t get_tbstats_flag(void); void set_tbstats_flag(uint32_t flag); +void set_tbstats_max_tbs(int max); #endif diff --git a/linux-user/exit.c b/linux-user/exit.c index 3017d28a3c..4fd23bcf60 100644 --- a/linux-user/exit.c +++ b/linux-user/exit.c @@ -25,6 +25,7 @@ #ifdef CONFIG_GPROF #include #endif +#include "exec/tb-stats-dump.h" #ifdef CONFIG_GCOV extern void __gcov_dump(void); @@ -41,4 +42,5 @@ void preexit_cleanup(CPUArchState *env, int code) gdb_exit(code); qemu_plugin_user_exit(); perf_exit(); + tb_stats_dump(); } diff --git a/softmmu/runstate.c b/softmmu/runstate.c index bd50062ed0..156156815b 100644 --- a/softmmu/runstate.c +++ b/softmmu/runstate.c @@ -30,6 +30,7 @@ #include "crypto/cipher.h" #include "crypto/init.h" #include "exec/cpu-common.h" +#include "exec/tb-stats-dump.h" #include "gdbstub/syscalls.h" #include "hw/boards.h" #include "migration/misc.h" @@ -818,6 +819,7 @@ void qemu_cleanup(void) vm_shutdown(); replay_finish(); + tb_stats_dump(); job_cancel_sync_all(); bdrv_close_all(); diff --git a/stubs/tb-stats.c b/stubs/tb-stats.c index 38ee12313e..78ae1aa217 100644 --- a/stubs/tb-stats.c +++ b/stubs/tb-stats.c @@ -30,3 +30,7 @@ void set_tbstats_flag(uint32_t flag) { return; } + +void set_tbstats_max_tbs(int max) { + return; +} diff --git a/util/log.c b/util/log.c index 419f02c380..ae5398fb69 100644 --- a/util/log.c +++ b/util/log.c @@ -496,8 +496,9 @@ const QEMULogItem qemu_log_items[] = { "log every user-mode syscall, its input, and its result" }, { LOG_PER_THREAD, "tid", "open a separate log file per thread; filename must contain '%d'" }, - { CPU_LOG_TB_STATS, "tb_stats_{all,jit,exec}", - "enable collection of TBs statistics at startup" }, + { CPU_LOG_TB_STATS, "tb_stats_{all,jit,exec}[:dump_num_at_exit]", + "enable collection of TBs statistics at startup " + "and dump at exit until given a limit" }, { 0, NULL, NULL }, }; @@ -524,16 +525,23 @@ int qemu_str_to_log_mask(const char *str) uint32_t flag = TB_NONE_STATS; if (g_str_has_prefix(p, "all")) { flag = TB_ALL_STATS; + p += 3; } else if (g_str_has_prefix(p, "jit")) { flag = TB_JIT_STATS; + p += 3; } else if (g_str_has_prefix(p, "exec")) { flag = TB_EXEC_STATS; + p += 4; } if (flag != TB_NONE_STATS) { mask |= CPU_LOG_TB_STATS; set_tbstats_flag(flag); enable_collect_tb_stats(); } + if (p[0] == ':') { + int max_to_dump = atoi(p + 1); + set_tbstats_max_tbs(max_to_dump); + } } else { for (item = qemu_log_items; item->mask != 0; item++) { if (g_str_equal(*tmp, item->name)) { From patchwork Wed Jun 7 12:24:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wu, Fei" X-Patchwork-Id: 13270627 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 673C3C7EE23 for ; Wed, 7 Jun 2023 12:23:39 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q6sAw-0002Dn-9s; Wed, 07 Jun 2023 08:22:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAu-00028J-7Y for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:22:04 -0400 Received: from mga06b.intel.com ([134.134.136.31] helo=mga06.intel.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q6sAs-0004lg-55 for qemu-devel@nongnu.org; Wed, 07 Jun 2023 08:22:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686140522; x=1717676522; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=dJ+2Srr8PrkmCOnhhnEFjWHUwRO9J31R50sJcSnAkj0=; b=CesYm1mTI/wnas320Ju2DVekHIkBqkC+SqzVC/LgPNaNAZNxyg3jlXik +NH9/jJEz3xbkSAAJeoUxdDRRtyYIql+rpRd19ZG5ZMbKKimivmELr6Oo 7H2eMKwPbtL4Bant/I1dUqd9gmq2hslXnOwabTStz9XmCjFKEBXWHoJQz nlLglIXio0UF3FXPSrWt7czrE3a727DpQxUNEH+/ZOGU10rabMRYVSKLK iGAyrAjgbJF7cGY4aDlPmlAny/7finEPgSZ+Znp2Q+ndBgVAt4vyM/iod wy5S5CIKau9D/ffEyCKauwjsJX6gbMo4ElFC33uiRiXIDvTUnlXHwPnLL A==; X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="420527977" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="420527977" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Jun 2023 05:22:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="686970084" X-IronPort-AV: E=Sophos;i="6.00,224,1681196400"; d="scan'208";a="686970084" Received: from wufei-optiplex-7090.sh.intel.com ([10.238.200.247]) by orsmga006.jf.intel.com with ESMTP; 07 Jun 2023 05:21:59 -0700 From: Fei Wu To: richard.henderson@linaro.org, alex.bennee@linaro.org, qemu-devel@nongnu.org Cc: Fei Wu , Paolo Bonzini Subject: [PATCH v15 10/10] docs: add tb-stats how to Date: Wed, 7 Jun 2023 20:24:11 +0800 Message-Id: <20230607122411.3394702-11-fei2.wu@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230607122411.3394702-1-fei2.wu@intel.com> References: <20230607122411.3394702-1-fei2.wu@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.31; envelope-from=fei2.wu@intel.com; helo=mga06.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: Fei Wu --- docs/devel/tcg-tbstats.rst | 97 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 docs/devel/tcg-tbstats.rst diff --git a/docs/devel/tcg-tbstats.rst b/docs/devel/tcg-tbstats.rst new file mode 100644 index 0000000000..dd611e41f3 --- /dev/null +++ b/docs/devel/tcg-tbstats.rst @@ -0,0 +1,97 @@ +============ +TBStatistics +============ + +What is TBStatistics +==================== + +TBStatistics (tb_stats) is a tool to gather various internal information of TCG +during binary translation, this allows us to identify such as hottest TBs, +guest to host instruction translation ratio, number of spills during register +allocation and more. + + +How to use TBStatistics +======================= + +1. HMP interface +---------------- + +TBStatistics provides HMP interface, you can try the following examples after +connecting to the monitor. + +* First check the help info:: + + (qemu) help tb_stats + tb_stats command [flag] -- Control tb statistics collection:tb_stats (start|stop|status) [all|jit|exec] + + (qemu) help info tb-list + info tb-list [number sortedby] -- show a [number] translated blocks sorted by [sortedby]sortedby opts: hotness hg spills + + (qemu) help info tb + info tb id [flag1,flag2,...] -- show information about one translated block by id.dump flags can be used to set dump code level: out_asm in_asm op + +* Enable TBStatistics:: + + (qemu) tb_stats start all + (qemu) + +* Get interested TB list:: + + (qemu) info tb-list 2 + TB id:0 | phys:0x79bca0 virt:0xffffffff8059bca0 flags:0x01024001 0 inv/1 + | exec:1464084/0 guest inst cov:0.15% + | trans:1 ints: g:3 op:16 op_opt:15 spills:0 + | h/g (host bytes / guest insts): 64.000000 + + TB id:1 | phys:0x2adf0c virt:0xffffffff800adf0c flags:0x01024001 0 inv/1 + | exec:1033298/0 guest inst cov:0.28% + | trans:1 ints: g:8 op:35 op_opt:33 spills:0 + | h/g (host bytes / guest insts): 86.000000 + +* Dive into the specific TB:: + + (qemu) info tb 1 + ------------------------------ + + TB id:0 | phys:0x79bca0 virt:0xffffffff8059bca0 flags:0x01024001 7 inv/19 + | exec:2038349/0 guest inst cov:0.15% + | trans:19 ints: g:3 op:16 op_opt:15 spills:0 + | h/g (host bytes / guest insts): 64.000000 + + ------------------------------ + +* Stop TBStatistics after investigation, this will disable TBStatistics completely.:: + + (qemu) tb_stats stop + (qemu) + +* Definitely, TBStatistics can be restarted for another round of investigation.:: + + (qemu) tb_stats start all + (qemu) + + +2. Dump at exit +--------------- + +New command line options have been added to enable dump TB information at exit::: + + -d tb_stats_{all,jit,exec}[:dump_num_at_exit] + +e.g. starting qemu like this::: + + -d tb_stats_all:2 + +Qemu prints the following at exit::: + + QEMU: Terminated + TB id:1 | phys:0x61be02 virt:0xffffffff8041be02 flags:0x01024001 0 inv/1 + | exec:72739176/0 guest inst cov:20.22% + | trans:1 ints: g:9 op:35 op_opt:33 spills:0 + | h/g (host bytes / guest insts): 51.555557 + + TB id:2 | phys:0x61bc66 virt:0xffffffff8041bc66 flags:0x01024001 0 inv/1 + | exec:25069507/0 guest inst cov:0.77% + | trans:1 ints: g:1 op:15 op_opt:14 spills:0 + | h/g (host bytes / guest insts): 128.000000