From fe4db84d49545e669806d0cce12b3aa384e04ac3 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Tue, 4 Oct 2016 14:35:52 +0100 Subject: [PATCH] trace: provide mechanism for registering trace events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the notion of there being a single global array of trace events, by introducing a method for registering groups of events. The module_call_init() needs to be invoked at the start of any program that wants to make use of the trace support. Currently this covers system emulators qemu-nbd, qemu-img and qemu-io. [Squashed the following fix from Daniel P. Berrange : linux-user/bsd-user: initialize trace events subsystem The bsd-user/linux-user programs make use of the CPU emulation code and this now requires that the trace events subsystem is enabled, otherwise it'll crash trying to allocate an empty trace events bitmap for the CPU object. --Stefan] Reviewed-by: Stefan Hajnoczi Reviewed-by: LluĂ­s Vilanova Signed-off-by: Daniel P. Berrange Message-id: 1475588159-30598-14-git-send-email-berrange@redhat.com Signed-off-by: Stefan Hajnoczi --- bsd-user/main.c | 1 + include/qemu/module.h | 2 ++ linux-user/main.c | 1 + qemu-img.c | 1 + qemu-io.c | 1 + qemu-nbd.c | 1 + scripts/tracetool/format/events_c.py | 6 ++++++ trace/control-internal.h | 4 +++- trace/control.c | 25 +++++++++++++++++++++++-- trace/control.h | 1 + vl.c | 2 ++ 11 files changed, 42 insertions(+), 3 deletions(-) diff --git a/bsd-user/main.c b/bsd-user/main.c index d8367bda46..4fd7b6396d 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -740,6 +740,7 @@ int main(int argc, char **argv) if (argc <= 1) usage(); + module_call_init(MODULE_INIT_TRACE); qemu_init_cpu_list(); module_call_init(MODULE_INIT_QOM); diff --git a/include/qemu/module.h b/include/qemu/module.h index dc2c9d4c4e..877cca7d7b 100644 --- a/include/qemu/module.h +++ b/include/qemu/module.h @@ -44,6 +44,7 @@ typedef enum { MODULE_INIT_OPTS, MODULE_INIT_QAPI, MODULE_INIT_QOM, + MODULE_INIT_TRACE, MODULE_INIT_MAX } module_init_type; @@ -51,6 +52,7 @@ typedef enum { #define opts_init(function) module_init(function, MODULE_INIT_OPTS) #define qapi_init(function) module_init(function, MODULE_INIT_QAPI) #define type_init(function) module_init(function, MODULE_INIT_QOM) +#define trace_init(function) module_init(function, MODULE_INIT_TRACE) #define block_module_load_one(lib) module_load_one("block-", lib) diff --git a/linux-user/main.c b/linux-user/main.c index 9e4b430d66..0e31dad684 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -4158,6 +4158,7 @@ int main(int argc, char **argv, char **envp) int ret; int execfd; + module_call_init(MODULE_INIT_TRACE); qemu_init_cpu_list(); module_call_init(MODULE_INIT_QOM); diff --git a/qemu-img.c b/qemu-img.c index ceffefeacb..02c07b913d 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -4165,6 +4165,7 @@ int main(int argc, char **argv) signal(SIGPIPE, SIG_IGN); #endif + module_call_init(MODULE_INIT_TRACE); error_set_progname(argv[0]); qemu_init_exec_dir(argv[0]); diff --git a/qemu-io.c b/qemu-io.c index db129eac5f..23a229f880 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -467,6 +467,7 @@ int main(int argc, char **argv) signal(SIGPIPE, SIG_IGN); #endif + module_call_init(MODULE_INIT_TRACE); progname = basename(argv[0]); qemu_init_exec_dir(argv[0]); diff --git a/qemu-nbd.c b/qemu-nbd.c index 705b95ec29..cca4a983b7 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -533,6 +533,7 @@ int main(int argc, char **argv) sa_sigterm.sa_handler = termsig_handler; sigaction(SIGTERM, &sa_sigterm, NULL); + module_call_init(MODULE_INIT_TRACE); qcrypto_init(&error_fatal); module_call_init(MODULE_INIT_QOM); diff --git a/scripts/tracetool/format/events_c.py b/scripts/tracetool/format/events_c.py index 40ae39568e..88175559de 100644 --- a/scripts/tracetool/format/events_c.py +++ b/scripts/tracetool/format/events_c.py @@ -60,3 +60,9 @@ def generate(events, backend): out(' NULL,', '};', '') + + out('static void trace_register_events(void)', + '{', + ' trace_event_register_group(trace_events);', + '}', + 'trace_init(trace_register_events)') diff --git a/trace/control-internal.h b/trace/control-internal.h index 9abbc96bcb..a9d395a587 100644 --- a/trace/control-internal.h +++ b/trace/control-internal.h @@ -15,7 +15,6 @@ #include "qom/cpu.h" -extern TraceEvent *trace_events[]; extern int trace_events_enabled_count; @@ -83,4 +82,7 @@ static inline bool trace_event_get_vcpu_state_dynamic(CPUState *vcpu, return trace_event_get_vcpu_state_dynamic_by_vcpu_id(vcpu, vcpu_id); } + +void trace_event_register_group(TraceEvent **events); + #endif /* TRACE__CONTROL_INTERNAL_H */ diff --git a/trace/control.c b/trace/control.c index 6b32511d60..a2313273d8 100644 --- a/trace/control.c +++ b/trace/control.c @@ -29,6 +29,13 @@ int trace_events_enabled_count; +typedef struct TraceEventGroup { + TraceEvent **events; +} TraceEventGroup; + +static TraceEventGroup *event_groups; +static size_t nevent_groups; + QemuOptsList qemu_trace_opts = { .name = "trace", .implied_opt_name = "enable", @@ -50,6 +57,14 @@ QemuOptsList qemu_trace_opts = { }; +void trace_event_register_group(TraceEvent **events) +{ + event_groups = g_renew(TraceEventGroup, event_groups, nevent_groups + 1); + event_groups[nevent_groups].events = events; + nevent_groups++; +} + + TraceEvent *trace_event_name(const char *name) { assert(name != NULL); @@ -100,14 +115,20 @@ static bool pattern_glob(const char *pat, const char *ev) void trace_event_iter_init(TraceEventIter *iter, const char *pattern) { iter->event = 0; + iter->group = 0; iter->pattern = pattern; } TraceEvent *trace_event_iter_next(TraceEventIter *iter) { - while (trace_events[iter->event] != NULL) { - TraceEvent *ev = trace_events[iter->event]; + while (iter->group < nevent_groups && + event_groups[iter->group].events[iter->event] != NULL) { + TraceEvent *ev = event_groups[iter->group].events[iter->event]; iter->event++; + if (event_groups[iter->group].events[iter->event] == NULL) { + iter->event = 0; + iter->group++; + } if (!iter->pattern || pattern_glob(iter->pattern, trace_event_get_name(ev))) { diff --git a/trace/control.h b/trace/control.h index cccd2a295e..3f30a0c2b7 100644 --- a/trace/control.h +++ b/trace/control.h @@ -15,6 +15,7 @@ typedef struct TraceEventIter { size_t event; + size_t group; const char *pattern; } TraceEventIter; diff --git a/vl.c b/vl.c index eb3c5ee348..c657acdd3c 100644 --- a/vl.c +++ b/vl.c @@ -3024,6 +3024,8 @@ int main(int argc, char **argv, char **envp) Error *err = NULL; bool list_data_dirs = false; + module_call_init(MODULE_INIT_TRACE); + qemu_init_cpu_list(); qemu_init_cpu_loop(); qemu_mutex_lock_iothread();