@@ -5,6 +5,8 @@
/config-target.*
/config.status
/config-temp
+/instrument-root.h
+/instrument/generated-tcg-tracers.h
/trace-events-all
/trace/generated-events.h
/trace/generated-events.c
@@ -116,6 +118,7 @@ tags
TAGS
docker-src.*
*~
+instrument.h
trace.h
trace.c
trace-ust.h
@@ -191,6 +191,29 @@ trace-dtrace-root.h: trace-dtrace-root.dtrace
trace-dtrace-root.o: trace-dtrace-root.dtrace
+INSTRUMENT_HEADERS = instrument-root.h $(trace-events-subdirs:%=%/instrument.h)
+INSTRUMENT_HEADERS += instrument/generated-tcg-tracers.h
+
+GENERATED_FILES += $(INSTRUMENT_HEADERS)
+
+%/instrument.h: %/instrument.h-timestamp
+ @cmp $< $@ >/dev/null 2>&1 || cp $< $@
+%/instrument.h-timestamp: $(SRC_PATH)/%/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
+ $(call quiet-command,$(TRACETOOL) \
+ --group=$(call trace-group-name,$@) \
+ --format=instr-h \
+ --backends=$(TRACE_INSTRUMENT_BACKEND) \
+ $< > $@,"GEN","$(@:%-timestamp=%)")
+
+instrument-root.h: instrument-root.h-timestamp
+ @cmp $< $@ >/dev/null 2>&1 || cp $< $@
+instrument-root.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
+ $(call quiet-command,$(TRACETOOL) \
+ --group=root \
+ --format=instr-h \
+ --backends=$(TRACE_INSTRUMENT_BACKEND) \
+ $< > $@,"GEN","$(@:%-timestamp=%)")
+
# Don't try to regenerate Makefile or configure
# We don't generate any of them
Makefile: ;
@@ -806,7 +829,8 @@ endif
.SECONDARY: $(TRACE_HEADERS) $(TRACE_HEADERS:%=%-timestamp) \
$(TRACE_SOURCES) $(TRACE_SOURCES:%=%-timestamp) \
- $(TRACE_DTRACE) $(TRACE_DTRACE:%=%-timestamp)
+ $(TRACE_DTRACE) $(TRACE_DTRACE:%=%-timestamp) \
+ $(INSTRUMENT_HEADERS) $(INSTRUMENT_HEADERS:%=%-timestamp)
# Include automatically generated dependency files
# Dependencies in Makefile.objs files come from our recursive subdir rules
@@ -98,6 +98,10 @@ util-obj-y += trace/
target-obj-y += trace/
######################################################################
+# instrumentation
+util-obj-y += instrument/
+
+######################################################################
# guest agent
# FIXME: a few definitions from qapi-types.o/qapi-visit.o are needed
@@ -351,6 +351,8 @@ pie=""
qom_cast_debug="yes"
trace_backends="log"
trace_file="trace"
+trace_instrument="no"
+trace_instrument_backend="none"
spice=""
rbd=""
smartcard=""
@@ -5282,6 +5284,7 @@ echo "Trace backends $trace_backends"
if have_backend "simple"; then
echo "Trace output file $trace_file-<pid>"
fi
+echo "Trace instrumentation $trace_instrument"
echo "spice support $spice $(echo_version $spice $spice_protocol_version/$spice_server_version)"
echo "rbd support $rbd"
echo "xfsctl support $xfs"
@@ -5989,6 +5992,11 @@ else
fi
QEMU_INCLUDES="-I\$(SRC_PATH)/tcg $QEMU_INCLUDES"
+##########################################
+# trace instrumentation
+echo "TRACE_INSTRUMENT_BACKEND=instr-$trace_instrument_backend" >> $config_host_mak
+##########################################
+
echo "TOOLS=$tools" >> $config_host_mak
echo "ROMS=$roms" >> $config_host_mak
echo "MAKE=$make" >> $config_host_mak
@@ -2,5 +2,6 @@
#define TRACE_TCG_H
#include "trace/generated-tcg-tracers.h"
+#include "instrument/generated-tcg-tracers.h"
#endif /* TRACE_TCG_H */
new file mode 100644
@@ -0,0 +1,14 @@
+# -*- mode: makefile -*-
+
+######################################################################
+# QEMU trace->instrument interface
+
+$(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp
+ @cmp $< $@ >/dev/null 2>&1 || cp $< $@
+$(obj)/generated-tcg-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
+ @mkdir -p $(dir $@)
+ $(call quiet-command,$(TRACETOOL) \
+ --group=root \
+ --format=instr-tcg-h \
+ --backend=$(TRACE_INSTRUMENT_BACKEND) \
+ $< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
@@ -161,7 +161,7 @@ class Event(object):
"(?:(?:(?P<fmt_trans>\".+),)?\s*(?P<fmt>\".+))?"
"\s*")
- _VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec", "vcpu"])
+ _VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec", "vcpu", "instrument"])
def __init__(self, name, props, fmt, args, orig=None,
event_trans=None, event_exec=None):
@@ -269,13 +269,15 @@ class Event(object):
QEMU_TRACE = "trace_%(name)s"
QEMU_TRACE_NOCHECK = "_nocheck__" + QEMU_TRACE
+ QEMU_TRACE_BACKEND = "_backend__" + QEMU_TRACE
QEMU_TRACE_TCG = QEMU_TRACE + "_tcg"
+ QEMU_TRACE_TCG_BACKEND = "_backend__" + 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
+ fmt = Event.QEMU_TRACE_BACKEND
return fmt % {"name": self.name, "NAME": self.name.upper()}
def transform(self, *trans):
new file mode 100644
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+No-instrumentation proxy.
+"""
+
+__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2017, 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
+
+
+##################################################
+# instr-tcg-h
+
+def generate_instr_tcg_h(event, group):
+ out(' %(backend)s(%(argnames)s);',
+ backend=event.api(event.QEMU_TRACE_TCG_BACKEND),
+ argnames=", ".join(event.args.names()))
+
+
+##################################################
+# instr-h
+
+def generate_instr_h(event, group):
+ out(' %(backend)s(%(argnames)s);',
+ backend=event.api(event.QEMU_TRACE_BACKEND),
+ argnames=", ".join(event.args.names()))
@@ -87,4 +87,10 @@ def generate(events, backend, group):
backend.generate_end(events, group)
- out('#endif /* TRACE_%s_GENERATED_TRACERS_H */' % group.upper())
+ out('')
+ if group == "root":
+ out('#include "instrument-root.h"')
+ else:
+ out('#include "instrument.h"')
+ out('',
+ '#endif /* TRACE_%s_GENERATED_TRACERS_H */' % group.upper())
new file mode 100644
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+/instrument-root.h
+.../instrument.h
+
+"""
+
+__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2017, 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
+from tracetool.transform import *
+
+
+def generate(events, backend, group):
+ out('/* This file is autogenerated by tracetool, do not edit. */',
+ '',
+ '#ifndef INSTRUMENT_%s_GENERATED_TRACERS_H' % group.upper(),
+ '#define INSTRUMENT_%s_GENERATED_TRACERS_H' % group.upper(),
+ '')
+ backend.generate_begin(events, group)
+
+ for e in events:
+ out('static inline void %(qemu)s(%(args)s)',
+ '{',
+ qemu=e.api(e.QEMU_TRACE),
+ args=e.args)
+
+ if "tcg-trans" in e.properties or "instrument" not in e.properties:
+ # "*_trans" never called directly (and never instrumented)
+ out(' %(backend)s(%(argnames)s);',
+ backend=e.api(e.QEMU_TRACE_BACKEND),
+ argnames=", ".join(e.args.names()))
+ else:
+ backend.generate(e, group)
+
+ out('}')
+
+ backend.generate_end(events, group)
+ out('',
+ '#endif /* INSTRUMENT_%s_GENERATED_TRACERS_H */' % group.upper())
new file mode 100644
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+instrument/generated-tcg-tracers.h
+
+"""
+
+__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2017, 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, Arguments
+import tracetool.vcpu
+
+
+API = True
+
+
+def generate(events, backend, group):
+ events = [e.original for e in events
+ if "tcg-trans" in e.properties]
+
+ out('/* This file is autogenerated by tracetool, do not edit. */',
+ '',
+ '#ifndef INSTRUMENT_%s_GENERATED_TCG_TRACERS_H' % group.upper(),
+ '#define INSTRUMENT_%s_GENERATED_TCG_TRACERS_H' % group.upper(),
+ '')
+ backend.generate_begin(events, group)
+
+ for e in events:
+ args_api = tracetool.vcpu.transform_args("tcg_h", e)
+
+ out('static inline void %(qemu)s(%(args)s)',
+ '{',
+ qemu=e.api(e.QEMU_TRACE_TCG),
+ args=args_api)
+
+ if "instrument" in e.properties:
+ e = e.copy()
+ e.args = args_api
+ backend.generate(e, group)
+ else:
+ out(' %(backend)s(%(argnames)s);',
+ backend=e.api(e.QEMU_TRACE_TCG_BACKEND),
+ argnames=", ".join(args_api.names()))
+
+ out('}')
+
+ backend.generate_end(events, group)
+ out('',
+ '#endif /* INSTRUMENT_%s_GENERATED_TCG_TRACERS_H */' % group.upper())
@@ -51,7 +51,7 @@ def generate(events, backend, group):
out('static inline void %(name_tcg)s(%(args)s)',
'{',
- name_tcg=e.original.api(e.QEMU_TRACE_TCG),
+ name_tcg=e.original.api(e.QEMU_TRACE_TCG_BACKEND),
args=tracetool.vcpu.transform_args("tcg_h", e.original))
if "disable" not in e.properties:
@@ -72,8 +72,8 @@ def generate(events, backend, group):
' if (%(cond)s) {',
' gen_helper_%(name_exec)s(%(argnames_exec)s);',
' }',
- name_trans=e.original.event_trans.api(e.QEMU_TRACE),
- name_exec=e.original.event_exec.api(e.QEMU_TRACE),
+ name_trans=e.original.event_trans.api(e.QEMU_TRACE_BACKEND),
+ name_exec=e.original.event_exec.api(e.QEMU_TRACE_BACKEND),
argnames_trans=", ".join(args_trans.names()),
argnames_exec=", ".join(args_exec.names()),
cond=cond)
@@ -74,7 +74,7 @@ def generate(events, backend, group):
# NOTE: the check was already performed at TCG-generation time
' %(name)s(%(args_call)s);',
'}',
- name_tcg="helper_%s_proxy" % e.api(),
+ name_tcg="helper_%s_proxy" % e.api(e.QEMU_TRACE_BACKEND),
name=e.api(e.QEMU_TRACE_NOCHECK),
args_api=e_args_api,
args_call=", ".join(e_args_call.casted()),
@@ -44,6 +44,6 @@ def generate(events, backend, group):
out(fmt,
flags=flags,
argc=len(args),
- name=e.api() + "_proxy",
+ name=e.api(e.QEMU_TRACE_BACKEND) + "_proxy",
types=types,
)
@@ -54,7 +54,7 @@ def generate(events, backend, group):
for (type_, name) in args_tcg_compat
]
- gen_name = "gen_helper_" + e.api()
+ gen_name = "gen_helper_" + e.api(e.QEMU_TRACE_BACKEND)
out('static inline void %(name)s(%(args)s)',
'{',
Renames existing tracing routines into "_backend__trace_*", and instead adds an instrumentation-aware "trace_*". Since we're in a "null" instrumentation mode for tracing events, the new routines simply call the original tracing code. Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> --- .gitignore | 3 + Makefile | 26 ++++++++++ Makefile.objs | 4 ++ configure | 8 +++ include/trace-tcg.h | 1 instrument/Makefile.objs | 14 ++++++ scripts/tracetool/__init__.py | 6 ++ scripts/tracetool/backend/instr_none.py | 34 +++++++++++++ scripts/tracetool/format/h.py | 8 +++ scripts/tracetool/format/instr_h.py | 48 +++++++++++++++++++ scripts/tracetool/format/instr_tcg_h.py | 56 ++++++++++++++++++++++ scripts/tracetool/format/tcg_h.py | 6 +- scripts/tracetool/format/tcg_helper_c.py | 2 - scripts/tracetool/format/tcg_helper_h.py | 2 - scripts/tracetool/format/tcg_helper_wrapper_h.py | 2 - 15 files changed, 210 insertions(+), 10 deletions(-) create mode 100644 instrument/Makefile.objs create mode 100644 scripts/tracetool/backend/instr_none.py create mode 100644 scripts/tracetool/format/instr_h.py create mode 100644 scripts/tracetool/format/instr_tcg_h.py