qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

trace: add TRACE_<event>_BACKEND_DSTATE()

QEMU keeps track of trace event enabled/disabled state and provides
monitor commands to inspect and modify the "dstate". SystemTap and
LTTng UST maintain independent enabled/disabled states for each trace
event, the other backends rely on QEMU dstate.

Introduce a new per-event macro that combines backend-specific dstate
like this:

#define TRACE_MY_EVENT_BACKEND_DSTATE() ( \
QEMU_MY_EVENT_ENABLED() || /* SystemTap */ \
tracepoint_enabled(qemu, my_event) /* LTTng UST */ || \
false)

This will be used to extend trace_event_get_state() in the next patch.

[Daniel Berrange pointed out that QEMU_MY_EVENT_ENABLED() must be true
by default, not false. This way events will fire even if the DTrace
implementation does not implement the SystemTap semaphores feature.

Ubuntu Precise uses lttng-ust-dev 2.0.2 which does not have
tracepoint_enabled(), so we need a compatibility wrapper to keep Travis
builds passing.
--Stefan]

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20170731140718.22010-2-stefanha@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>

fixup! trace: add TRACE_<event>_BACKEND_DSTATE()

+56
+1
scripts/tracetool/__init__.py
··· 271 271 QEMU_TRACE_NOCHECK = "_nocheck__" + QEMU_TRACE 272 272 QEMU_TRACE_TCG = QEMU_TRACE + "_tcg" 273 273 QEMU_DSTATE = "_TRACE_%(NAME)s_DSTATE" 274 + QEMU_BACKEND_DSTATE = "TRACE_%(NAME)s_BACKEND_DSTATE" 274 275 QEMU_EVENT = "_TRACE_%(NAME)s_EVENT" 275 276 276 277 def api(self, fmt=None):
+3
scripts/tracetool/backend/__init__.py
··· 119 119 def generate(self, event, group): 120 120 self._run_function("generate_%s", event, group) 121 121 122 + def generate_backend_dstate(self, event, group): 123 + self._run_function("generate_%s_backend_dstate", event, group) 124 + 122 125 def generate_end(self, events, group): 123 126 self._run_function("generate_%s_end", events, group)
+12
scripts/tracetool/backend/dtrace.py
··· 44 44 out('#include "%s"' % header, 45 45 '') 46 46 47 + # SystemTap defines <provider>_<name>_ENABLED() but other DTrace 48 + # implementations might not. 49 + for e in events: 50 + out('#ifndef QEMU_%(uppername)s_ENABLED', 51 + '#define QEMU_%(uppername)s_ENABLED() true', 52 + '#endif', 53 + uppername=e.name.upper()) 47 54 48 55 def generate_h(event, group): 49 56 out(' QEMU_%(uppername)s(%(argnames)s);', 50 57 uppername=event.name.upper(), 51 58 argnames=", ".join(event.args.names())) 59 + 60 + 61 + def generate_h_backend_dstate(event, group): 62 + out(' QEMU_%(uppername)s_ENABLED() || \\', 63 + uppername=event.name.upper())
+5
scripts/tracetool/backend/ftrace.py
··· 45 45 event_id="TRACE_" + event.name.upper(), 46 46 fmt=event.fmt.rstrip("\n"), 47 47 argnames=argnames) 48 + 49 + 50 + def generate_h_backend_dstate(event, group): 51 + out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\', 52 + event_id="TRACE_" + event.name.upper())
+5
scripts/tracetool/backend/log.py
··· 48 48 name=event.name, 49 49 fmt=event.fmt.rstrip("\n"), 50 50 argnames=argnames) 51 + 52 + 53 + def generate_h_backend_dstate(event, group): 54 + out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\', 55 + event_id="TRACE_" + event.name.upper())
+5
scripts/tracetool/backend/simple.py
··· 42 42 args=", ".join(event.args.names())) 43 43 44 44 45 + def generate_h_backend_dstate(event, group): 46 + out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\', 47 + event_id="TRACE_" + event.name.upper()) 48 + 49 + 45 50 def generate_c_begin(events, group): 46 51 out('#include "qemu/osdep.h"', 47 52 '#include "trace/control.h"',
+5
scripts/tracetool/backend/syslog.py
··· 42 42 name=event.name, 43 43 fmt=event.fmt.rstrip("\n"), 44 44 argnames=argnames) 45 + 46 + 47 + def generate_h_backend_dstate(event, group): 48 + out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\', 49 + event_id="TRACE_" + event.name.upper())
+10
scripts/tracetool/backend/ust.py
··· 27 27 28 28 out('#include <lttng/tracepoint.h>', 29 29 '#include "%s"' % header, 30 + '', 31 + '/* tracepoint_enabled() was introduced in LTTng UST 2.7 */', 32 + '#ifndef tracepoint_enabled', 33 + '#define tracepoint_enabled(a, b) true', 34 + '#endif', 30 35 '') 31 36 32 37 ··· 38 43 out(' tracepoint(qemu, %(name)s%(tp_args)s);', 39 44 name=event.name, 40 45 tp_args=argnames) 46 + 47 + 48 + def generate_h_backend_dstate(event, group): 49 + out(' tracepoint_enabled(qemu, %(name)s) || \\', 50 + name=event.name)
+10
scripts/tracetool/format/h.py
··· 49 49 backend.generate_begin(events, group) 50 50 51 51 for e in events: 52 + # tracer-specific dstate 53 + out('', 54 + '#define %(api)s() ( \\', 55 + api=e.api(e.QEMU_BACKEND_DSTATE)) 56 + 57 + if "disable" not in e.properties: 58 + backend.generate_backend_dstate(e, group) 59 + 60 + out(' false)') 61 + 52 62 # tracer without checks 53 63 out('', 54 64 'static inline void %(api)s(%(args)s)',