From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-devel@nongnu.org
Cc: robert.foley@futurewei.com,
"Richard Henderson" <richard.henderson@linaro.org>,
peter.puhov@futurewei.com, aaron@os.amperecomputing.com,
cota@braap.org, "Alex Bennée" <alex.bennee@linaro.org>
Subject: [PATCH v6 48/54] tests/plugin: add a hotblocks plugin
Date: Thu, 17 Oct 2019 14:16:09 +0100 [thread overview]
Message-ID: <20191017131615.19660-49-alex.bennee@linaro.org> (raw)
In-Reply-To: <20191017131615.19660-1-alex.bennee@linaro.org>
This is a simple plugin to track which translation blocks are call
most often. As we don't have a view of the internals of TCG we can
only work by the address of the start of the block so we also need to
tracks how often the address is translated.
As there will be multiple blocks starting at the same address. We can
try and work around this by futzing the value to feed to the hash with
the insn count.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
v5
- handle 0 length report
v6
- init api update
- use plugin_outs
squash! tests/plugin: add a hotblocks plugin
---
tests/plugin/Makefile | 1 +
tests/plugin/hotblocks.c | 143 +++++++++++++++++++++++++++++++++++++++
2 files changed, 144 insertions(+)
create mode 100644 tests/plugin/hotblocks.c
diff --git a/tests/plugin/Makefile b/tests/plugin/Makefile
index f9a3546ea3..e74940eaac 100644
--- a/tests/plugin/Makefile
+++ b/tests/plugin/Makefile
@@ -10,6 +10,7 @@ NAMES += bb
NAMES += empty
NAMES += insn
NAMES += mem
+NAMES += hotblocks
SONAMES := $(addsuffix .so,$(addprefix lib,$(NAMES)))
diff --git a/tests/plugin/hotblocks.c b/tests/plugin/hotblocks.c
new file mode 100644
index 0000000000..1bd183849a
--- /dev/null
+++ b/tests/plugin/hotblocks.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2019, Alex Bennée <alex.bennee@linaro.org>
+ *
+ * License: GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include <inttypes.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <glib.h>
+
+#include <qemu-plugin.h>
+
+static bool do_inline;
+
+/* Plugins need to take care of their own locking */
+static GMutex lock;
+static GHashTable *hotblocks;
+static guint64 limit = 20;
+
+/*
+ * Counting Structure
+ *
+ * The internals of the TCG are not exposed to plugins so we can only
+ * get the starting PC for each block. We cheat this slightly by
+ * xor'ing the number of instructions to the hash to help
+ * differentiate.
+ */
+typedef struct {
+ uint64_t start_addr;
+ uint64_t exec_count;
+ int trans_count;
+ unsigned long insns;
+} ExecCount;
+
+static gint cmp_exec_count(gconstpointer a, gconstpointer b)
+{
+ ExecCount *ea = (ExecCount *) a;
+ ExecCount *eb = (ExecCount *) b;
+ return ea->exec_count > eb->exec_count ? -1 : 1;
+}
+
+static void plugin_exit(qemu_plugin_id_t id, void *p)
+{
+ g_autoptr(GString) report = g_string_new("collected ");
+ GList *counts, *it;
+ int i;
+
+ g_mutex_lock(&lock);
+ g_string_append_printf(report, "%d entries in the hash table\n",
+ g_hash_table_size(hotblocks));
+ counts = g_hash_table_get_values(hotblocks);
+ it = g_list_sort(counts, cmp_exec_count);
+
+ if (it) {
+ g_string_append_printf(report, "pc, tcount, icount, ecount\n");
+
+ for (i = 0; i < limit && it->next; i++, it = it->next) {
+ ExecCount *rec = (ExecCount *) it->data;
+ g_string_append_printf(report, "%#016"PRIx64", %d, %ld, %"PRId64"\n",
+ rec->start_addr, rec->trans_count,
+ rec->insns, rec->exec_count);
+ }
+
+ g_list_free(it);
+ g_mutex_unlock(&lock);
+ }
+
+ qemu_plugin_outs(report->str);
+}
+
+static void plugin_init(void)
+{
+ hotblocks = g_hash_table_new(NULL, g_direct_equal);
+}
+
+static void vcpu_tb_exec(unsigned int cpu_index, void *udata)
+{
+ ExecCount *cnt;
+ uint64_t hash = (uint64_t) udata;
+
+ g_mutex_lock(&lock);
+ cnt = (ExecCount *) g_hash_table_lookup(hotblocks, (gconstpointer) hash);
+ /* should always succeed */
+ g_assert(cnt);
+ cnt->exec_count++;
+ g_mutex_unlock(&lock);
+}
+
+/*
+ * When do_inline we ask the plugin to increment the counter for us.
+ * Otherwise a helper is inserted which calls the vcpu_tb_exec
+ * callback.
+ */
+static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
+{
+ ExecCount *cnt;
+ uint64_t pc = qemu_plugin_tb_vaddr(tb);
+ unsigned long insns = qemu_plugin_tb_n_insns(tb);
+ uint64_t hash = pc ^ insns;
+
+ g_mutex_lock(&lock);
+ cnt = (ExecCount *) g_hash_table_lookup(hotblocks, (gconstpointer) hash);
+ if (cnt) {
+ cnt->trans_count++;
+ } else {
+ cnt = g_new0(ExecCount, 1);
+ cnt->start_addr = pc;
+ cnt->trans_count = 1;
+ cnt->insns = insns;
+ g_hash_table_insert(hotblocks, (gpointer) hash, (gpointer) cnt);
+ }
+
+ g_mutex_unlock(&lock);
+
+ if (do_inline) {
+ qemu_plugin_register_vcpu_tb_exec_inline(tb, QEMU_PLUGIN_INLINE_ADD_U64,
+ &cnt->exec_count, 1);
+ } else {
+ qemu_plugin_register_vcpu_tb_exec_cb(tb, vcpu_tb_exec,
+ QEMU_PLUGIN_CB_NO_REGS,
+ (void *)hash);
+ }
+}
+
+QEMU_PLUGIN_EXPORT
+int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,
+ int argc, char **argv)
+{
+ if (argc && strcmp(argv[0], "inline") == 0) {
+ do_inline = true;
+ }
+
+ plugin_init();
+
+ qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans);
+ qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
+ return 0;
+}
--
2.20.1
next prev parent reply other threads:[~2019-10-17 13:53 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-17 13:15 [PATCH for 4.2 v6 00/54] Support for TCG plugins Alex Bennée
2019-10-17 13:15 ` [PATCH v6 01/54] trace: expand mem_info:size_shift to 4 bits Alex Bennée
2019-10-17 13:15 ` [PATCH v6 02/54] trace: add mmu_index to mem_info Alex Bennée
2019-10-17 13:15 ` [PATCH v6 03/54] cpu: introduce cpu_in_exclusive_context() Alex Bennée
2019-10-17 13:15 ` [PATCH v6 04/54] translate-all: use cpu_in_exclusive_work_context() in tb_flush Alex Bennée
2019-10-17 13:15 ` [PATCH v6 05/54] docs/devel: add plugins.rst design document Alex Bennée
2019-10-17 13:15 ` [PATCH v6 06/54] plugin: add user-facing API Alex Bennée
2019-10-17 13:15 ` [PATCH v6 07/54] plugin: add core code Alex Bennée
2019-10-17 13:15 ` [PATCH v6 08/54] plugin: add implementation of the api Alex Bennée
2019-10-17 13:15 ` [PATCH v6 09/54] queue: add QTAILQ_REMOVE_SEVERAL Alex Bennée
2019-10-17 13:15 ` [PATCH v6 10/54] cputlb: document get_page_addr_code Alex Bennée
2019-10-17 13:15 ` [PATCH v6 11/54] cputlb: introduce get_page_addr_code_hostp Alex Bennée
2019-10-17 13:15 ` [PATCH v6 12/54] tcg: add tcg_gen_st_ptr Alex Bennée
2019-10-17 13:15 ` [PATCH v6 13/54] plugin-gen: add module for TCG-related code Alex Bennée
2019-10-17 13:15 ` [PATCH v6 14/54] atomic_template: add inline trace/plugin helpers Alex Bennée
2019-10-17 13:15 ` [PATCH v6 15/54] tcg: let plugins instrument virtual memory accesses Alex Bennée
2019-10-17 13:15 ` [PATCH v6 16/54] plugins: implement helpers for resolving hwaddr Alex Bennée
2019-10-17 13:15 ` [PATCH v6 17/54] translate-all: notify plugin code of tb_flush Alex Bennée
2019-10-17 13:15 ` [PATCH v6 18/54] *-user: notify plugin of exit Alex Bennée
2019-10-17 13:15 ` [PATCH v6 19/54] *-user: plugin syscalls Alex Bennée
2019-10-17 13:15 ` [PATCH v6 20/54] cpu: hook plugin vcpu events Alex Bennée
2019-10-17 13:15 ` [PATCH v6 21/54] plugin-gen: add plugin_insn_append Alex Bennée
2019-10-17 13:15 ` [PATCH v6 22/54] translator: add translator_ld{ub,sw,uw,l,q} Alex Bennée
2019-10-17 13:15 ` [PATCH v6 23/54] target/arm: fetch code with translator_ld Alex Bennée
2019-10-17 13:15 ` [PATCH v6 24/54] target/ppc: " Alex Bennée
2019-10-17 13:15 ` [PATCH v6 25/54] target/sh4: " Alex Bennée
2019-10-17 13:15 ` [PATCH v6 26/54] target/i386: " Alex Bennée
2019-10-17 13:15 ` [PATCH v6 27/54] target/hppa: " Alex Bennée
2019-10-17 13:15 ` [PATCH v6 28/54] target/m68k: " Alex Bennée
2019-10-17 13:15 ` [PATCH v6 29/54] target/alpha: " Alex Bennée
2019-10-17 13:15 ` [PATCH v6 30/54] target/riscv: " Alex Bennée
2019-10-17 13:15 ` [PATCH v6 31/54] target/sparc: " Alex Bennée
2019-10-17 13:15 ` [PATCH v6 32/54] target/xtensa: " Alex Bennée
2019-10-17 13:15 ` [PATCH v6 33/54] target/openrisc: " Alex Bennée
2019-10-17 13:15 ` [PATCH v6 34/54] translator: inject instrumentation from plugins Alex Bennée
2019-10-17 13:15 ` [PATCH v6 35/54] configure: add --enable-plugins Alex Bennée
2019-10-17 13:15 ` [PATCH v6 36/54] plugin: add API symbols to qemu-plugins.symbols Alex Bennée
2019-10-17 13:15 ` [PATCH v6 37/54] plugin: expand the plugin_init function to include an info block Alex Bennée
2019-10-18 15:32 ` Aaron Lindsay OS
2019-10-18 15:54 ` Alex Bennée
2019-10-22 14:04 ` Aaron Lindsay OS
2019-10-24 13:09 ` Alex Bennée
2019-10-17 13:15 ` [PATCH v6 38/54] plugin: add qemu_plugin_insn_disas helper Alex Bennée
2019-10-17 13:16 ` [PATCH v6 39/54] plugin: add qemu_plugin_outs helper Alex Bennée
2019-10-22 14:07 ` Aaron Lindsay OS
2019-10-17 13:16 ` [PATCH v6 40/54] vl: support -plugin option Alex Bennée
2019-10-17 13:16 ` [PATCH v6 41/54] linux-user: " Alex Bennée
2019-10-17 13:16 ` [PATCH v6 42/54] tests/plugin: add sample plugins Alex Bennée
2019-10-17 13:16 ` [PATCH v6 43/54] tests/tcg/Makefile.target: fix path to config-host.mak Alex Bennée
2019-10-17 13:16 ` [PATCH v6 44/54] tests/tcg: set QEMU_OPTS for all cris runs Alex Bennée
2019-10-17 13:16 ` [PATCH v6 45/54] tests/tcg: move "virtual" tests to EXTRA_TESTS Alex Bennée
2019-10-17 13:16 ` [PATCH v6 46/54] tests/tcg: drop test-i386-fprem from TESTS when not SLOW Alex Bennée
2019-10-17 13:16 ` [PATCH v6 47/54] tests/tcg: enable plugin testing Alex Bennée
2019-10-17 13:16 ` Alex Bennée [this message]
2019-10-17 13:16 ` [PATCH v6 49/54] tests/plugin: add instruction execution breakdown Alex Bennée
2019-10-17 13:16 ` [PATCH v6 50/54] tests/plugin: add hotpages to analyse memory access patterns Alex Bennée
2019-10-17 13:16 ` [PATCH v6 51/54] accel/stubs: reduce headers from tcg-stub Alex Bennée
2019-10-17 13:16 ` [PATCH v6 52/54] include/exec: wrap cpu_ldst.h in CONFIG_TCG Alex Bennée
2019-10-17 13:16 ` [PATCH v6 53/54] .travis.yml: add --enable-plugins tests Alex Bennée
2019-10-17 13:16 ` [PATCH v6 54/54] scripts/checkpatch.pl: don't complain about (foo, /* empty */) Alex Bennée
2019-10-22 14:12 ` Aaron Lindsay OS
2019-10-17 19:25 ` [PATCH for 4.2 v6 00/54] Support for TCG plugins no-reply
2019-10-18 7:07 ` no-reply
2019-10-18 17:43 ` no-reply
2019-10-22 11:37 ` 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=20191017131615.19660-49-alex.bennee@linaro.org \
--to=alex.bennee@linaro.org \
--cc=aaron@os.amperecomputing.com \
--cc=cota@braap.org \
--cc=peter.puhov@futurewei.com \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=robert.foley@futurewei.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).