aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--Makefile.target6
-rw-r--r--bsd-user/main.c1
-rw-r--r--include/qemu/module.h2
-rw-r--r--include/qom/cpu.h9
-rw-r--r--include/trace-tcg.h1
-rw-r--r--include/trace.h1
-rw-r--r--linux-user/main.c1
-rw-r--r--monitor.c26
-rw-r--r--net/trace-events16
-rw-r--r--qemu-img.c1
-rw-r--r--qemu-io.c1
-rw-r--r--qemu-nbd.c1
-rw-r--r--qom/cpu.c7
-rwxr-xr-xscripts/simpletrace.py56
-rwxr-xr-xscripts/tracetool.py20
-rw-r--r--scripts/tracetool/__init__.py28
-rw-r--r--scripts/tracetool/backend/__init__.py12
-rw-r--r--scripts/tracetool/backend/dtrace.py4
-rw-r--r--scripts/tracetool/backend/ftrace.py5
-rw-r--r--scripts/tracetool/backend/log.py7
-rw-r--r--scripts/tracetool/backend/simple.py12
-rw-r--r--scripts/tracetool/backend/syslog.py5
-rw-r--r--scripts/tracetool/backend/ust.py4
-rw-r--r--scripts/tracetool/format/__init__.py4
-rw-r--r--scripts/tracetool/format/c.py56
-rw-r--r--scripts/tracetool/format/d.py2
-rw-r--r--scripts/tracetool/format/events_c.py44
-rw-r--r--scripts/tracetool/format/events_h.py60
-rw-r--r--scripts/tracetool/format/h.py37
-rw-r--r--scripts/tracetool/format/simpletrace_stap.py26
-rw-r--r--scripts/tracetool/format/stap.py2
-rw-r--r--scripts/tracetool/format/tcg_h.py8
-rw-r--r--scripts/tracetool/format/tcg_helper_c.py2
-rw-r--r--scripts/tracetool/format/tcg_helper_h.py2
-rw-r--r--scripts/tracetool/format/tcg_helper_wrapper_h.py2
-rw-r--r--scripts/tracetool/format/ust_events_c.py2
-rw-r--r--scripts/tracetool/format/ust_events_h.py9
-rw-r--r--stubs/trace-control.c9
-rw-r--r--trace-events18
-rw-r--r--trace/Makefile.objs46
-rw-r--r--trace/control-internal.h48
-rw-r--r--trace/control-target.c35
-rw-r--r--trace/control.c123
-rw-r--r--trace/control.h112
-rw-r--r--trace/event-internal.h18
-rw-r--r--trace/ftrace.c6
-rw-r--r--trace/qmp.c16
-rw-r--r--trace/simple.c41
-rw-r--r--trace/simple.h6
-rw-r--r--vl.c2
51 files changed, 504 insertions, 461 deletions
diff --git a/Makefile b/Makefile
index 5f6acaed3b..3bcb0565b6 100644
--- a/Makefile
+++ b/Makefile
@@ -56,9 +56,6 @@ GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c
GENERATED_HEADERS += qmp-introspect.h
GENERATED_SOURCES += qmp-introspect.c
-GENERATED_HEADERS += trace/generated-events.h
-GENERATED_SOURCES += trace/generated-events.c
-
GENERATED_HEADERS += trace/generated-tracers.h
ifeq ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace)
GENERATED_HEADERS += trace/generated-tracers-dtrace.h
diff --git a/Makefile.target b/Makefile.target
index 9968871d6e..2c46091225 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -55,7 +55,7 @@ $(QEMU_PROG).stp-installed: $(BUILD_DIR)/trace-events-all
--binary=$(bindir)/$(QEMU_PROG) \
--target-name=$(TARGET_NAME) \
--target-type=$(TARGET_TYPE) \
- < $< > $@,"GEN","$(TARGET_DIR)$(QEMU_PROG).stp-installed")
+ $< > $@,"GEN","$(TARGET_DIR)$(QEMU_PROG).stp-installed")
$(QEMU_PROG).stp: $(BUILD_DIR)/trace-events-all
$(call quiet-command,$(TRACETOOL) \
@@ -64,14 +64,14 @@ $(QEMU_PROG).stp: $(BUILD_DIR)/trace-events-all
--binary=$(realpath .)/$(QEMU_PROG) \
--target-name=$(TARGET_NAME) \
--target-type=$(TARGET_TYPE) \
- < $< > $@,"GEN","$(TARGET_DIR)$(QEMU_PROG).stp")
+ $< > $@,"GEN","$(TARGET_DIR)$(QEMU_PROG).stp")
$(QEMU_PROG)-simpletrace.stp: $(BUILD_DIR)/trace-events-all
$(call quiet-command,$(TRACETOOL) \
--format=simpletrace-stap \
--backends=$(TRACE_BACKENDS) \
--probe-prefix=qemu.$(TARGET_TYPE).$(TARGET_NAME) \
- < $< > $@,"GEN","$(TARGET_DIR)$(QEMU_PROG)-simpletrace.stp")
+ $< > $@,"GEN","$(TARGET_DIR)$(QEMU_PROG)-simpletrace.stp")
else
stap:
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/include/qom/cpu.h b/include/qom/cpu.h
index 22b54d6d93..6d481a1dc0 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -27,7 +27,6 @@
#include "qemu/bitmap.h"
#include "qemu/queue.h"
#include "qemu/thread.h"
-#include "trace/generated-events.h"
typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
void *opaque);
@@ -345,8 +344,12 @@ struct CPUState {
struct KVMState *kvm_state;
struct kvm_run *kvm_run;
- /* Used for events with 'vcpu' and *without* the 'disabled' properties */
- DECLARE_BITMAP(trace_dstate, TRACE_VCPU_EVENT_COUNT);
+ /*
+ * Used for events with 'vcpu' and *without* the 'disabled' properties.
+ * Dynamically allocated based on bitmap requried to hold up to
+ * trace_get_vcpu_event_count() entries.
+ */
+ unsigned long *trace_dstate;
/* TODO Move common fields from CPUArchState here. */
int cpu_index; /* used by alpha TCG */
diff --git a/include/trace-tcg.h b/include/trace-tcg.h
index edab4b159c..da68608c85 100644
--- a/include/trace-tcg.h
+++ b/include/trace-tcg.h
@@ -2,6 +2,5 @@
#define TRACE_TCG_H
#include "trace/generated-tcg-tracers.h"
-#include "trace/generated-events.h"
#endif /* TRACE_TCG_H */
diff --git a/include/trace.h b/include/trace.h
index 9a01e4454b..ac9ff3dddd 100644
--- a/include/trace.h
+++ b/include/trace.h
@@ -2,6 +2,5 @@
#define TRACE_H
#include "trace/generated-tracers.h"
-#include "trace/generated-events.h"
#endif /* TRACE_H */
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/monitor.c b/monitor.c
index b07f254698..8728dd9fa5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3330,13 +3330,14 @@ void info_trace_events_completion(ReadLineState *rs, int nb_args, const char *st
len = strlen(str);
readline_set_completion_index(rs, len);
if (nb_args == 2) {
- TraceEventID id;
- for (id = 0; id < trace_event_count(); id++) {
- const char *event_name = trace_event_get_name(trace_event_id(id));
- if (!strncmp(str, event_name, len)) {
- readline_add_completion(rs, event_name);
- }
+ TraceEventIter iter;
+ TraceEvent *ev;
+ char *pattern = g_strdup_printf("%s*", str);
+ trace_event_iter_init(&iter, pattern);
+ while ((ev = trace_event_iter_next(&iter)) != NULL) {
+ readline_add_completion(rs, trace_event_get_name(ev));
}
+ g_free(pattern);
}
}
@@ -3347,13 +3348,14 @@ void trace_event_completion(ReadLineState *rs, int nb_args, const char *str)
len = strlen(str);
readline_set_completion_index(rs, len);
if (nb_args == 2) {
- TraceEventID id;
- for (id = 0; id < trace_event_count(); id++) {
- const char *event_name = trace_event_get_name(trace_event_id(id));
- if (!strncmp(str, event_name, len)) {
- readline_add_completion(rs, event_name);
- }
+ TraceEventIter iter;
+ TraceEvent *ev;
+ char *pattern = g_strdup_printf("%s*", str);
+ trace_event_iter_init(&iter, pattern);
+ while ((ev = trace_event_iter_next(&iter)) != NULL) {
+ readline_add_completion(rs, trace_event_get_name(ev));
}
+ g_free(pattern);
} else if (nb_args == 3) {
add_completion_option(rs, str, "on");
add_completion_option(rs, str, "off");
diff --git a/net/trace-events b/net/trace-events
index 65c46a48fb..d67f048825 100644
--- a/net/trace-events
+++ b/net/trace-events
@@ -2,3 +2,19 @@
# net/vhost-user.c
vhost_user_event(const char *chr, int event) "chr: %s got event: %d"
+
+# net/colo.c
+colo_proxy_main(const char *chr) ": %s"
+
+# net/colo-compare.c
+colo_compare_main(const char *chr) ": %s"
+colo_compare_udp_miscompare(const char *sta, int size) ": %s = %d"
+colo_compare_icmp_miscompare(const char *sta, int size) ": %s = %d"
+colo_compare_ip_info(int psize, const char *sta, const char *stb, int ssize, const char *stc, const char *std) "ppkt size = %d, ip_src = %s, ip_dst = %s, spkt size = %d, ip_src = %s, ip_dst = %s"
+colo_old_packet_check_found(int64_t old_time) "%" PRId64
+colo_compare_miscompare(void) ""
+
+# net/filter-rewriter.c
+colo_filter_rewriter_debug(void) ""
+colo_filter_rewriter_pkt_info(const char *func, const char *src, const char *dst, uint32_t seq, uint32_t ack, uint32_t flag) "%s: src/dst: %s/%s p: seq/ack=%u/%u flags=%x\n"
+colo_filter_rewriter_conn_offset(uint32_t offset) ": offset=%u\n"
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/qom/cpu.c b/qom/cpu.c
index e765bc0caf..c40f774a0c 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -360,12 +360,15 @@ static void cpu_common_initfn(Object *obj)
qemu_mutex_init(&cpu->work_mutex);
QTAILQ_INIT(&cpu->breakpoints);
QTAILQ_INIT(&cpu->watchpoints);
- bitmap_zero(cpu->trace_dstate, TRACE_VCPU_EVENT_COUNT);
+
+ cpu->trace_dstate = bitmap_new(trace_get_vcpu_event_count());
}
static void cpu_common_finalize(Object *obj)
{
- cpu_exec_exit(CPU(obj));
+ CPUState *cpu = CPU(obj);
+ cpu_exec_exit(cpu);
+ g_free(cpu->trace_dstate);
}
static int64_t cpu_common_get_arch_id(CPUState *cpu)
diff --git a/scripts/simpletrace.py b/scripts/simpletrace.py
index 3916c6d14a..4ca903dc0c 100755
--- a/scripts/simpletrace.py
+++ b/scripts/simpletrace.py
@@ -12,13 +12,16 @@
import struct
import re
import inspect
-from tracetool import _read_events, Event
+from tracetool import read_events, Event
from tracetool.backend.simple import is_string
header_event_id = 0xffffffffffffffff
header_magic = 0xf2b177cb0aa429b4
dropped_event_id = 0xfffffffffffffffe
+record_type_mapping = 0
+record_type_event = 1
+
log_header_fmt = '=QQQ'
rec_header_fmt = '=QQII'
@@ -30,14 +33,16 @@ def read_header(fobj, hfmt):
return None
return struct.unpack(hfmt, hdr)
-def get_record(edict, rechdr, fobj):
- """Deserialize a trace record from a file into a tuple (event_num, timestamp, pid, arg1, ..., arg6)."""
+def get_record(edict, idtoname, rechdr, fobj):
+ """Deserialize a trace record from a file into a tuple
+ (name, timestamp, pid, arg1, ..., arg6)."""
if rechdr is None:
return None
- rec = (rechdr[0], rechdr[1], rechdr[3])
if rechdr[0] != dropped_event_id:
event_id = rechdr[0]
- event = edict[event_id]
+ name = idtoname[event_id]
+ rec = (name, rechdr[1], rechdr[3])
+ event = edict[name]
for type, name in event.args:
if is_string(type):
l = fobj.read(4)
@@ -48,15 +53,22 @@ def get_record(edict, rechdr, fobj):
(value,) = struct.unpack('=Q', fobj.read(8))
rec = rec + (value,)
else:
+ rec = ("dropped", rechdr[1], rechdr[3])
(value,) = struct.unpack('=Q', fobj.read(8))
rec = rec + (value,)
return rec
+def get_mapping(fobj):
+ (event_id, ) = struct.unpack('=Q', fobj.read(8))
+ (len, ) = struct.unpack('=L', fobj.read(4))
+ name = fobj.read(len)
+
+ return (event_id, name)
-def read_record(edict, fobj):
+def read_record(edict, idtoname, fobj):
"""Deserialize a trace record from a file into a tuple (event_num, timestamp, pid, arg1, ..., arg6)."""
rechdr = read_header(fobj, rec_header_fmt)
- return get_record(edict, rechdr, fobj) # return tuple of record elements
+ return get_record(edict, idtoname, rechdr, fobj)
def read_trace_header(fobj):
"""Read and verify trace file header"""
@@ -67,20 +79,30 @@ def read_trace_header(fobj):
raise ValueError('Not a valid trace file!')
log_version = header[2]
- if log_version not in [0, 2, 3]:
+ if log_version not in [0, 2, 3, 4]:
raise ValueError('Unknown version of tracelog format!')
- if log_version != 3:
+ if log_version != 4:
raise ValueError('Log format %d not supported with this QEMU release!'
% log_version)
def read_trace_records(edict, fobj):
"""Deserialize trace records from a file, yielding record tuples (event_num, timestamp, pid, arg1, ..., arg6)."""
+ idtoname = {
+ dropped_event_id: "dropped"
+ }
while True:
- rec = read_record(edict, fobj)
- if rec is None:
+ t = fobj.read(8)
+ if len(t) == 0:
break
- yield rec
+ (rectype, ) = struct.unpack('=Q', t)
+ if rectype == record_type_mapping:
+ event_id, name = get_mapping(fobj)
+ idtoname[event_id] = name
+ else:
+ rec = read_record(edict, idtoname, fobj)
+
+ yield rec
class Analyzer(object):
"""A trace file analyzer which processes trace records.
@@ -107,7 +129,7 @@ class Analyzer(object):
def process(events, log, analyzer, read_header=True):
"""Invoke an analyzer on each event in a log."""
if isinstance(events, str):
- events = _read_events(open(events, 'r'))
+ events = read_events(open(events, 'r'))
if isinstance(log, str):
log = open(log, 'rb')
@@ -115,10 +137,10 @@ def process(events, log, analyzer, read_header=True):
read_trace_header(log)
dropped_event = Event.build("Dropped_Event(uint64_t num_events_dropped)")
- edict = {dropped_event_id: dropped_event}
+ edict = {"dropped": dropped_event}
- for num, event in enumerate(events):
- edict[num] = event
+ for event in events:
+ edict[event.name] = event
def build_fn(analyzer, event):
if isinstance(event, str):
@@ -166,7 +188,7 @@ def run(analyzer):
'<trace-file>\n' % sys.argv[0])
sys.exit(1)
- events = _read_events(open(sys.argv[1], 'r'))
+ events = read_events(open(sys.argv[1], 'r'))
process(events, sys.argv[2], analyzer, read_header=read_header)
if __name__ == '__main__':
diff --git a/scripts/tracetool.py b/scripts/tracetool.py
index 7b82959e84..629b2593c8 100755
--- a/scripts/tracetool.py
+++ b/scripts/tracetool.py
@@ -15,6 +15,8 @@ __email__ = "stefanha@linux.vnet.ibm.com"
import sys
import getopt
+import os.path
+import re
from tracetool import error_write, out
import tracetool.backend
@@ -60,6 +62,15 @@ Options:
else:
sys.exit(1)
+def make_group_name(filename):
+ dirname = os.path.realpath(os.path.dirname(filename))
+ basedir = os.path.join(os.path.dirname(__file__), os.pardir)
+ basedir = os.path.realpath(os.path.abspath(basedir))
+ dirname = dirname[len(basedir) + 1:]
+
+ if dirname == "":
+ return "common"
+ return re.sub(r"/|-", "_", dirname)
def main(args):
global _SCRIPT
@@ -129,8 +140,15 @@ def main(args):
if probe_prefix is None:
probe_prefix = ".".join(["qemu", target_type, target_name])
+ if len(args) != 1:
+ error_opt("missing trace-events filepath")
+ with open(args[0], "r") as fh:
+ events = tracetool.read_events(fh)
+
+ group = make_group_name(args[0])
+
try:
- tracetool.generate(sys.stdin, arg_format, arg_backends,
+ tracetool.generate(events, group, arg_format, arg_backends,
binary=binary, probe_prefix=probe_prefix)
except tracetool.TracetoolError as e:
error_opt(str(e))
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index be24039c5e..365446fa53 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -265,11 +265,13 @@ class Event(object):
QEMU_TRACE = "trace_%(name)s"
QEMU_TRACE_TCG = QEMU_TRACE + "_tcg"
+ QEMU_DSTATE = "_TRACE_%(NAME)s_DSTATE"
+ QEMU_EVENT = "_TRACE_%(NAME)s_EVENT"
def api(self, fmt=None):
if fmt is None:
fmt = Event.QEMU_TRACE
- return fmt % {"name": self.name}
+ return fmt % {"name": self.name, "NAME": self.name.upper()}
def transform(self, *trans):
"""Return a new Event with transformed Arguments."""
@@ -280,7 +282,17 @@ class Event(object):
self)
-def _read_events(fobj):
+def read_events(fobj):
+ """Generate the output for the given (format, backends) pair.
+
+ Parameters
+ ----------
+ fobj : file
+ Event description file.
+
+ Returns a list of Event objects
+ """
+
events = []
for line in fobj:
if not line.strip():
@@ -352,14 +364,16 @@ def try_import(mod_name, attr_name=None, attr_default=None):
return False, None
-def generate(fevents, format, backends,
+def generate(events, group, format, backends,
binary=None, probe_prefix=None):
"""Generate the output for the given (format, backends) pair.
Parameters
----------
- fevents : file
- Event description file.
+ events : list
+ list of Event objects to generate for
+ group: str
+ Name of the tracing group
format : str
Output format name.
backends : list
@@ -389,6 +403,4 @@ def generate(fevents, format, backends,
tracetool.backend.dtrace.BINARY = binary
tracetool.backend.dtrace.PROBEPREFIX = probe_prefix
- events = _read_events(fevents)
-
- tracetool.format.generate(events, format, backend)
+ tracetool.format.generate(events, format, backend, group)
diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py
index d4b6dab9ca..f735a259c0 100644
--- a/scripts/tracetool/backend/__init__.py
+++ b/scripts/tracetool/backend/__init__.py
@@ -113,11 +113,11 @@ class Wrapper:
if func is not None:
func(*args, **kwargs)
- def generate_begin(self, events):
- self._run_function("generate_%s_begin", events)
+ def generate_begin(self, events, group):
+ self._run_function("generate_%s_begin", events, group)
- def generate(self, event):
- self._run_function("generate_%s", event)
+ def generate(self, event, group):
+ self._run_function("generate_%s", event, group)
- def generate_end(self, events):
- self._run_function("generate_%s_end", events)
+ def generate_end(self, events, group):
+ self._run_function("generate_%s_end", events, group)
diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py
index ab9ecfab30..79505c6b1a 100644
--- a/scripts/tracetool/backend/dtrace.py
+++ b/scripts/tracetool/backend/dtrace.py
@@ -35,12 +35,12 @@ def binary():
return BINARY
-def generate_h_begin(events):
+def generate_h_begin(events, group):
out('#include "trace/generated-tracers-dtrace.h"',
'')
-def generate_h(event):
+def generate_h(event, group):
out(' QEMU_%(uppername)s(%(argnames)s);',
uppername=event.name.upper(),
argnames=", ".join(event.args.names()))
diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py
index 80dcf30478..db9fe7ad57 100644
--- a/scripts/tracetool/backend/ftrace.py
+++ b/scripts/tracetool/backend/ftrace.py
@@ -19,13 +19,12 @@ from tracetool import out
PUBLIC = True
-def generate_h_begin(events):
+def generate_h_begin(events, group):
out('#include "trace/ftrace.h"',
- '#include "trace/control.h"',
'')
-def generate_h(event):
+def generate_h(event, group):
argnames = ", ".join(event.args.names())
if len(event.args) > 0:
argnames = ", " + argnames
diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py
index b3ff064011..4f4a4d38b1 100644
--- a/scripts/tracetool/backend/log.py
+++ b/scripts/tracetool/backend/log.py
@@ -19,13 +19,12 @@ from tracetool import out
PUBLIC = True
-def generate_h_begin(events):
- out('#include "trace/control.h"',
- '#include "qemu/log.h"',
+def generate_h_begin(events, group):
+ out('#include "qemu/log.h"',
'')
-def generate_h(event):
+def generate_h(event, group):
argnames = ", ".join(event.args.names())
if len(event.args) > 0:
argnames = ", " + argnames
diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py
index 1bccada63d..9885e83cd4 100644
--- a/scripts/tracetool/backend/simple.py
+++ b/scripts/tracetool/backend/simple.py
@@ -27,7 +27,7 @@ def is_string(arg):
return False
-def generate_h_begin(events):
+def generate_h_begin(events, group):
for event in events:
out('void _simple_%(api)s(%(args)s);',
api=event.api(),
@@ -35,13 +35,13 @@ def generate_h_begin(events):
out('')
-def generate_h(event):
+def generate_h(event, group):
out(' _simple_%(api)s(%(args)s);',
api=event.api(),
args=", ".join(event.args.names()))
-def generate_c_begin(events):
+def generate_c_begin(events, group):
out('#include "qemu/osdep.h"',
'#include "trace.h"',
'#include "trace/control.h"',
@@ -49,7 +49,7 @@ def generate_c_begin(events):
'')
-def generate_c(event):
+def generate_c(event, group):
out('void _simple_%(api)s(%(args)s)',
'{',
' TraceBufferRecord rec;',
@@ -80,11 +80,11 @@ def generate_c(event):
' return;',
' }',
'',
- ' if (trace_record_start(&rec, %(event_id)s, %(size_str)s)) {',
+ ' if (trace_record_start(&rec, %(event_obj)s.id, %(size_str)s)) {',
' return; /* Trace Buffer Full, Event Dropped ! */',
' }',
cond=cond,
- event_id=event_id,
+ event_obj=event.api(event.QEMU_EVENT),
size_str=sizestr)
if len(event.args) > 0:
diff --git a/scripts/tracetool/backend/syslog.py b/scripts/tracetool/backend/syslog.py
index 89019bc759..b8ff2790c4 100644
--- a/scripts/tracetool/backend/syslog.py
+++ b/scripts/tracetool/backend/syslog.py
@@ -19,13 +19,12 @@ from tracetool import out
PUBLIC = True
-def generate_h_begin(events):
+def generate_h_begin(events, group):
out('#include <syslog.h>',
- '#include "trace/control.h"',
'')
-def generate_h(event):
+def generate_h(event, group):
argnames = ", ".join(event.args.names())
if len(event.args) > 0:
argnames = ", " + argnames
diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/ust.py
index ed4c227f69..4594db6128 100644
--- a/scripts/tracetool/backend/ust.py
+++ b/scripts/tracetool/backend/ust.py
@@ -19,13 +19,13 @@ from tracetool import out
PUBLIC = True
-def generate_h_begin(events):
+def generate_h_begin(events, group):
out('#include <lttng/tracepoint.h>',
'#include "trace/generated-ust-provider.h"',
'')
-def generate_h(event):
+def generate_h(event, group):
argnames = ", ".join(event.args.names())
if len(event.args) > 0:
argnames = ", " + argnames
diff --git a/scripts/tracetool/format/__init__.py b/scripts/tracetool/format/__init__.py
index 812570ff6f..cf6e0e2da5 100644
--- a/scripts/tracetool/format/__init__.py
+++ b/scripts/tracetool/format/__init__.py
@@ -74,7 +74,7 @@ def exists(name):
return tracetool.try_import("tracetool.format." + name)[1]
-def generate(events, format, backend):
+def generate(events, format, backend, group):
if not exists(format):
raise ValueError("unknown format: %s" % format)
format = format.replace("-", "_")
@@ -82,4 +82,4 @@ def generate(events, format, backend):
"generate")[1]
if func is None:
raise AttributeError("format has no 'generate': %s" % format)
- func(events, backend)
+ func(events, backend, group)
diff --git a/scripts/tracetool/format/c.py b/scripts/tracetool/format/c.py
index 699598fb02..47115ed8af 100644
--- a/scripts/tracetool/format/c.py
+++ b/scripts/tracetool/format/c.py
@@ -16,13 +16,55 @@ __email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
-def generate(events, backend):
- events = [e for e in events
- if "disable" not in e.properties]
+def generate(events, backend, group):
+ active_events = [e for e in events
+ if "disable" not in e.properties]
out('/* This file is autogenerated by tracetool, do not edit. */',
+ '',
+ '#include "qemu/osdep.h"',
+ '#include "trace.h"',
'')
- backend.generate_begin(events)
- for event in events:
- backend.generate(event)
- backend.generate_end(events)
+
+ for e in events:
+ out('uint16_t %s;' % e.api(e.QEMU_DSTATE))
+
+ for e in events:
+ if "vcpu" in e.properties:
+ vcpu_id = 0
+ else:
+ vcpu_id = "TRACE_VCPU_EVENT_NONE"
+ out('TraceEvent %(event)s = {',
+ ' .id = 0,',
+ ' .vcpu_id = %(vcpu_id)s,',
+ ' .name = \"%(name)s\",',
+ ' .sstate = %(sstate)s,',
+ ' .dstate = &%(dstate)s ',
+ '};',
+ event = e.api(e.QEMU_EVENT),
+ vcpu_id = vcpu_id,
+ name = e.name,
+ sstate = "TRACE_%s_ENABLED" % e.name.upper(),
+ dstate = e.api(e.QEMU_DSTATE))
+
+ out('TraceEvent *%(group)s_trace_events[] = {',
+ group = group.lower())
+
+ for e in events:
+ out(' &%(event)s,', event = e.api(e.QEMU_EVENT))
+
+ out(' NULL,',
+ '};',
+ '')
+
+ out('static void trace_%(group)s_register_events(void)',
+ '{',
+ ' trace_event_register_group(%(group)s_trace_events);',
+ '}',
+ 'trace_init(trace_%(group)s_register_events)',
+ group = group.lower())
+
+ backend.generate_begin(active_events, group)
+ for event in active_events:
+ backend.generate(event, group)
+ backend.generate_end(active_events, group)
diff --git a/scripts/tracetool/format/d.py b/scripts/tracetool/format/d.py
index c77d5b7ab0..78397c24d2 100644
--- a/scripts/tracetool/format/d.py
+++ b/scripts/tracetool/format/d.py
@@ -29,7 +29,7 @@ RESERVED_WORDS = (
)
-def generate(events, backend):
+def generate(events, backend, group):
events = [e for e in events
if "disable" not in e.properties]
diff --git a/scripts/tracetool/format/events_c.py b/scripts/tracetool/format/events_c.py
deleted file mode 100644
index 4012063283..0000000000
--- a/scripts/tracetool/format/events_c.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
-trace/generated-events.c
-"""
-
-__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
-__license__ = "GPL version 2 or (at your option) any later version"
-
-__maintainer__ = "Stefan Hajnoczi"
-__email__ = "stefanha@linux.vnet.ibm.com"
-
-
-from tracetool import out
-
-
-def generate(events, backend):
- out('/* This file is autogenerated by tracetool, do not edit. */',
- '',
- '#include "qemu/osdep.h"',
- '#include "trace.h"',
- '#include "trace/generated-events.h"',
- '#include "trace/control.h"',
- '')
-
- out('TraceEvent trace_events[TRACE_EVENT_COUNT] = {')
-
- for e in events:
- if "vcpu" in e.properties:
- vcpu_id = "TRACE_VCPU_" + e.name.upper()
- else:
- vcpu_id = "TRACE_VCPU_EVENT_COUNT"
- out(' { .id = %(id)s, .vcpu_id = %(vcpu_id)s,'
- ' .name = \"%(name)s\",'
- ' .sstate = %(sstate)s },',
- id = "TRACE_" + e.name.upper(),
- vcpu_id = vcpu_id,
- name = e.name,
- sstate = "TRACE_%s_ENABLED" % e.name.upper())
-
- out('};',
- '')
diff --git a/scripts/tracetool/format/events_h.py b/scripts/tracetool/format/events_h.py
deleted file mode 100644
index a9da60b7fa..0000000000
--- a/scripts/tracetool/format/events_h.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
-trace/generated-events.h
-"""
-
-__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
-__license__ = "GPL version 2 or (at your option) any later version"
-
-__maintainer__ = "Stefan Hajnoczi"
-__email__ = "stefanha@linux.vnet.ibm.com"
-
-
-from tracetool import out
-
-
-def generate(events, backend):
- out('/* This file is autogenerated by tracetool, do not edit. */',
- '',
- '#ifndef TRACE__GENERATED_EVENTS_H',
- '#define TRACE__GENERATED_EVENTS_H',
- '')
-
- # event identifiers
- out('typedef enum {')
-
- for e in events:
- out(' TRACE_%s,' % e.name.upper())
-
- out(' TRACE_EVENT_COUNT',
- '} TraceEventID;')
-
- # per-vCPU event identifiers
- out('typedef enum {')
-
- for e in events:
- if "vcpu" in e.properties:
- out(' TRACE_VCPU_%s,' % e.name.upper())
-
- out(' TRACE_VCPU_EVENT_COUNT',
- '} TraceEventVCPUID;')
-
- # static state
- for e in events:
- if 'disable' in e.properties:
- enabled = 0
- else:
- enabled = 1
- if "tcg-exec" in e.properties:
- # a single define for the two "sub-events"
- out('#define TRACE_%(name)s_ENABLED %(enabled)d',
- name=e.original.name.upper(),
- enabled=enabled)
- out('#define TRACE_%s_ENABLED %d' % (e.name.upper(), enabled))
-
- out('#include "trace/event-internal.h"',
- '',
- '#endif /* TRACE__GENERATED_EVENTS_H */')
diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py
index 3763e9aecb..3682f4e6a8 100644
--- a/scripts/tracetool/format/h.py
+++ b/scripts/tracetool/format/h.py
@@ -16,24 +16,43 @@ __email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
-def generate(events, backend):
+def generate(events, backend, group):
out('/* This file is autogenerated by tracetool, do not edit. */',
'',
- '#ifndef TRACE__GENERATED_TRACERS_H',
- '#define TRACE__GENERATED_TRACERS_H',
+ '#ifndef TRACE_%s_GENERATED_TRACERS_H' % group.upper(),
+ '#define TRACE_%s_GENERATED_TRACERS_H' % group.upper(),
'',
'#include "qemu-common.h"',
'#include "trace/control.h"',
'')
- backend.generate_begin(events)
+ for e in events:
+ out('extern TraceEvent %(event)s;',
+ event = e.api(e.QEMU_EVENT))
+
+ for e in events:
+ out('extern uint16_t %s;' % e.api(e.QEMU_DSTATE))
+
+ # static state
+ for e in events:
+ if 'disable' in e.properties:
+ enabled = 0
+ else:
+ enabled = 1
+ if "tcg-exec" in e.properties:
+ # a single define for the two "sub-events"
+ out('#define TRACE_%(name)s_ENABLED %(enabled)d',
+ name=e.original.name.upper(),
+ enabled=enabled)
+ out('#define TRACE_%s_ENABLED %d' % (e.name.upper(), enabled))
+
+ backend.generate_begin(events, group)
for e in events:
if "vcpu" in e.properties:
trace_cpu = next(iter(e.args))[1]
cond = "trace_event_get_vcpu_state(%(cpu)s,"\
- " TRACE_%(id)s,"\
- " TRACE_VCPU_%(id)s)"\
+ " TRACE_%(id)s)"\
% dict(
cpu=trace_cpu,
id=e.name.upper())
@@ -49,11 +68,11 @@ def generate(events, backend):
cond=cond)
if "disable" not in e.properties:
- backend.generate(e)
+ backend.generate(e, group)
out(' }',
'}')
- backend.generate_end(events)
+ backend.generate_end(events, group)
- out('#endif /* TRACE__GENERATED_TRACERS_H */')
+ out('#endif /* TRACE_%s_GENERATED_TRACERS_H */' % group.upper())
diff --git a/scripts/tracetool/format/simpletrace_stap.py b/scripts/tracetool/format/simpletrace_stap.py
index 7e44bc1811..c35e662e00 100644
--- a/scripts/tracetool/format/simpletrace_stap.py
+++ b/scripts/tracetool/format/simpletrace_stap.py
@@ -19,8 +19,27 @@ from tracetool.backend.simple import is_string
from tracetool.format.stap import stap_escape
-def generate(events, backend):
+def generate(events, backend, group):
out('/* This file is autogenerated by tracetool, do not edit. */',
+ '',
+ 'global event_name_to_id_map',
+ 'global event_next_id',
+ 'function simple_trace_map_event(name)',
+ '',
+ '{',
+ ' if (!([name] in event_name_to_id_map)) {',
+ ' event_name_to_id_map[name] = event_next_id',
+ ' name_len = strlen(name)',
+ ' printf("%%8b%%8b%%4b%%.*s", 0, ',
+ ' event_next_id, name_len, name_len, name)',
+ ' event_next_id = event_next_id + 1',
+ ' }',
+ ' return event_name_to_id_map[name]',
+ '}',
+ 'probe begin',
+ '{',
+ ' printf("%%8b%%8b%%8b", 0xffffffffffffffff, 0xf2b177cb0aa429b4, 4)',
+ '}',
'')
for event_id, e in enumerate(events):
@@ -29,6 +48,7 @@ def generate(events, backend):
out('probe %(probeprefix)s.simpletrace.%(name)s = %(probeprefix)s.%(name)s ?',
'{',
+ ' id = simple_trace_map_event("%(name)s")',
probeprefix=probeprefix(),
name=e.name)
@@ -48,7 +68,7 @@ def generate(events, backend):
sizestr = ' + '.join(sizes)
# Generate format string and value pairs for record header and arguments
- fields = [('8b', str(event_id)),
+ fields = [('8b', 'id'),
('8b', 'gettimeofday_ns()'),
('4b', sizestr),
('4b', 'pid()')]
@@ -63,7 +83,7 @@ def generate(events, backend):
# Emit the entire record in a single SystemTap printf()
fmt_str = '%'.join(fmt for fmt, _ in fields)
arg_str = ', '.join(arg for _, arg in fields)
- out(' printf("%%%(fmt_str)s", %(arg_str)s)',
+ out(' printf("%%8b%%%(fmt_str)s", 1, %(arg_str)s)',
fmt_str=fmt_str, arg_str=arg_str)
out('}')
diff --git a/scripts/tracetool/format/stap.py b/scripts/tracetool/format/stap.py
index 9e780f1b06..e8ef3e762d 100644
--- a/scripts/tracetool/format/stap.py
+++ b/scripts/tracetool/format/stap.py
@@ -34,7 +34,7 @@ def stap_escape(identifier):
return identifier
-def generate(events, backend):
+def generate(events, backend, group):
events = [e for e in events
if "disable" not in e.properties]
diff --git a/scripts/tracetool/format/tcg_h.py b/scripts/tracetool/format/tcg_h.py
index e2331f251d..5f213f6cba 100644
--- a/scripts/tracetool/format/tcg_h.py
+++ b/scripts/tracetool/format/tcg_h.py
@@ -27,12 +27,12 @@ def vcpu_transform_args(args):
])
-def generate(events, backend):
+def generate(events, backend, group):
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* You must include this file after the inclusion of helper.h */',
'',
- '#ifndef TRACE__GENERATED_TCG_TRACERS_H',
- '#define TRACE__GENERATED_TCG_TRACERS_H',
+ '#ifndef TRACE_%s_GENERATED_TCG_TRACERS_H' % group.upper(),
+ '#define TRACE_%s_GENERATED_TCG_TRACERS_H' % group.upper(),
'',
'#include "trace.h"',
'#include "exec/helper-proto.h"',
@@ -63,4 +63,4 @@ def generate(events, backend):
out('}')
out('',
- '#endif /* TRACE__GENERATED_TCG_TRACERS_H */')
+ '#endif /* TRACE_%s_GENERATED_TCG_TRACERS_H */' % group.upper())
diff --git a/scripts/tracetool/format/tcg_helper_c.py b/scripts/tracetool/format/tcg_helper_c.py
index e3485b7f92..cc26e03008 100644
--- a/scripts/tracetool/format/tcg_helper_c.py
+++ b/scripts/tracetool/format/tcg_helper_c.py
@@ -40,7 +40,7 @@ def vcpu_transform_args(args, mode):
assert False
-def generate(events, backend):
+def generate(events, backend, group):
events = [e for e in events
if "disable" not in e.properties]
diff --git a/scripts/tracetool/format/tcg_helper_h.py b/scripts/tracetool/format/tcg_helper_h.py
index dc76c15ebc..6b184b641b 100644
--- a/scripts/tracetool/format/tcg_helper_h.py
+++ b/scripts/tracetool/format/tcg_helper_h.py
@@ -18,7 +18,7 @@ from tracetool.transform import *
import tracetool.vcpu
-def generate(events, backend):
+def generate(events, backend, group):
events = [e for e in events
if "disable" not in e.properties]
diff --git a/scripts/tracetool/format/tcg_helper_wrapper_h.py b/scripts/tracetool/format/tcg_helper_wrapper_h.py
index 020f4422a9..ff53447512 100644
--- a/scripts/tracetool/format/tcg_helper_wrapper_h.py
+++ b/scripts/tracetool/format/tcg_helper_wrapper_h.py
@@ -18,7 +18,7 @@ from tracetool.transform import *
import tracetool.vcpu
-def generate(events, backend):
+def generate(events, backend, group):
events = [e for e in events
if "disable" not in e.properties]
diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/format/ust_events_c.py
index 9967c7a82e..cd87d8ab8f 100644
--- a/scripts/tracetool/format/ust_events_c.py
+++ b/scripts/tracetool/format/ust_events_c.py
@@ -16,7 +16,7 @@ __email__ = "stefanha@redhat.com"
from tracetool import out
-def generate(events, backend):
+def generate(events, backend, group):
events = [e for e in events
if "disabled" not in e.properties]
diff --git a/scripts/tracetool/format/ust_events_h.py b/scripts/tracetool/format/ust_events_h.py
index 3e8a7cdf19..d853155d21 100644
--- a/scripts/tracetool/format/ust_events_h.py
+++ b/scripts/tracetool/format/ust_events_h.py
@@ -16,7 +16,7 @@ __email__ = "stefanha@redhat.com"
from tracetool import out
-def generate(events, backend):
+def generate(events, backend, group):
events = [e for e in events
if "disabled" not in e.properties]
@@ -28,8 +28,9 @@ def generate(events, backend):
'#undef TRACEPOINT_INCLUDE_FILE',
'#define TRACEPOINT_INCLUDE_FILE ./generated-ust-provider.h',
'',
- '#if !defined (TRACE__GENERATED_UST_H) || defined(TRACEPOINT_HEADER_MULTI_READ)',
- '#define TRACE__GENERATED_UST_H',
+ '#if !defined (TRACE_%s_GENERATED_UST_H) || \\' % group.upper(),
+ ' defined(TRACEPOINT_HEADER_MULTI_READ)',
+ '#define TRACE_%s_GENERATED_UST_H' % group.upper(),
'',
'#include "qemu-common.h"',
'#include <lttng/tracepoint.h>',
@@ -94,7 +95,7 @@ def generate(events, backend):
'',
name=e.name)
- out('#endif /* TRACE__GENERATED_UST_H */',
+ out('#endif /* TRACE_%s_GENERATED_UST_H */' % group.upper(),
'',
'/* This part must be outside ifdef protection */',
'#include <lttng/tracepoint-event.h>')
diff --git a/stubs/trace-control.c b/stubs/trace-control.c
index f765a02018..7f856e5c24 100644
--- a/stubs/trace-control.c
+++ b/stubs/trace-control.c
@@ -18,22 +18,21 @@ void trace_event_set_state_dynamic_init(TraceEvent *ev, bool state)
void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
{
- TraceEventID id;
bool state_pre;
assert(trace_event_get_state_static(ev));
- id = trace_event_get_id(ev);
+
/*
* We ignore the "vcpu" property here, since there's no target code. Then
* dstate can only be 1 or 0.
*/
- state_pre = trace_events_dstate[id];
+ state_pre = *(ev->dstate);
if (state_pre != state) {
if (state) {
trace_events_enabled_count++;
- trace_events_dstate[id] = 1;
+ *(ev->dstate) = 1;
} else {
trace_events_enabled_count--;
- trace_events_dstate[id] = 0;
+ *(ev->dstate) = 0;
}
}
}
diff --git a/trace-events b/trace-events
index 1a4e092418..8ecded5150 100644
--- a/trace-events
+++ b/trace-events
@@ -122,22 +122,6 @@ memory_region_subpage_write(int cpu_index, void *mr, uint64_t offset, uint64_t v
memory_region_tb_read(int cpu_index, uint64_t addr, uint64_t value, unsigned size) "cpu %d addr %#"PRIx64" value %#"PRIx64" size %u"
memory_region_tb_write(int cpu_index, uint64_t addr, uint64_t value, unsigned size) "cpu %d addr %#"PRIx64" value %#"PRIx64" size %u"
-# net/colo.c
-colo_proxy_main(const char *chr) ": %s"
-
-# net/colo-compare.c
-colo_compare_main(const char *chr) ": %s"
-colo_compare_udp_miscompare(const char *sta, int size) ": %s = %d"
-colo_compare_icmp_miscompare(const char *sta, int size) ": %s = %d"
-colo_compare_ip_info(int psize, const char *sta, const char *stb, int ssize, const char *stc, const char *std) "ppkt size = %d, ip_src = %s, ip_dst = %s, spkt size = %d, ip_src = %s, ip_dst = %s"
-colo_old_packet_check_found(int64_t old_time) "%" PRId64
-colo_compare_miscompare(void) ""
-
-# net/filter-rewriter.c
-colo_filter_rewriter_debug(void) ""
-colo_filter_rewriter_pkt_info(const char *func, const char *src, const char *dst, uint32_t seq, uint32_t ack, uint32_t flag) "%s: src/dst: %s/%s p: seq/ack=%u/%u flags=%x\n"
-colo_filter_rewriter_conn_offset(uint32_t offset) ": offset=%u\n"
-
### Guest events, keep at bottom
@@ -145,11 +129,13 @@ colo_filter_rewriter_conn_offset(uint32_t offset) ": offset=%u\n"
# Hot-plug a new virtual (guest) CPU
#
+# Mode: user, softmmu
# Targets: all
vcpu guest_cpu_enter(void)
# Reset the state of a virtual (guest) CPU
#
+# Mode: user, softmmu
# Targets: all
vcpu guest_cpu_reset(void)
diff --git a/trace/Makefile.objs b/trace/Makefile.objs
index 24d3b3758c..1e1ce7479d 100644
--- a/trace/Makefile.objs
+++ b/trace/Makefile.objs
@@ -22,7 +22,7 @@ $(obj)/generated-ust-provider.h-timestamp: $(BUILD_DIR)/trace-events-all $(trace
$(call quiet-command,$(TRACETOOL) \
--format=ust-events-h \
--backends=$(TRACE_BACKENDS) \
- < $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
+ $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
$(obj)/generated-ust.c: $(obj)/generated-ust.c-timestamp $(BUILD_DIR)/config-host.mak
@cmp $< $@ >/dev/null 2>&1 || cp $< $@
@@ -30,34 +30,13 @@ $(obj)/generated-ust.c-timestamp: $(BUILD_DIR)/trace-events-all $(tracetool-y)
$(call quiet-command,$(TRACETOOL) \
--format=ust-events-c \
--backends=$(TRACE_BACKENDS) \
- < $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
+ $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
-$(obj)/generated-events.h: $(obj)/generated-ust-provider.h
-$(obj)/generated-events.c: $(obj)/generated-ust.c
+$(obj)/generated-tracers.h: $(obj)/generated-ust-provider.h
+$(obj)/generated-tracers.c: $(obj)/generated-ust.c
endif
-######################################################################
-# Auto-generated event descriptions
-
-$(obj)/generated-events.h: $(obj)/generated-events.h-timestamp
- @cmp $< $@ >/dev/null 2>&1 || cp $< $@
-$(obj)/generated-events.h-timestamp: $(BUILD_DIR)/trace-events-all $(tracetool-y)
- $(call quiet-command,$(TRACETOOL) \
- --format=events-h \
- --backends=$(TRACE_BACKENDS) \
- < $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
-
-$(obj)/generated-events.c: $(obj)/generated-events.c-timestamp $(BUILD_DIR)/config-host.mak
- @cmp $< $@ >/dev/null 2>&1 || cp $< $@
-$(obj)/generated-events.c-timestamp: $(BUILD_DIR)/trace-events-all $(tracetool-y)
- $(call quiet-command,$(TRACETOOL) \
- --format=events-c \
- --backends=$(TRACE_BACKENDS) \
- < $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
-
-util-obj-y += generated-events.o
-
######################################################################
# Auto-generated tracing routines
@@ -71,7 +50,7 @@ $(obj)/generated-tracers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)
$(call quiet-command,$(TRACETOOL) \
--format=h \
--backends=$(TRACE_BACKENDS) \
- < $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
+ $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
##############################
# non-DTrace
@@ -82,7 +61,7 @@ $(obj)/generated-tracers.c-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)
$(call quiet-command,$(TRACETOOL) \
--format=c \
--backends=$(TRACE_BACKENDS) \
- < $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
+ $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
$(obj)/generated-tracers.o: $(obj)/generated-tracers.c $(obj)/generated-tracers.h
@@ -100,7 +79,7 @@ $(obj)/generated-tracers-dtrace.dtrace-timestamp: $(BUILD_DIR)/trace-events-all
$(call quiet-command,$(TRACETOOL) \
--format=d \
--backends=$(TRACE_BACKENDS) \
- < $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
+ $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
$(obj)/generated-tracers-dtrace.h: $(obj)/generated-tracers-dtrace.dtrace
$(call quiet-command,dtrace -o $@ -h -s $<,"GEN","$@")
@@ -119,7 +98,7 @@ $(obj)/generated-helpers-wrappers.h-timestamp: $(BUILD_DIR)/trace-events-all $(B
$(call quiet-command,$(TRACETOOL) \
--format=tcg-helper-wrapper-h \
--backend=$(TRACE_BACKENDS) \
- < $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
+ $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
$(obj)/generated-helpers.h: $(obj)/generated-helpers.h-timestamp
@cmp $< $@ >/dev/null 2>&1 || cp $< $@
@@ -127,7 +106,7 @@ $(obj)/generated-helpers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)
$(call quiet-command,$(TRACETOOL) \
--format=tcg-helper-h \
--backend=$(TRACE_BACKENDS) \
- < $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
+ $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
$(obj)/generated-helpers.c: $(obj)/generated-helpers.c-timestamp
@cmp $< $@ >/dev/null 2>&1 || cp $< $@
@@ -135,7 +114,7 @@ $(obj)/generated-helpers.c-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)
$(call quiet-command,$(TRACETOOL) \
--format=tcg-helper-c \
--backend=$(TRACE_BACKENDS) \
- < $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
+ $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
$(obj)/generated-helpers.o: $(obj)/generated-helpers.c
@@ -148,13 +127,14 @@ $(obj)/generated-tcg-tracers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_
$(call quiet-command,$(TRACETOOL) \
--format=tcg-h \
--backend=$(TRACE_BACKENDS) \
- < $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
+ $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
######################################################################
# Backend code
-util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o generated-tracers.o
+util-obj-y += generated-tracers.o
+util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o
util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o
util-obj-$(CONFIG_TRACE_UST) += generated-ust.o
util-obj-y += control.o
diff --git a/trace/control-internal.h b/trace/control-internal.h
index a4e5f4aa06..a9d395a587 100644
--- a/trace/control-internal.h
+++ b/trace/control-internal.h
@@ -15,42 +15,29 @@
#include "qom/cpu.h"
-extern TraceEvent trace_events[];
-extern uint16_t trace_events_dstate[];
extern int trace_events_enabled_count;
-static inline TraceEventID trace_event_count(void)
-{
- return TRACE_EVENT_COUNT;
-}
-
-static inline TraceEvent *trace_event_id(TraceEventID id)
-{
- assert(id < trace_event_count());
- return &trace_events[id];
-}
-
static inline bool trace_event_is_pattern(const char *str)
{
assert(str != NULL);
return strchr(str, '*') != NULL;
}
-static inline TraceEventID trace_event_get_id(TraceEvent *ev)
+static inline uint32_t trace_event_get_id(TraceEvent *ev)
{
assert(ev != NULL);
return ev->id;
}
-static inline TraceEventVCPUID trace_event_get_vcpu_id(TraceEvent *ev)
+static inline uint32_t trace_event_get_vcpu_id(TraceEvent *ev)
{
return ev->vcpu_id;
}
static inline bool trace_event_is_vcpu(TraceEvent *ev)
{
- return ev->vcpu_id != TRACE_VCPU_EVENT_COUNT;
+ return ev->vcpu_id != TRACE_VCPU_EVENT_NONE;
}
static inline const char * trace_event_get_name(TraceEvent *ev)
@@ -65,26 +52,22 @@ static inline bool trace_event_get_state_static(TraceEvent *ev)
return ev->sstate;
}
-static inline bool trace_event_get_state_dynamic_by_id(TraceEventID id)
-{
- /* it's on fast path, avoid consistency checks (asserts) */
- return unlikely(trace_events_enabled_count) && trace_events_dstate[id];
-}
+/* it's on fast path, avoid consistency checks (asserts) */
+#define trace_event_get_state_dynamic_by_id(id) \
+ (unlikely(trace_events_enabled_count) && _ ## id ## _DSTATE)
static inline bool trace_event_get_state_dynamic(TraceEvent *ev)
{
- TraceEventID id;
- assert(trace_event_get_state_static(ev));
- id = trace_event_get_id(ev);
- return trace_event_get_state_dynamic_by_id(id);
+ return unlikely(trace_events_enabled_count) && *ev->dstate;
}
-static inline bool trace_event_get_vcpu_state_dynamic_by_vcpu_id(CPUState *vcpu,
- TraceEventVCPUID id)
+static inline bool
+trace_event_get_vcpu_state_dynamic_by_vcpu_id(CPUState *vcpu,
+ uint32_t vcpu_id)
{
/* it's on fast path, avoid consistency checks (asserts) */
if (unlikely(trace_events_enabled_count)) {
- return test_bit(id, vcpu->trace_dstate);
+ return test_bit(vcpu_id, vcpu->trace_dstate);
} else {
return false;
}
@@ -93,10 +76,13 @@ static inline bool trace_event_get_vcpu_state_dynamic_by_vcpu_id(CPUState *vcpu,
static inline bool trace_event_get_vcpu_state_dynamic(CPUState *vcpu,
TraceEvent *ev)
{
- TraceEventVCPUID id;
+ uint32_t vcpu_id;
assert(trace_event_is_vcpu(ev));
- id = trace_event_get_vcpu_id(ev);
- return trace_event_get_vcpu_state_dynamic_by_vcpu_id(vcpu, id);
+ vcpu_id = trace_event_get_vcpu_id(ev);
+ 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-target.c b/trace/control-target.c
index 52fcce5a00..7ebf6e0bcb 100644
--- a/trace/control-target.c
+++ b/trace/control-target.c
@@ -16,21 +16,20 @@
void trace_event_set_state_dynamic_init(TraceEvent *ev, bool state)
{
- TraceEventID id = trace_event_get_id(ev);
bool state_pre;
assert(trace_event_get_state_static(ev));
/*
* We ignore the "vcpu" property here, since no vCPUs have been created
* yet. Then dstate can only be 1 or 0.
*/
- state_pre = trace_events_dstate[id];
+ state_pre = *ev->dstate;
if (state_pre != state) {
if (state) {
trace_events_enabled_count++;
- trace_events_dstate[id] = 1;
+ *ev->dstate = 1;
} else {
trace_events_enabled_count--;
- trace_events_dstate[id] = 0;
+ *ev->dstate = 0;
}
}
}
@@ -45,15 +44,14 @@ void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
}
} else {
/* Without the "vcpu" property, dstate can only be 1 or 0 */
- TraceEventID id = trace_event_get_id(ev);
- bool state_pre = trace_events_dstate[id];
+ bool state_pre = *ev->dstate;
if (state_pre != state) {
if (state) {
trace_events_enabled_count++;
- trace_events_dstate[id] = 1;
+ *ev->dstate = 1;
} else {
trace_events_enabled_count--;
- trace_events_dstate[id] = 0;
+ *ev->dstate = 0;
}
}
}
@@ -62,23 +60,21 @@ void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
TraceEvent *ev, bool state)
{
- TraceEventID id;
- TraceEventVCPUID vcpu_id;
+ uint32_t vcpu_id;
bool state_pre;
assert(trace_event_get_state_static(ev));
assert(trace_event_is_vcpu(ev));
- id = trace_event_get_id(ev);
vcpu_id = trace_event_get_vcpu_id(ev);
state_pre = test_bit(vcpu_id, vcpu->trace_dstate);
if (state_pre != state) {
if (state) {
trace_events_enabled_count++;
set_bit(vcpu_id, vcpu->trace_dstate);
- trace_events_dstate[id]++;
+ (*ev->dstate)++;
} else {
trace_events_enabled_count--;
clear_bit(vcpu_id, vcpu->trace_dstate);
- trace_events_dstate[id]--;
+ (*ev->dstate)--;
}
}
}
@@ -98,18 +94,18 @@ static bool adding_first_cpu(void)
void trace_init_vcpu(CPUState *vcpu)
{
- TraceEvent *ev = NULL;
-
- while ((ev = trace_event_pattern("*", ev)) != NULL) {
+ TraceEventIter iter;
+ TraceEvent *ev;
+ trace_event_iter_init(&iter, NULL);
+ while ((ev = trace_event_iter_next(&iter)) != NULL) {
if (trace_event_is_vcpu(ev) &&
trace_event_get_state_static(ev) &&
trace_event_get_state_dynamic(ev)) {
- TraceEventID id = trace_event_get_id(ev);
if (adding_first_cpu()) {
/* check preconditions */
- assert(trace_events_dstate[id] == 1);
+ assert(*ev->dstate == 1);
/* disable early-init state ... */
- trace_events_dstate[id] = 0;
+ *ev->dstate = 0;
trace_events_enabled_count--;
/* ... and properly re-enable */
trace_event_set_vcpu_state_dynamic(vcpu, ev, true);
@@ -118,6 +114,5 @@ void trace_init_vcpu(CPUState *vcpu)
}
}
}
-
trace_guest_cpu_enter(vcpu);
}
diff --git a/trace/control.c b/trace/control.c
index 10b3e9baba..1a7bee6ddc 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -28,12 +28,15 @@
#include "monitor/monitor.h"
int trace_events_enabled_count;
-/*
- * Interpretation depends on wether the event has the 'vcpu' property:
- * - false: Boolean value indicating whether the event is active.
- * - true : Integral counting the number of vCPUs that have this event enabled.
- */
-uint16_t trace_events_dstate[TRACE_EVENT_COUNT];
+
+typedef struct TraceEventGroup {
+ TraceEvent **events;
+} TraceEventGroup;
+
+static TraceEventGroup *event_groups;
+static size_t nevent_groups;
+static uint32_t next_id;
+static uint32_t next_vcpu_id;
QemuOptsList qemu_trace_opts = {
.name = "trace",
@@ -56,13 +59,29 @@ QemuOptsList qemu_trace_opts = {
};
+void trace_event_register_group(TraceEvent **events)
+{
+ size_t i;
+ for (i = 0; events[i] != NULL; i++) {
+ events[i]->id = next_id++;
+ if (events[i]->vcpu_id != TRACE_VCPU_EVENT_NONE) {
+ events[i]->vcpu_id = next_vcpu_id++;
+ }
+ }
+ 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);
- TraceEventID i;
- for (i = 0; i < trace_event_count(); i++) {
- TraceEvent *ev = trace_event_id(i);
+ TraceEventIter iter;
+ TraceEvent *ev;
+ trace_event_iter_init(&iter, NULL);
+ while ((ev = trace_event_iter_next(&iter)) != NULL) {
if (strcmp(trace_event_get_name(ev), name) == 0) {
return ev;
}
@@ -101,25 +120,29 @@ static bool pattern_glob(const char *pat, const char *ev)
}
}
-TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev)
-{
- assert(pat != NULL);
- TraceEventID i;
-
- if (ev == NULL) {
- i = -1;
- } else {
- i = trace_event_get_id(ev);
- }
- i++;
+void trace_event_iter_init(TraceEventIter *iter, const char *pattern)
+{
+ iter->event = 0;
+ iter->group = 0;
+ iter->pattern = pattern;
+}
- while (i < trace_event_count()) {
- TraceEvent *res = trace_event_id(i);
- if (pattern_glob(pat, trace_event_get_name(res))) {
- return res;
+TraceEvent *trace_event_iter_next(TraceEventIter *iter)
+{
+ 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))) {
+ return ev;
}
- i++;
}
return NULL;
@@ -127,10 +150,11 @@ TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev)
void trace_list_events(void)
{
- int i;
- for (i = 0; i < trace_event_count(); i++) {
- TraceEvent *res = trace_event_id(i);
- fprintf(stderr, "%s\n", trace_event_get_name(res));
+ TraceEventIter iter;
+ TraceEvent *ev;
+ trace_event_iter_init(&iter, NULL);
+ while ((ev = trace_event_iter_next(&iter)) != NULL) {
+ fprintf(stderr, "%s\n", trace_event_get_name(ev));
}
}
@@ -138,26 +162,32 @@ static void do_trace_enable_events(const char *line_buf)
{
const bool enable = ('-' != line_buf[0]);
const char *line_ptr = enable ? line_buf : line_buf + 1;
+ TraceEventIter iter;
+ TraceEvent *ev;
+ bool is_pattern = trace_event_is_pattern(line_ptr);
- if (trace_event_is_pattern(line_ptr)) {
- TraceEvent *ev = NULL;
- while ((ev = trace_event_pattern(line_ptr, ev)) != NULL) {
- if (trace_event_get_state_static(ev)) {
- trace_event_set_state_dynamic_init(ev, enable);
+ trace_event_iter_init(&iter, line_ptr);
+ while ((ev = trace_event_iter_next(&iter)) != NULL) {
+ if (!trace_event_get_state_static(ev)) {
+ if (!is_pattern) {
+ error_report("WARNING: trace event '%s' is not traceable",
+ line_ptr);
+ return;
}
+ continue;
}
- } else {
- TraceEvent *ev = trace_event_name(line_ptr);
- if (ev == NULL) {
- error_report("WARNING: trace event '%s' does not exist",
- line_ptr);
- } else if (!trace_event_get_state_static(ev)) {
- error_report("WARNING: trace event '%s' is not traceable",
- line_ptr);
- } else {
- trace_event_set_state_dynamic_init(ev, enable);
+
+ /* start tracing */
+ trace_event_set_state_dynamic(ev, enable);
+ if (!is_pattern) {
+ return;
}
}
+
+ if (!is_pattern) {
+ error_report("WARNING: trace event '%s' does not exist",
+ line_ptr);
+ }
}
void trace_enable_events(const char *line_buf)
@@ -269,3 +299,8 @@ char *trace_opt_parse(const char *optarg)
return trace_file;
}
+
+uint32_t trace_get_vcpu_event_count(void)
+{
+ return next_vcpu_id;
+}
diff --git a/trace/control.h b/trace/control.h
index a22d11242e..ccaeac8552 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -11,35 +11,37 @@
#define TRACE__CONTROL_H
#include "qemu-common.h"
-#include "trace/generated-events.h"
+#include "event-internal.h"
+
+typedef struct TraceEventIter {
+ size_t event;
+ size_t group;
+ const char *pattern;
+} TraceEventIter;
/**
- * TraceEventID:
- *
- * Unique tracing event identifier.
- *
- * These are named as 'TRACE_${EVENT_NAME}'.
+ * trace_event_iter_init:
+ * @iter: the event iterator struct
+ * @pattern: optional pattern to filter events on name
*
- * See also: "trace/generated-events.h"
+ * Initialize the event iterator struct @iter,
+ * optionally using @pattern to filter out events
+ * with non-matching names.
*/
-enum TraceEventID;
+void trace_event_iter_init(TraceEventIter *iter, const char *pattern);
/**
- * trace_event_id:
- * @id: Event identifier.
- *
- * Get an event by its identifier.
+ * trace_event_iter_next:
+ * @iter: the event iterator struct
*
- * This routine has a constant cost, as opposed to trace_event_name and
- * trace_event_pattern.
- *
- * Pre-conditions: The identifier is valid.
- *
- * Returns: pointer to #TraceEvent.
+ * Get the next event, if any. When this returns NULL,
+ * the iterator should no longer be used.
*
+ * Returns: the next event, or NULL if no more events exist
*/
-static TraceEvent *trace_event_id(TraceEventID id);
+TraceEvent *trace_event_iter_next(TraceEventIter *iter);
+
/**
* trace_event_name:
@@ -52,48 +54,29 @@ static TraceEvent *trace_event_id(TraceEventID id);
TraceEvent *trace_event_name(const char *name);
/**
- * trace_event_pattern:
- * @pat: Event name pattern.
- * @ev: Event to start searching from (not included).
- *
- * Get all events with a given name pattern.
- *
- * Returns: pointer to #TraceEvent or NULL if not found.
- */
-TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev);
-
-/**
* trace_event_is_pattern:
*
* Whether the given string is an event name pattern.
*/
static bool trace_event_is_pattern(const char *str);
-/**
- * trace_event_count:
- *
- * Return the number of events.
- */
-static TraceEventID trace_event_count(void);
-
-
/**
* trace_event_get_id:
*
* Get the identifier of an event.
*/
-static TraceEventID trace_event_get_id(TraceEvent *ev);
+static uint32_t trace_event_get_id(TraceEvent *ev);
/**
* trace_event_get_vcpu_id:
*
* Get the per-vCPU identifier of an event.
*
- * Special value #TRACE_VCPU_EVENT_COUNT means the event is not vCPU-specific
+ * Special value #TRACE_VCPU_EVENT_NONE means the event is not vCPU-specific
* (does not have the "vcpu" property).
*/
-static TraceEventVCPUID trace_event_get_vcpu_id(TraceEvent *ev);
+static uint32_t trace_event_get_vcpu_id(TraceEvent *ev);
/**
* trace_event_is_vcpu:
@@ -111,14 +94,12 @@ static const char * trace_event_get_name(TraceEvent *ev);
/**
* trace_event_get_state:
- * @id: Event identifier.
+ * @id: Event identifier name.
*
* Get the tracing state of an event (both static and dynamic).
*
* If the event has the disabled property, the check will have no performance
* impact.
- *
- * As a down side, you must always use an immediate #TraceEventID value.
*/
#define trace_event_get_state(id) \
((id ##_ENABLED) && trace_event_get_state_dynamic_by_id(id))
@@ -126,19 +107,18 @@ static const char * trace_event_get_name(TraceEvent *ev);
/**
* trace_event_get_vcpu_state:
* @vcpu: Target vCPU.
- * @id: Event identifier (TraceEventID).
- * @vcpu_id: Per-vCPU event identifier (TraceEventVCPUID).
+ * @id: Event identifier name.
*
* Get the tracing state of an event (both static and dynamic) for the given
* vCPU.
*
* If the event has the disabled property, the check will have no performance
* impact.
- *
- * As a down side, you must always use an immediate #TraceEventID value.
*/
-#define trace_event_get_vcpu_state(vcpu, id, vcpu_id) \
- ((id ##_ENABLED) && trace_event_get_vcpu_state_dynamic_by_vcpu_id(vcpu, vcpu_id))
+#define trace_event_get_vcpu_state(vcpu, id) \
+ ((id ##_ENABLED) && \
+ trace_event_get_vcpu_state_dynamic_by_vcpu_id( \
+ vcpu, _ ## id ## _EVENT.vcpu_id))
/**
* trace_event_get_state_static:
@@ -167,31 +147,6 @@ static bool trace_event_get_state_dynamic(TraceEvent *ev);
*/
static bool trace_event_get_vcpu_state_dynamic(CPUState *vcpu, TraceEvent *ev);
-/**
- * trace_event_set_state:
- *
- * Set the tracing state of an event (only if possible).
- */
-#define trace_event_set_state(id, state) \
- do { \
- if ((id ##_ENABLED)) { \
- TraceEvent *_e = trace_event_id(id); \
- trace_event_set_state_dynamic(_e, state); \
- } \
- } while (0)
-
-/**
- * trace_event_set_vcpu_state:
- *
- * Set the tracing state of an event for the given vCPU (only if not disabled).
- */
-#define trace_event_set_vcpu_state(vcpu, id, state) \
- do { \
- if ((id ##_ENABLED)) { \
- TraceEvent *_e = trace_event_id(id); \
- trace_event_set_vcpu_state_dynamic(vcpu, _e, state); \
- } \
- } while (0)
/**
* trace_event_set_state_dynamic:
@@ -277,6 +232,13 @@ extern QemuOptsList qemu_trace_opts;
*/
char *trace_opt_parse(const char *optarg);
+/**
+ * trace_get_vcpu_event_count:
+ *
+ * Return the number of known vcpu-specific events
+ */
+uint32_t trace_get_vcpu_event_count(void);
+
#include "trace/control-internal.h"
diff --git a/trace/event-internal.h b/trace/event-internal.h
index 074faf6862..f63500b37e 100644
--- a/trace/event-internal.h
+++ b/trace/event-internal.h
@@ -10,8 +10,11 @@
#ifndef TRACE__EVENT_INTERNAL_H
#define TRACE__EVENT_INTERNAL_H
-#include "trace/generated-events.h"
-
+/*
+ * Special value for TraceEvent.vcpu_id field to indicate
+ * that the event is not VCPU specific
+ */
+#define TRACE_VCPU_EVENT_NONE ((uint32_t)-1)
/**
* TraceEvent:
@@ -19,14 +22,21 @@
* @vcpu_id: Unique per-vCPU event identifier.
* @name: Event name.
* @sstate: Static tracing state.
+ * @dstate: Dynamic tracing state
+ *
+ * Interpretation of @dstate depends on whether the event has the 'vcpu'
+ * property:
+ * - false: Boolean value indicating whether the event is active.
+ * - true : Integral counting the number of vCPUs that have this event enabled.
*
* Opaque generic description of a tracing event.
*/
typedef struct TraceEvent {
- TraceEventID id;
- TraceEventVCPUID vcpu_id;
+ uint32_t id;
+ uint32_t vcpu_id;
const char * name;
const bool sstate;
+ uint16_t *dstate;
} TraceEvent;
void trace_event_set_state_dynamic_init(TraceEvent *ev, bool state);
diff --git a/trace/ftrace.c b/trace/ftrace.c
index e953922f5b..3588bb0eb4 100644
--- a/trace/ftrace.c
+++ b/trace/ftrace.c
@@ -51,6 +51,12 @@ bool ftrace_init(void)
snprintf(path, PATH_MAX, "%s/tracing/tracing_on", debugfs);
trace_fd = open(path, O_WRONLY);
if (trace_fd < 0) {
+ if (errno == EACCES) {
+ trace_marker_fd = open("/dev/null", O_WRONLY);
+ if (trace_marker_fd != -1) {
+ return true;
+ }
+ }
perror("Could not open ftrace 'tracing_on' file");
return false;
} else {
diff --git a/trace/qmp.c b/trace/qmp.c
index 11d2564e7b..ac777d154f 100644
--- a/trace/qmp.c
+++ b/trace/qmp.c
@@ -52,8 +52,10 @@ static bool check_events(bool has_vcpu, bool ignore_unavailable, bool is_pattern
return true;
} else {
/* error for unavailable events */
- TraceEvent *ev = NULL;
- while ((ev = trace_event_pattern(name, ev)) != NULL) {
+ TraceEventIter iter;
+ TraceEvent *ev;
+ trace_event_iter_init(&iter, name);
+ while ((ev = trace_event_iter_next(&iter)) != NULL) {
if (!ignore_unavailable && !trace_event_get_state_static(ev)) {
error_setg(errp, "event \"%s\" is disabled", trace_event_get_name(ev));
return false;
@@ -69,6 +71,7 @@ TraceEventInfoList *qmp_trace_event_get_state(const char *name,
{
Error *err = NULL;
TraceEventInfoList *events = NULL;
+ TraceEventIter iter;
TraceEvent *ev;
bool is_pattern = trace_event_is_pattern(name);
CPUState *cpu;
@@ -86,8 +89,8 @@ TraceEventInfoList *qmp_trace_event_get_state(const char *name,
}
/* Get states (all errors checked above) */
- ev = NULL;
- while ((ev = trace_event_pattern(name, ev)) != NULL) {
+ trace_event_iter_init(&iter, name);
+ while ((ev = trace_event_iter_next(&iter)) != NULL) {
TraceEventInfoList *elem;
bool is_vcpu = trace_event_is_vcpu(ev);
if (has_vcpu && !is_vcpu) {
@@ -132,6 +135,7 @@ void qmp_trace_event_set_state(const char *name, bool enable,
Error **errp)
{
Error *err = NULL;
+ TraceEventIter iter;
TraceEvent *ev;
bool is_pattern = trace_event_is_pattern(name);
CPUState *cpu;
@@ -150,8 +154,8 @@ void qmp_trace_event_set_state(const char *name, bool enable,
}
/* Apply changes (all errors checked above) */
- ev = NULL;
- while ((ev = trace_event_pattern(name, ev)) != NULL) {
+ trace_event_iter_init(&iter, name);
+ while ((ev = trace_event_iter_next(&iter)) != NULL) {
if (!trace_event_get_state_static(ev) ||
(has_vcpu && !trace_event_is_vcpu(ev))) {
continue;
diff --git a/trace/simple.c b/trace/simple.c
index 2f09dafcbc..b263622fa9 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -17,14 +17,14 @@
#include "trace/control.h"
#include "trace/simple.h"
-/** Trace file header event ID */
-#define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */
+/** Trace file header event ID, picked to avoid conflict with real event IDs */
+#define HEADER_EVENT_ID (~(uint64_t)0)
/** Trace file magic number */
#define HEADER_MAGIC 0xf2b177cb0aa429b4ULL
/** Trace file version number, bump if format changes */
-#define HEADER_VERSION 3
+#define HEADER_VERSION 4
/** Records were dropped event ID */
#define DROPPED_EVENT_ID (~(uint64_t)0 - 1)
@@ -56,9 +56,12 @@ static uint32_t trace_pid;
static FILE *trace_fp;
static char *trace_file_name;
+#define TRACE_RECORD_TYPE_MAPPING 0
+#define TRACE_RECORD_TYPE_EVENT 1
+
/* * Trace buffer entry */
typedef struct {
- uint64_t event; /* TraceEventID */
+ uint64_t event; /* event ID value */
uint64_t timestamp_ns;
uint32_t length; /* in bytes */
uint32_t pid;
@@ -160,6 +163,7 @@ static gpointer writeout_thread(gpointer opaque)
unsigned int idx = 0;
int dropped_count;
size_t unused __attribute__ ((unused));
+ uint64_t type = TRACE_RECORD_TYPE_EVENT;
for (;;) {
wait_for_trace_records_available();
@@ -174,10 +178,12 @@ static gpointer writeout_thread(gpointer opaque)
} while (!g_atomic_int_compare_and_exchange(&dropped_events,
dropped_count, 0));
dropped.rec.arguments[0] = dropped_count;
+ unused = fwrite(&type, sizeof(type), 1, trace_fp);
unused = fwrite(&dropped.rec, dropped.rec.length, 1, trace_fp);
}
while (get_trace_record(idx, &recordptr)) {
+ unused = fwrite(&type, sizeof(type), 1, trace_fp);
unused = fwrite(recordptr, recordptr->length, 1, trace_fp);
writeout_idx += recordptr->length;
free(recordptr); /* don't use g_free, can deadlock when traced */
@@ -202,7 +208,7 @@ void trace_record_write_str(TraceBufferRecord *rec, const char *s, uint32_t slen
rec->rec_off = write_to_buffer(rec->rec_off, (void*)s, slen);
}
-int trace_record_start(TraceBufferRecord *rec, TraceEventID event, size_t datasize)
+int trace_record_start(TraceBufferRecord *rec, uint32_t event, size_t datasize)
{
unsigned int idx, rec_off, old_idx, new_idx;
uint32_t rec_len = sizeof(TraceRecord) + datasize;
@@ -273,6 +279,28 @@ void trace_record_finish(TraceBufferRecord *rec)
}
}
+static int st_write_event_mapping(void)
+{
+ uint64_t type = TRACE_RECORD_TYPE_MAPPING;
+ TraceEventIter iter;
+ TraceEvent *ev;
+
+ trace_event_iter_init(&iter, NULL);
+ while ((ev = trace_event_iter_next(&iter)) != NULL) {
+ uint64_t id = trace_event_get_id(ev);
+ const char *name = trace_event_get_name(ev);
+ uint32_t len = strlen(name);
+ if (fwrite(&type, sizeof(type), 1, trace_fp) != 1 ||
+ fwrite(&id, sizeof(id), 1, trace_fp) != 1 ||
+ fwrite(&len, sizeof(len), 1, trace_fp) != 1 ||
+ fwrite(name, len, 1, trace_fp) != 1) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
void st_set_trace_file_enabled(bool enable)
{
if (enable == !!trace_fp) {
@@ -297,7 +325,8 @@ void st_set_trace_file_enabled(bool enable)
return;
}
- if (fwrite(&header, sizeof header, 1, trace_fp) != 1) {
+ if (fwrite(&header, sizeof header, 1, trace_fp) != 1 ||
+ st_write_event_mapping() < 0) {
fclose(trace_fp);
trace_fp = NULL;
return;
diff --git a/trace/simple.h b/trace/simple.h
index 1e7de45575..9931808c05 100644
--- a/trace/simple.h
+++ b/trace/simple.h
@@ -11,10 +11,6 @@
#ifndef TRACE_SIMPLE_H
#define TRACE_SIMPLE_H
-
-#include "trace/generated-events.h"
-
-
void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf);
void st_set_trace_file_enabled(bool enable);
void st_set_trace_file(const char *file);
@@ -33,7 +29,7 @@ typedef struct {
*
* @arglen number of bytes required for arguments
*/
-int trace_record_start(TraceBufferRecord *rec, TraceEventID id, size_t arglen);
+int trace_record_start(TraceBufferRecord *rec, uint32_t id, size_t arglen);
/**
* Append a 64-bit argument to a trace record
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();