From 3596f524d4257ede23f68b7005c4548660db463a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Date: Thu, 25 Feb 2016 17:43:04 +0100 Subject: trace: Extend API to manage event arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lets the user manage event arguments as a list, and simplifies argument concatenation. Signed-off-by: Lluís Vilanova Reviewed-by: Eric Blake Message-id: 145641858432.30295.3069911069472672646.stgit@localhost Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/__init__.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 181675f..0663e7f 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -50,9 +50,14 @@ class Arguments: Parameters ---------- args : - List of (type, name) tuples. + List of (type, name) tuples or Arguments objects. """ - self._args = args + self._args = [] + for arg in args: + if isinstance(arg, Arguments): + self._args.extend(arg._args) + else: + self._args.append(arg) def copy(self): """Create a new copy.""" @@ -83,6 +88,12 @@ class Arguments: res.append((arg_type, identifier)) return Arguments(res) + def __getitem__(self, index): + if isinstance(index, slice): + return Arguments(self._args[index]) + else: + return self._args[index] + def __iter__(self): """Iterate over the (type, name) pairs.""" return iter(self._args) -- cgit v1.1 From 56797b1fbce86b3844cec753100a7260b9132a6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Date: Thu, 25 Feb 2016 17:43:10 +0100 Subject: trace: Remove unnecessary intermediate event copies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current code forces the use of a chain of ".original" dereferences, which looks odd. Signed-off-by: Lluís Vilanova Message-id: 145641858988.30295.7223459456488075843.stgit@localhost Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/__init__.py | 5 ++--- scripts/tracetool/format/events_h.py | 4 ++-- scripts/tracetool/format/tcg_h.py | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 0663e7f..26878f4 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -6,7 +6,7 @@ Machinery for generating tracing-related intermediate files. """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -288,13 +288,12 @@ def _read_events(fobj): if atrans == aorig: args_trans.append(atrans) event_trans.args = Arguments(args_trans) - event_trans = event_trans.copy() event_exec = event.copy() event_exec.name += "_exec" event_exec.properties += ["tcg-exec"] event_exec.fmt = event.fmt[1] - event_exec = event_exec.transform(tracetool.transform.TCG_2_HOST) + event_exec.args = event_exec.args.transform(tracetool.transform.TCG_2_HOST) new_event = [event_trans, event_exec] event.event_trans, event.event_exec = new_event diff --git a/scripts/tracetool/format/events_h.py b/scripts/tracetool/format/events_h.py index 9f114a3..bbfaa5b 100644 --- a/scripts/tracetool/format/events_h.py +++ b/scripts/tracetool/format/events_h.py @@ -6,7 +6,7 @@ trace/generated-events.h """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -43,7 +43,7 @@ def generate(events, backend): if "tcg-trans" in e.properties: # a single define for the two "sub-events" out('#define TRACE_%(name)s_ENABLED %(enabled)d', - name=e.original.original.name.upper(), + name=e.original.name.upper(), enabled=enabled) out('#define TRACE_%s_ENABLED %d' % (e.name.upper(), enabled)) diff --git a/scripts/tracetool/format/tcg_h.py b/scripts/tracetool/format/tcg_h.py index f676b66..0d2cf79 100644 --- a/scripts/tracetool/format/tcg_h.py +++ b/scripts/tracetool/format/tcg_h.py @@ -6,7 +6,7 @@ Generate .h file for TCG code generation. """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -36,7 +36,7 @@ def generate(events, backend): continue # get the original event definition - e = e.original.original + e = e.original out('static inline void %(name_tcg)s(%(args)s)', '{', -- cgit v1.1 From bc9beb47c7822628cf7028ba177b390eabbe88a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Date: Thu, 25 Feb 2016 17:43:27 +0100 Subject: trace: Add helper function to cast event arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lluís Vilanova Message-id: 145641860680.30295.1873612736245870753.stgit@localhost Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 26878f4..9e02f73 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -121,6 +121,10 @@ class Arguments: """List of argument types.""" return [ type_ for type_, _ in self._args ] + def casted(self): + """List of argument names casted to their type.""" + return ["(%s)%s" % (type_, name) for type_, name in self._args] + def transform(self, *trans): """Return a new Arguments instance with transformed types. -- cgit v1.1 From 3d211d9f4dbee7483f092c287ef20d8336100445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Date: Thu, 25 Feb 2016 17:43:38 +0100 Subject: trace: Add 'vcpu' event property to trace guest vCPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This property identifies events that trace vCPU-specific information. It adds a "CPUState*" argument to events with the property, identifying the vCPU raising the event. TCG translation events also have a "TCGv_env" implicit argument that is later used as the "CPUState*" argument at execution time. Signed-off-by: Lluís Vilanova Message-id: 145641861797.30295.6991314023181842105.stgit@localhost Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/__init__.py | 11 +++- scripts/tracetool/format/h.py | 3 +- scripts/tracetool/format/tcg_h.py | 31 +++++++---- scripts/tracetool/format/tcg_helper_c.py | 45 +++++++++++---- scripts/tracetool/format/tcg_helper_h.py | 7 +-- scripts/tracetool/format/tcg_helper_wrapper_h.py | 5 +- scripts/tracetool/format/ust_events_c.py | 1 + scripts/tracetool/transform.py | 4 +- scripts/tracetool/vcpu.py | 70 ++++++++++++++++++++++++ 9 files changed, 146 insertions(+), 31 deletions(-) create mode 100644 scripts/tracetool/vcpu.py (limited to 'scripts') diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 9e02f73..23caba0 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -161,7 +161,7 @@ class Event(object): "(?:(?:(?P\".+),)?\s*(?P\".+))?" "\s*") - _VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec"]) + _VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec", "vcpu"]) def __init__(self, name, props, fmt, args, orig=None): """ @@ -230,7 +230,13 @@ class Event(object): if "tcg" in props and isinstance(fmt, str): raise ValueError("Events with 'tcg' property must have two formats") - return Event(name, props, fmt, args) + event = Event(name, props, fmt, args) + + # add implicit arguments when using the 'vcpu' property + import tracetool.vcpu + event = tracetool.vcpu.transform_event(event) + + return event def __repr__(self): """Evaluable string representation for this object.""" @@ -285,6 +291,7 @@ def _read_events(fobj): event_trans.name += "_trans" event_trans.properties += ["tcg-trans"] event_trans.fmt = event.fmt[0] + # ignore TCG arguments args_trans = [] for atrans, aorig in zip( event_trans.transform(tracetool.transform.TCG_2_HOST).args, diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py index 9b39430..2bd68a2 100644 --- a/scripts/tracetool/format/h.py +++ b/scripts/tracetool/format/h.py @@ -6,7 +6,7 @@ trace/generated-tracers.h """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -23,6 +23,7 @@ def generate(events, backend): '#define TRACE__GENERATED_TRACERS_H', '', '#include "qemu-common.h"', + '#include "qemu/typedefs.h"', '') backend.generate_begin(events) diff --git a/scripts/tracetool/format/tcg_h.py b/scripts/tracetool/format/tcg_h.py index 0d2cf79..006eaa8 100644 --- a/scripts/tracetool/format/tcg_h.py +++ b/scripts/tracetool/format/tcg_h.py @@ -13,7 +13,18 @@ __maintainer__ = "Stefan Hajnoczi" __email__ = "stefanha@linux.vnet.ibm.com" -from tracetool import out +from tracetool import out, Arguments +import tracetool.vcpu + + +def vcpu_transform_args(args): + assert len(args) == 1 + return Arguments([ + args, + # NOTE: this name must be kept in sync with the one in "tcg_h" + # NOTE: Current helper code uses TCGv_env (CPUArchState*) + ("TCGv_env", "__tcg_" + args.names()[0]), + ]) def generate(events, backend): @@ -35,21 +46,21 @@ def generate(events, backend): if "tcg-trans" not in e.properties: continue - # get the original event definition - e = e.original - out('static inline void %(name_tcg)s(%(args)s)', '{', - name_tcg=e.api(e.QEMU_TRACE_TCG), - args=e.args) + name_tcg=e.original.api(e.QEMU_TRACE_TCG), + args=tracetool.vcpu.transform_args("tcg_h", e.original)) if "disable" not in e.properties: + args_trans = e.original.event_trans.args + args_exec = tracetool.vcpu.transform_args( + "tcg_helper_c", e.original.event_exec, "wrapper") out(' %(name_trans)s(%(argnames_trans)s);', ' gen_helper_%(name_exec)s(%(argnames_exec)s);', - name_trans=e.event_trans.api(e.QEMU_TRACE), - name_exec=e.event_exec.api(e.QEMU_TRACE), - argnames_trans=", ".join(e.event_trans.args.names()), - argnames_exec=", ".join(e.event_exec.args.names())) + name_trans=e.original.event_trans.api(e.QEMU_TRACE), + name_exec=e.original.event_exec.api(e.QEMU_TRACE), + argnames_trans=", ".join(args_trans.names()), + argnames_exec=", ".join(args_exec.names())) out('}') diff --git a/scripts/tracetool/format/tcg_helper_c.py b/scripts/tracetool/format/tcg_helper_c.py index afd6e98..a089b0b 100644 --- a/scripts/tracetool/format/tcg_helper_c.py +++ b/scripts/tracetool/format/tcg_helper_c.py @@ -6,15 +6,38 @@ Generate trace/generated-helpers.c. """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __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 import Arguments, out from tracetool.transform import * +import tracetool.vcpu + + +def vcpu_transform_args(args, mode): + assert len(args) == 1 + # NOTE: this name must be kept in sync with the one in "tcg_h" + args = Arguments([(args.types()[0], "__tcg_" + args.names()[0])]) + if mode == "code": + return Arguments([ + # Does cast from helper requirements to tracing types + ("CPUState *", "ENV_GET_CPU(%s)" % args.names()[0]), + ]) + else: + args = Arguments([ + # NOTE: Current helper code uses TCGv_env (CPUArchState*) + ("CPUArchState *", args.names()[0]), + ]) + if mode == "header": + return args + elif mode == "wrapper": + return args.transform(HOST_2_TCG) + else: + assert False def generate(events, backend): @@ -34,18 +57,18 @@ def generate(events, backend): if "tcg-exec" not in e.properties: continue - # tracetool.generate always transforms types to host - e_args = e.original.args - - values = ["(%s)%s" % (t, n) - for t, n in e.args.transform(TCG_2_TCG_HELPER_DEF)] + e_args_api = tracetool.vcpu.transform_args( + "tcg_helper_c", e.original, "header").transform( + HOST_2_TCG_COMPAT, TCG_2_TCG_HELPER_DEF) + e_args_call = tracetool.vcpu.transform_args( + "tcg_helper_c", e, "code") - out('void %(name_tcg)s(%(args)s)', + out('void %(name_tcg)s(%(args_api)s)', '{', - ' %(name)s(%(values)s);', + ' %(name)s(%(args_call)s);', '}', name_tcg="helper_%s_proxy" % e.api(), name=e.api(), - args=e_args.transform(HOST_2_TCG_COMPAT, TCG_2_TCG_HELPER_DEF), - values=", ".join(values), + args_api=e_args_api, + args_call=", ".join(e_args_call.casted()), ) diff --git a/scripts/tracetool/format/tcg_helper_h.py b/scripts/tracetool/format/tcg_helper_h.py index a8ba7ba..dc76c15 100644 --- a/scripts/tracetool/format/tcg_helper_h.py +++ b/scripts/tracetool/format/tcg_helper_h.py @@ -6,7 +6,7 @@ Generate trace/generated-helpers.h. """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -15,6 +15,7 @@ __email__ = "stefanha@linux.vnet.ibm.com" from tracetool import out from tracetool.transform import * +import tracetool.vcpu def generate(events, backend): @@ -29,11 +30,9 @@ def generate(events, backend): if "tcg-exec" not in e.properties: continue - # tracetool.generate always transforms types to host - e_args = e.original.args - # TCG helper proxy declaration fmt = "DEF_HELPER_FLAGS_%(argc)d(%(name)s, %(flags)svoid%(types)s)" + e_args = tracetool.vcpu.transform_args("tcg_helper_c", e.original, "header") args = e_args.transform(HOST_2_TCG_COMPAT, HOST_2_TCG, TCG_2_TCG_HELPER_DECL) types = ", ".join(args.types()) diff --git a/scripts/tracetool/format/tcg_helper_wrapper_h.py b/scripts/tracetool/format/tcg_helper_wrapper_h.py index cac5a87..020f442 100644 --- a/scripts/tracetool/format/tcg_helper_wrapper_h.py +++ b/scripts/tracetool/format/tcg_helper_wrapper_h.py @@ -6,7 +6,7 @@ Generate trace/generated-helpers-wrappers.h. """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -15,6 +15,7 @@ __email__ = "stefanha@linux.vnet.ibm.com" from tracetool import out from tracetool.transform import * +import tracetool.vcpu def generate(events, backend): @@ -33,7 +34,7 @@ def generate(events, backend): continue # tracetool.generate always transforms types to host - e_args = e.original.args + e_args = tracetool.vcpu.transform_args("tcg_helper_c", e.original, "wrapper") # mixed-type to TCG helper bridge args_tcg_compat = e_args.transform(HOST_2_TCG_COMPAT) diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/format/ust_events_c.py index 9967c7a..bf0b334 100644 --- a/scripts/tracetool/format/ust_events_c.py +++ b/scripts/tracetool/format/ust_events_c.py @@ -32,4 +32,5 @@ def generate(events, backend): ' */', '#pragma GCC diagnostic ignored "-Wredundant-decls"', '', + '#include "qemu/typedefs.h"', '#include "generated-ust-provider.h"') diff --git a/scripts/tracetool/transform.py b/scripts/tracetool/transform.py index fc5e679..e18b053 100644 --- a/scripts/tracetool/transform.py +++ b/scripts/tracetool/transform.py @@ -6,7 +6,7 @@ Type-transformation rules. """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -98,6 +98,7 @@ HOST_2_TCG = { "uint32_t": "TCGv_i32", "uint64_t": "TCGv_i64", "void *" : "TCGv_ptr", + "CPUArchState *": "TCGv_env", None: _host_2_tcg, } @@ -130,6 +131,7 @@ TCG_2_TCG_HELPER_DECL = { "TCGv_ptr": "ptr", "TCGv_i32": "i32", "TCGv_i64": "i64", + "TCGv_env": "env", None: _tcg_2_tcg_helper_decl_error, } diff --git a/scripts/tracetool/vcpu.py b/scripts/tracetool/vcpu.py new file mode 100644 index 0000000..452c7f5 --- /dev/null +++ b/scripts/tracetool/vcpu.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Generic management for the 'vcpu' property. + +""" + +__author__ = "Lluís Vilanova " +__copyright__ = "Copyright 2016, Lluís Vilanova " +__license__ = "GPL version 2 or (at your option) any later version" + +__maintainer__ = "Stefan Hajnoczi" +__email__ = "stefanha@linux.vnet.ibm.com" + + +from tracetool import Arguments, try_import + + +def transform_event(event): + """Transform event to comply with the 'vcpu' property (if present).""" + if "vcpu" in event.properties: + # events with 'tcg-trans' and 'tcg-exec' are auto-generated from + # already-patched events + assert "tcg-trans" not in event.properties + assert "tcg-exec" not in event.properties + + event.args = Arguments([("CPUState *", "__cpu"), event.args]) + if "tcg" in event.properties: + fmt = "\"cpu=%p \"" + event.fmt = [fmt + event.fmt[0], + fmt + event.fmt[1]] + else: + fmt = "\"cpu=%p \"" + event.fmt = fmt + event.fmt + return event + + +def transform_args(format, event, *args, **kwargs): + """Transforms the arguments to suit the specified format. + + The format module must implement function 'vcpu_args', which receives the + implicit arguments added by the 'vcpu' property, and must return suitable + arguments for the given format. + + The function is only called for events with the 'vcpu' property. + + Parameters + ========== + format : str + Format module name. + event : Event + args, kwargs + Passed to 'vcpu_transform_args'. + + Returns + ======= + Arguments + The transformed arguments, including the non-implicit ones. + + """ + if "vcpu" in event.properties: + ok, func = try_import("tracetool.format." + format, + "vcpu_transform_args") + assert ok + assert func + return Arguments([func(event.args[:1], *args, **kwargs), + event.args[1:]]) + else: + return event.args -- cgit v1.1 From 4ade0541de712fbf151ac7a2403613a1dbdb25b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Date: Thu, 25 Feb 2016 14:06:30 +0100 Subject: trace: Add a proper API to manage auto-generated events from the 'tcg' property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Formalizes the existence of the 'event_trans' and 'event_exec' event attributes, which until now were monkey-patched only when necessary. Signed-off-by: Lluís Vilanova Message-id: 145640558759.20978.6374959404425591089.stgit@localhost Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/__init__.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 23caba0..be24039 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -163,7 +163,8 @@ class Event(object): _VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec", "vcpu"]) - def __init__(self, name, props, fmt, args, orig=None): + def __init__(self, name, props, fmt, args, orig=None, + event_trans=None, event_exec=None): """ Parameters ---------- @@ -176,13 +177,19 @@ class Event(object): args : Arguments Event arguments. orig : Event or None - Original Event before transformation. + Original Event before transformation/generation. + event_trans : Event or None + Generated translation-time event ("tcg" property). + event_exec : Event or None + Generated execution-time event ("tcg" property). """ self.name = name self.properties = props self.fmt = fmt self.args = args + self.event_trans = event_trans + self.event_exec = event_exec if orig is None: self.original = weakref.ref(self) @@ -198,7 +205,7 @@ class Event(object): def copy(self): """Create a new copy.""" return Event(self.name, list(self.properties), self.fmt, - self.args.copy(), self) + self.args.copy(), self, self.event_trans, self.event_exec) @staticmethod def build(line_str): -- cgit v1.1