From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Vasilev Oleg" <vasilev.oleg@huawei.com>,
"Richard Henderson" <richard.henderson@linaro.org>,
aaron@os.amperecomputing.com, robhenry@microsoft.com,
mahmoudabdalghany@outlook.com, minyihh@uci.edu, cota@braap.org,
Luke.Craig@ll.mit.edu, "Alexandre Iooss" <erdnaxe@crans.org>,
kuhn.chenqun@huawei.com, ma.mandourr@gmail.com,
"Alex Bennée" <alex.bennee@linaro.org>
Subject: [PATCH v1 20/22] tests/plugins: add instruction matching to libinsn.so
Date: Mon, 24 Jan 2022 20:16:06 +0000 [thread overview]
Message-ID: <20220124201608.604599-21-alex.bennee@linaro.org> (raw)
In-Reply-To: <20220124201608.604599-1-alex.bennee@linaro.org>
This adds simple instruction matching to the libinsn.so plugin which
is useful for examining the execution distance between instructions.
For example to track how often we flush in ARM due to TLB updates:
-plugin ./tests/plugin/libinsn.so,match=tlbi
which leads to output like this:
0xffffffc01018fa00, tlbi aside1is, x0, 339, 32774 match hits, 23822 since last, avg 47279
0xffffffc01018fa00, tlbi aside1is, x0, 340, 32775 match hits, 565051 since last, avg 47295
0xffffffc0101915a4, tlbi vae1is, x0, 155, 32776 match hits, 151135 since last, avg 47298
0xffffffc01018fc60, tlbi vae1is, x4, 224, 32777 match hits, 814 since last, avg 47297
0xffffffc010194a44, tlbi vale1is, x1, 8835, 32778 match hits, 52027 since last, avg 47297
0xffffffc010194a44, tlbi vale1is, x1, 8836, 32779 match hits, 8347 since last, avg 47296
0xffffffc010194a44, tlbi vale1is, x1, 8837, 32780 match hits, 33677 since last, avg 47295
showing we do some sort of TLBI invalidation every 47 thousand
instructions.
Cc: Vasilev Oleg <vasilev.oleg@huawei.com>
Cc: Richard Henderson <richard.henderson@linaro.org>
Cc: Emilio Cota <cota@braap.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
tests/plugin/insn.c | 88 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 87 insertions(+), 1 deletion(-)
diff --git a/tests/plugin/insn.c b/tests/plugin/insn.c
index d5a0a08cb4..3f48c86fd7 100644
--- a/tests/plugin/insn.c
+++ b/tests/plugin/insn.c
@@ -28,9 +28,25 @@ static uint64_t inline_insn_count;
static bool do_inline;
static bool do_size;
-static bool do_frequency;
static GArray *sizes;
+typedef struct {
+ char *match_string;
+ uint64_t hits[MAX_CPUS];
+ uint64_t last_hit[MAX_CPUS];
+ uint64_t total_delta[MAX_CPUS];
+ GPtrArray *history[MAX_CPUS];
+} Match;
+
+static GArray *matches;
+
+typedef struct {
+ Match *match;
+ uint64_t vaddr;
+ uint64_t hits;
+ char *disas;
+} Instruction;
+
static void vcpu_insn_exec_before(unsigned int cpu_index, void *udata)
{
unsigned int i = cpu_index % MAX_CPUS;
@@ -45,6 +61,36 @@ static void vcpu_insn_exec_before(unsigned int cpu_index, void *udata)
c->insn_count++;
}
+static void vcpu_insn_matched_exec_before(unsigned int cpu_index, void *udata)
+{
+ unsigned int i = cpu_index % MAX_CPUS;
+ Instruction *insn = (Instruction *) udata;
+ Match *match = insn->match;
+ g_autoptr(GString) ts = g_string_new("");
+
+ insn->hits++;
+ g_string_append_printf(ts, "0x%" PRIx64 ", %s, % "PRId64,
+ insn->vaddr, insn->disas, insn->hits);
+
+ uint64_t icount = counts[i].insn_count;
+ uint64_t delta = icount - match->last_hit[i];
+
+ match->hits[i]++;
+ match->total_delta[i] += delta;
+
+ g_string_append_printf(ts,
+ ", %"PRId64" match hits, %"PRId64
+ " since last, avg %"PRId64"\n",
+ match->hits[i], delta,
+ match->total_delta[i] / match->hits[i]);
+
+ match->last_hit[i] = icount;
+
+ qemu_plugin_outs(ts->str);
+
+ g_ptr_array_add(match->history[i], insn);
+}
+
static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
{
size_t n = qemu_plugin_tb_n_insns(tb);
@@ -71,6 +117,29 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
unsigned long *cnt = &g_array_index(sizes, unsigned long, sz);
(*cnt)++;
}
+
+ /*
+ * If we are tracking certain instructions we will need more
+ * information about the instruction which we also need to
+ * save if there is a hit.
+ */
+ if (matches) {
+ char *insn_disas = qemu_plugin_insn_disas(insn);
+ int j;
+ for (j = 0; j < matches->len; j++) {
+ Match *m = &g_array_index(matches, Match, j);
+ if (g_str_has_prefix(insn_disas, m->match_string)) {
+ Instruction *rec = g_new0(Instruction, 1);
+ rec->disas = g_strdup(insn_disas);
+ rec->vaddr = qemu_plugin_insn_vaddr(insn);
+ rec->match = m;
+ qemu_plugin_register_vcpu_insn_exec_cb(
+ insn, vcpu_insn_matched_exec_before,
+ QEMU_PLUGIN_CB_NO_REGS, rec);
+ }
+ }
+ g_free(insn_disas);
+ }
}
}
@@ -105,6 +174,21 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
qemu_plugin_outs(out->str);
}
+
+/* Add a match to the array of matches */
+static void parse_match(char *match)
+{
+ Match new_match = { .match_string = match };
+ int i;
+ for (i = 0; i < MAX_CPUS; i++) {
+ new_match.history[i] = g_ptr_array_new();
+ }
+ if (!matches) {
+ matches = g_array_new(false, true, sizeof(Match));
+ }
+ g_array_append_val(matches, new_match);
+}
+
QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
const qemu_info_t *info,
int argc, char **argv)
@@ -122,6 +206,8 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
fprintf(stderr, "boolean argument parsing failed: %s\n", opt);
return -1;
}
+ } else if (g_strcmp0(tokens[0], "match") == 0) {
+ parse_match(tokens[1]);
} else {
fprintf(stderr, "option parsing failed: %s\n", opt);
return -1;
--
2.30.2
next prev parent reply other threads:[~2022-01-24 20:32 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-24 20:15 [PATCH v1 00/22] testing and plugin updates Alex Bennée
2022-01-24 20:15 ` [PATCH v1 01/22] tests/Makefile.include: clean-up old code Alex Bennée
2022-01-24 20:38 ` Philippe Mathieu-Daudé via
2022-01-24 20:15 ` [PATCH v1 02/22] tests/qtest: enable more vhost-user tests by default Alex Bennée
2022-01-25 8:18 ` Thomas Huth
2022-01-24 20:15 ` [PATCH v1 03/22] Makefile: also remove .gcno files when cleaning Alex Bennée
2022-01-25 7:40 ` Thomas Huth
2022-01-24 20:15 ` [PATCH v1 04/22] .gitignore: add .gcov pattern Alex Bennée
2022-01-24 20:38 ` Philippe Mathieu-Daudé via
2022-01-24 20:15 ` [PATCH v1 05/22] MAINTAINERS: Cover lcitool submodule with build test / automation Alex Bennée
2022-01-24 20:15 ` [PATCH v1 06/22] gitmodules: Correct libvirt-ci submodule URL Alex Bennée
2022-01-24 20:15 ` [PATCH v1 07/22] tests/lcitool: Include local qemu.yml when refreshing cirrus-ci files Alex Bennée
2022-01-24 20:15 ` [PATCH v1 08/22] drop libxml2 checks since libxml is not actually used (for parallels) Alex Bennée
2022-01-25 21:29 ` Vladimir Sementsov-Ogievskiy
2022-01-24 20:15 ` [PATCH v1 09/22] tests/lcitool: Refresh submodule and remove libxml2 Alex Bennée
2022-01-25 10:23 ` Thomas Huth
2022-01-25 10:48 ` Philippe Mathieu-Daudé via
2022-01-24 20:15 ` [PATCH v1 10/22] tests: Manually remove libxml2 on MSYS2 runners Alex Bennée
2022-01-24 20:15 ` [PATCH v1 11/22] tests/lcitool: Install libibumad to cover RDMA on Debian based distros Alex Bennée
2022-01-24 20:15 ` [PATCH v1 12/22] plugins: stxp test case from Aaron (!upstream) Alex Bennée
2022-01-25 8:17 ` Thomas Huth
2022-02-01 14:58 ` Aaron Lindsay via
2022-02-01 15:00 ` Aaron Lindsay via
2022-02-01 15:29 ` Alex Bennée
2022-02-02 14:17 ` Aaron Lindsay via
2022-01-24 20:15 ` [PATCH v1 13/22] docs: remove references to TCG tracing Alex Bennée
2022-01-24 20:16 ` [PATCH v1 14/22] tracing: remove TCG memory access tracing Alex Bennée
2022-01-24 22:06 ` Philippe Mathieu-Daudé via
2022-01-24 20:16 ` [PATCH v1 15/22] tracing: remove the trace-tcg includes from the build Alex Bennée
2022-01-24 22:07 ` Philippe Mathieu-Daudé via
2022-01-24 20:16 ` [PATCH v1 16/22] tracing: excise the tcg related from tracetool Alex Bennée
2022-01-24 20:16 ` [PATCH v1 17/22] plugins: add helper functions for coverage plugins Alex Bennée
2022-01-24 20:16 ` [PATCH v1 18/22] contrib/plugins: add a drcov plugin Alex Bennée
2022-01-24 20:16 ` [PATCH v1 19/22] tests/plugin: allow libinsn.so per-CPU counts Alex Bennée
2022-01-24 20:16 ` Alex Bennée [this message]
2022-01-24 22:13 ` [PATCH v1 20/22] tests/plugins: add instruction matching to libinsn.so Philippe Mathieu-Daudé via
2022-01-24 20:16 ` [PATCH v1 21/22] target/i386: use CPU_LOG_INT for IRQ servicing Alex Bennée
2022-01-24 22:14 ` Philippe Mathieu-Daudé via
2022-01-26 21:33 ` Richard Henderson
2022-01-24 20:16 ` [PATCH v1 22/22] plugins: move reset of plugin data to tb_start Alex Bennée
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220124201608.604599-21-alex.bennee@linaro.org \
--to=alex.bennee@linaro.org \
--cc=Luke.Craig@ll.mit.edu \
--cc=aaron@os.amperecomputing.com \
--cc=cota@braap.org \
--cc=erdnaxe@crans.org \
--cc=kuhn.chenqun@huawei.com \
--cc=ma.mandourr@gmail.com \
--cc=mahmoudabdalghany@outlook.com \
--cc=minyihh@uci.edu \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=robhenry@microsoft.com \
--cc=vasilev.oleg@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).