From 50873504dc3cc67ca06b4ebf307d084316e407a6 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 29 Sep 2025 17:49:23 +0200 Subject: [PATCH 01/16] tracetool: fix usage of try_import() try_import returns a tuple of a boolean and the requested module or attribute. exists() functions return tracetool.try_import("tracetool.format." + name)[1] but they should return the boolean value instead. Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-ID: <20250929154938.594389-2-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/backend/__init__.py | 2 +- scripts/tracetool/format/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py index 7bfcc86cc5..6c6344dedd 100644 --- a/scripts/tracetool/backend/__init__.py +++ b/scripts/tracetool/backend/__init__.py @@ -94,7 +94,7 @@ def exists(name): if name == "nop": return True name = name.replace("-", "_") - return tracetool.try_import("tracetool.backend." + name)[1] + return tracetool.try_import("tracetool.backend." + name)[0] class Wrapper: diff --git a/scripts/tracetool/format/__init__.py b/scripts/tracetool/format/__init__.py index 2dc46f3dd9..042fe7d103 100644 --- a/scripts/tracetool/format/__init__.py +++ b/scripts/tracetool/format/__init__.py @@ -70,7 +70,7 @@ def exists(name): if len(name) == 0: return False name = name.replace("-", "_") - return tracetool.try_import("tracetool.format." + name)[1] + return tracetool.try_import("tracetool.format." + name)[0] def generate(events, format, backend, group): From 4c2f770f67e0b0d8b512defca4d81bd09936ab85 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 29 Sep 2025 17:49:24 +0200 Subject: [PATCH 02/16] tracetool: remove dead code Remove a bunch of dead code from tracetool. In particular, there are no tcg-exec events anymore and the sub-event functionality was only used for it. Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-ID: <20250929154938.594389-3-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/__init__.py | 45 +++----------------- scripts/tracetool/format/h.py | 5 --- scripts/tracetool/format/log_stap.py | 2 - scripts/tracetool/format/simpletrace_stap.py | 2 - 4 files changed, 6 insertions(+), 48 deletions(-) diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 1d5238a084..4ef1dc1fca 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -15,7 +15,6 @@ __email__ = "stefanha@redhat.com" import os import re import sys -import weakref from pathlib import PurePath import tracetool.backend @@ -122,10 +121,6 @@ class Arguments: else: self._args.append(arg) - def copy(self): - """Create a new copy.""" - return Arguments(list(self._args)) - @staticmethod def build(arg_str): """Build and Arguments instance from an argument string. @@ -222,13 +217,12 @@ class Event(object): r"(?P\w+)" r"\((?P[^)]*)\)" r"\s*" - r"(?:(?:(?P\".+),)?\s*(?P\".+))?" + r"(?P\".+)?" r"\s*") _VALID_PROPS = set(["disable"]) - def __init__(self, name, props, fmt, args, lineno, filename, orig=None, - event_trans=None, event_exec=None): + def __init__(self, name, props, fmt, args, lineno, filename): """ Parameters ---------- @@ -236,20 +230,14 @@ class Event(object): Event name. props : list of str Property names. - fmt : str, list of str - Event printing format string(s). + fmt : str + Event printing format string. args : Arguments Event arguments. lineno : int The line number in the input file. filename : str The path to the input file. - orig : Event or None - 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 @@ -258,29 +246,16 @@ class Event(object): self.args = args self.lineno = int(lineno) self.filename = str(filename) - self.event_trans = event_trans - self.event_exec = event_exec if len(args) > 10: raise ValueError("Event '%s' has more than maximum permitted " "argument count" % name) - if orig is None: - self.original = weakref.ref(self) - else: - self.original = orig - unknown_props = set(self.properties) - self._VALID_PROPS if len(unknown_props) > 0: raise ValueError("Unknown properties: %s" % ", ".join(unknown_props)) - assert isinstance(self.fmt, str) or len(self.fmt) == 2 - def copy(self): - """Create a new copy.""" - return Event(self.name, list(self.properties), self.fmt, - self.args.copy(), self.lineno, self.filename, - self, self.event_trans, self.event_exec) @staticmethod def build(line_str, lineno, filename): @@ -302,8 +277,7 @@ class Event(object): name = groups["name"] props = groups["props"].split() fmt = groups["fmt"] - fmt_trans = groups["fmt_trans"] - if fmt.find("%m") != -1 or fmt_trans.find("%m") != -1: + if fmt.find("%m") != -1: raise ValueError("Event format '%m' is forbidden, pass the error " "as an explicit trace argument") if fmt.endswith(r'\n"'): @@ -312,29 +286,22 @@ class Event(object): if '\\n' in fmt: raise ValueError("Event format must not use new line character") - if len(fmt_trans) > 0: - fmt = [fmt_trans, fmt] args = Arguments.build(groups["args"]) return Event(name, props, fmt, args, lineno, posix_relpath(filename)) def __repr__(self): """Evaluable string representation for this object.""" - if isinstance(self.fmt, str): - fmt = self.fmt - else: - fmt = "%s, %s" % (self.fmt[0], self.fmt[1]) return "Event('%s %s(%s) %s')" % (" ".join(self.properties), self.name, self.args, - fmt) + self.fmt) # Star matching on PRI is dangerous as one might have multiple # arguments with that format, hence the non-greedy version of it. _FMT = re.compile(r"(%[\d\.]*\w+|%.*?PRI\S+)") def formats(self): """List conversion specifiers in the argument print format string.""" - assert not isinstance(self.fmt, list) return self._FMT.findall(self.fmt) QEMU_TRACE = "trace_%(name)s" diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py index b42a8268a8..bd9e0ca7f2 100644 --- a/scripts/tracetool/format/h.py +++ b/scripts/tracetool/format/h.py @@ -40,11 +40,6 @@ def generate(events, backend, group): 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) diff --git a/scripts/tracetool/format/log_stap.py b/scripts/tracetool/format/log_stap.py index 710d62bffe..5b1bbe907f 100644 --- a/scripts/tracetool/format/log_stap.py +++ b/scripts/tracetool/format/log_stap.py @@ -18,8 +18,6 @@ from tracetool.backend.dtrace import binary, probeprefix from tracetool.backend.simple import is_string from tracetool.format.stap import stap_escape -def global_var_name(name): - return probeprefix().replace(".", "_") + "_" + name STATE_SKIP = 0 STATE_LITERAL = 1 diff --git a/scripts/tracetool/format/simpletrace_stap.py b/scripts/tracetool/format/simpletrace_stap.py index 72971133bf..ac39a492d9 100644 --- a/scripts/tracetool/format/simpletrace_stap.py +++ b/scripts/tracetool/format/simpletrace_stap.py @@ -17,8 +17,6 @@ from tracetool.backend.dtrace import probeprefix from tracetool.backend.simple import is_string from tracetool.format.stap import stap_escape -def global_var_name(name): - return probeprefix().replace(".", "_") + "_" + name def generate(events, backend, group): out('/* This file is autogenerated by tracetool, do not edit. */', From 20b92da6db74490a6ffdf01f3ec8d99fcb7c2c18 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 29 Sep 2025 17:49:25 +0200 Subject: [PATCH 03/16] treewide: remove unnessary "coding" header The "-*- coding: utf-8 -*-" header was needed in Python 2, but in Python 3 UTF-8 is already the default encoding of source files. It is even less necessary in .css files that do not have UTF-8 sequences at all. Suggested-by: Manos Pitsidianakis Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-ID: <20250929154938.594389-4-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- docs/conf.py | 2 -- docs/sphinx-static/theme_overrides.css | 3 +-- scripts/analyse-locks-simpletrace.py | 1 - scripts/modinfo-collect.py | 1 - scripts/modinfo-generate.py | 1 - scripts/oss-fuzz/minimize_qtest_trace.py | 1 - scripts/oss-fuzz/output_reproducer.py | 1 - scripts/oss-fuzz/reorder_fuzzer_qtest_trace.py | 1 - scripts/probe-gdb-support.py | 1 - scripts/qapi/error.py | 2 -- scripts/qapi/expr.py | 2 -- scripts/qapi/gen.py | 2 -- scripts/qapi/parser.py | 2 -- scripts/qapi/schema.py | 2 -- scripts/qemu-plugin-symbols.py | 1 - scripts/qemugdb/tcg.py | 2 -- scripts/qemugdb/timers.py | 1 - scripts/replay-dump.py | 1 - scripts/tracetool.py | 1 - scripts/tracetool/__init__.py | 2 -- scripts/tracetool/backend/__init__.py | 2 -- scripts/tracetool/backend/dtrace.py | 2 -- scripts/tracetool/backend/ftrace.py | 2 -- scripts/tracetool/backend/log.py | 2 -- scripts/tracetool/backend/simple.py | 2 -- scripts/tracetool/backend/syslog.py | 2 -- scripts/tracetool/backend/ust.py | 2 -- scripts/tracetool/format/__init__.py | 2 -- scripts/tracetool/format/c.py | 2 -- scripts/tracetool/format/d.py | 2 -- scripts/tracetool/format/h.py | 2 -- scripts/tracetool/format/log_stap.py | 2 -- scripts/tracetool/format/simpletrace_stap.py | 2 -- scripts/tracetool/format/stap.py | 2 -- scripts/tracetool/format/ust_events_c.py | 2 -- scripts/tracetool/format/ust_events_h.py | 2 -- 36 files changed, 1 insertion(+), 61 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index e09769e5f8..0c9ec74097 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# # QEMU documentation build configuration file, created by # sphinx-quickstart on Thu Jan 31 16:40:14 2019. # diff --git a/docs/sphinx-static/theme_overrides.css b/docs/sphinx-static/theme_overrides.css index b225bf706f..f312e9b57e 100644 --- a/docs/sphinx-static/theme_overrides.css +++ b/docs/sphinx-static/theme_overrides.css @@ -1,5 +1,4 @@ -/* -*- coding: utf-8; mode: css -*- - * +/* * Sphinx HTML theme customization: read the doc * Based on Linux Documentation/sphinx-static/theme_overrides.css */ diff --git a/scripts/analyse-locks-simpletrace.py b/scripts/analyse-locks-simpletrace.py index d650dd7140..bd04cd43c9 100755 --- a/scripts/analyse-locks-simpletrace.py +++ b/scripts/analyse-locks-simpletrace.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # # Analyse lock events and compute statistics # diff --git a/scripts/modinfo-collect.py b/scripts/modinfo-collect.py index 48bd92bd61..6ebaea989d 100644 --- a/scripts/modinfo-collect.py +++ b/scripts/modinfo-collect.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import os import sys diff --git a/scripts/modinfo-generate.py b/scripts/modinfo-generate.py index b1538fcced..aaf23544c4 100644 --- a/scripts/modinfo-generate.py +++ b/scripts/modinfo-generate.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import os import sys diff --git a/scripts/oss-fuzz/minimize_qtest_trace.py b/scripts/oss-fuzz/minimize_qtest_trace.py index d1f3990c16..414a6d91dd 100755 --- a/scripts/oss-fuzz/minimize_qtest_trace.py +++ b/scripts/oss-fuzz/minimize_qtest_trace.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ This takes a crashing qtest trace and tries to remove superfluous operations diff --git a/scripts/oss-fuzz/output_reproducer.py b/scripts/oss-fuzz/output_reproducer.py index e8ef76b341..0df96cf958 100755 --- a/scripts/oss-fuzz/output_reproducer.py +++ b/scripts/oss-fuzz/output_reproducer.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ Convert plain qtest traces to C or Bash reproducers diff --git a/scripts/oss-fuzz/reorder_fuzzer_qtest_trace.py b/scripts/oss-fuzz/reorder_fuzzer_qtest_trace.py index b154a25508..8af0d5d9c4 100755 --- a/scripts/oss-fuzz/reorder_fuzzer_qtest_trace.py +++ b/scripts/oss-fuzz/reorder_fuzzer_qtest_trace.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ Use this to convert qtest log info from a generic fuzzer input into a qtest diff --git a/scripts/probe-gdb-support.py b/scripts/probe-gdb-support.py index 6bcadce150..43c7030287 100644 --- a/scripts/probe-gdb-support.py +++ b/scripts/probe-gdb-support.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# coding: utf-8 # # Probe gdb for supported architectures. # diff --git a/scripts/qapi/error.py b/scripts/qapi/error.py index e35e4ddb26..f73bc553db 100644 --- a/scripts/qapi/error.py +++ b/scripts/qapi/error.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# # Copyright (c) 2017-2019 Red Hat Inc. # # Authors: diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py index cae0a08359..f40b247f8b 100644 --- a/scripts/qapi/expr.py +++ b/scripts/qapi/expr.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# # Copyright IBM, Corp. 2011 # Copyright (c) 2013-2021 Red Hat Inc. # diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py index d3c56d45c8..0c9b8db3b0 100644 --- a/scripts/qapi/gen.py +++ b/scripts/qapi/gen.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# # QAPI code generation # # Copyright (c) 2015-2019 Red Hat Inc. diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py index 2529edf81a..9fbf80a541 100644 --- a/scripts/qapi/parser.py +++ b/scripts/qapi/parser.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# # QAPI schema parser # # Copyright IBM, Corp. 2011 diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 3abddea352..8d88b40de2 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# # QAPI schema internal representation # # Copyright (c) 2015-2019 Red Hat Inc. diff --git a/scripts/qemu-plugin-symbols.py b/scripts/qemu-plugin-symbols.py index e285ebb8f9..69644979c1 100755 --- a/scripts/qemu-plugin-symbols.py +++ b/scripts/qemu-plugin-symbols.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # # Extract QEMU Plugin API symbols from a header file # diff --git a/scripts/qemugdb/tcg.py b/scripts/qemugdb/tcg.py index 16c03c06a9..22529c7277 100644 --- a/scripts/qemugdb/tcg.py +++ b/scripts/qemugdb/tcg.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# # GDB debugging support, TCG status # # Copyright 2016 Linaro Ltd diff --git a/scripts/qemugdb/timers.py b/scripts/qemugdb/timers.py index 46537b27cf..5714f92cc2 100644 --- a/scripts/qemugdb/timers.py +++ b/scripts/qemugdb/timers.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # GDB debugging support # # Copyright 2017 Linaro Ltd diff --git a/scripts/replay-dump.py b/scripts/replay-dump.py index 4ce7ff51cc..097636570d 100755 --- a/scripts/replay-dump.py +++ b/scripts/replay-dump.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # # Dump the contents of a recorded execution stream # diff --git a/scripts/tracetool.py b/scripts/tracetool.py index 5de9ce96d3..0fdc9cb947 100755 --- a/scripts/tracetool.py +++ b/scripts/tracetool.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ Command-line wrapper for the tracetool machinery. diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 4ef1dc1fca..9dd8ec27e1 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ Machinery for generating tracing-related intermediate files. """ diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py index 6c6344dedd..7040130919 100644 --- a/scripts/tracetool/backend/__init__.py +++ b/scripts/tracetool/backend/__init__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ Backend management. diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py index e17edc9b9d..4835454193 100644 --- a/scripts/tracetool/backend/dtrace.py +++ b/scripts/tracetool/backend/dtrace.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ DTrace/SystemTAP backend. """ diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py index 5fa30ccc08..e6317ca4bf 100644 --- a/scripts/tracetool/backend/ftrace.py +++ b/scripts/tracetool/backend/ftrace.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ Ftrace built-in backend. """ diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py index eb50ceea34..9842522b18 100644 --- a/scripts/tracetool/backend/log.py +++ b/scripts/tracetool/backend/log.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ Stderr built-in backend. """ diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py index 7c84c06b20..066e5e9f11 100644 --- a/scripts/tracetool/backend/simple.py +++ b/scripts/tracetool/backend/simple.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ Simple built-in backend. """ diff --git a/scripts/tracetool/backend/syslog.py b/scripts/tracetool/backend/syslog.py index 3f82e54aab..74af038089 100644 --- a/scripts/tracetool/backend/syslog.py +++ b/scripts/tracetool/backend/syslog.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ Syslog built-in backend. """ diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/ust.py index c857516f21..6cc651646d 100644 --- a/scripts/tracetool/backend/ust.py +++ b/scripts/tracetool/backend/ust.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ LTTng User Space Tracing backend. """ diff --git a/scripts/tracetool/format/__init__.py b/scripts/tracetool/format/__init__.py index 042fe7d103..94a37bfce9 100644 --- a/scripts/tracetool/format/__init__.py +++ b/scripts/tracetool/format/__init__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ Format management. diff --git a/scripts/tracetool/format/c.py b/scripts/tracetool/format/c.py index e473fb6c6e..3c4398c237 100644 --- a/scripts/tracetool/format/c.py +++ b/scripts/tracetool/format/c.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ trace/generated-tracers.c """ diff --git a/scripts/tracetool/format/d.py b/scripts/tracetool/format/d.py index a5e096e214..684598c183 100644 --- a/scripts/tracetool/format/d.py +++ b/scripts/tracetool/format/d.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ trace/generated-tracers.dtrace (DTrace only). """ diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py index bd9e0ca7f2..2119753be1 100644 --- a/scripts/tracetool/format/h.py +++ b/scripts/tracetool/format/h.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ trace/generated-tracers.h """ diff --git a/scripts/tracetool/format/log_stap.py b/scripts/tracetool/format/log_stap.py index 5b1bbe907f..02f23bfb8d 100644 --- a/scripts/tracetool/format/log_stap.py +++ b/scripts/tracetool/format/log_stap.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ Generate .stp file that printfs log messages (DTrace with SystemTAP only). """ diff --git a/scripts/tracetool/format/simpletrace_stap.py b/scripts/tracetool/format/simpletrace_stap.py index ac39a492d9..3c3584a931 100644 --- a/scripts/tracetool/format/simpletrace_stap.py +++ b/scripts/tracetool/format/simpletrace_stap.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ Generate .stp file that outputs simpletrace binary traces (DTrace with SystemTAP only). """ diff --git a/scripts/tracetool/format/stap.py b/scripts/tracetool/format/stap.py index 4d77fbc11a..04c7a35a25 100644 --- a/scripts/tracetool/format/stap.py +++ b/scripts/tracetool/format/stap.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ Generate .stp file (DTrace with SystemTAP only). """ diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/format/ust_events_c.py index 569754a304..ea5f0ae99f 100644 --- a/scripts/tracetool/format/ust_events_c.py +++ b/scripts/tracetool/format/ust_events_c.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ trace/generated-ust.c """ diff --git a/scripts/tracetool/format/ust_events_h.py b/scripts/tracetool/format/ust_events_h.py index 2a31fefeca..242c9814fd 100644 --- a/scripts/tracetool/format/ust_events_h.py +++ b/scripts/tracetool/format/ust_events_h.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ trace/generated-ust-provider.h """ From 6f94ad27f0014c04a2aa403988acc22740a21196 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 29 Sep 2025 17:49:26 +0200 Subject: [PATCH 04/16] tracetool: add SPDX headers Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-ID: <20250929154938.594389-5-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/__init__.py | 2 ++ scripts/tracetool/backend/__init__.py | 2 ++ scripts/tracetool/backend/dtrace.py | 2 ++ scripts/tracetool/backend/ftrace.py | 2 ++ scripts/tracetool/backend/log.py | 2 ++ scripts/tracetool/backend/simple.py | 2 ++ scripts/tracetool/backend/syslog.py | 2 ++ scripts/tracetool/backend/ust.py | 2 ++ scripts/tracetool/format/__init__.py | 2 ++ scripts/tracetool/format/c.py | 2 ++ scripts/tracetool/format/d.py | 2 ++ scripts/tracetool/format/h.py | 2 ++ scripts/tracetool/format/log_stap.py | 2 ++ scripts/tracetool/format/simpletrace_stap.py | 2 ++ scripts/tracetool/format/stap.py | 2 ++ scripts/tracetool/format/ust_events_c.py | 2 ++ scripts/tracetool/format/ust_events_h.py | 2 ++ 17 files changed, 34 insertions(+) diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 9dd8ec27e1..c4fa0f74e6 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ Machinery for generating tracing-related intermediate files. """ diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py index 7040130919..bf91e443e9 100644 --- a/scripts/tracetool/backend/__init__.py +++ b/scripts/tracetool/backend/__init__.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ Backend management. diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py index 4835454193..b4af403025 100644 --- a/scripts/tracetool/backend/dtrace.py +++ b/scripts/tracetool/backend/dtrace.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ DTrace/SystemTAP backend. """ diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py index e6317ca4bf..a14aafcee6 100644 --- a/scripts/tracetool/backend/ftrace.py +++ b/scripts/tracetool/backend/ftrace.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ Ftrace built-in backend. """ diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py index 9842522b18..faacec4610 100644 --- a/scripts/tracetool/backend/log.py +++ b/scripts/tracetool/backend/log.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ Stderr built-in backend. """ diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py index 066e5e9f11..97e40495ee 100644 --- a/scripts/tracetool/backend/simple.py +++ b/scripts/tracetool/backend/simple.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ Simple built-in backend. """ diff --git a/scripts/tracetool/backend/syslog.py b/scripts/tracetool/backend/syslog.py index 74af038089..78ee67136b 100644 --- a/scripts/tracetool/backend/syslog.py +++ b/scripts/tracetool/backend/syslog.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ Syslog built-in backend. """ diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/ust.py index 6cc651646d..3aa9bb1da2 100644 --- a/scripts/tracetool/backend/ust.py +++ b/scripts/tracetool/backend/ust.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ LTTng User Space Tracing backend. """ diff --git a/scripts/tracetool/format/__init__.py b/scripts/tracetool/format/__init__.py index 94a37bfce9..7b9d1b5782 100644 --- a/scripts/tracetool/format/__init__.py +++ b/scripts/tracetool/format/__init__.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ Format management. diff --git a/scripts/tracetool/format/c.py b/scripts/tracetool/format/c.py index 3c4398c237..50e03313cb 100644 --- a/scripts/tracetool/format/c.py +++ b/scripts/tracetool/format/c.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ trace/generated-tracers.c """ diff --git a/scripts/tracetool/format/d.py b/scripts/tracetool/format/d.py index 684598c183..e9e33dfe30 100644 --- a/scripts/tracetool/format/d.py +++ b/scripts/tracetool/format/d.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ trace/generated-tracers.dtrace (DTrace only). """ diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py index 2119753be1..be7f32e67b 100644 --- a/scripts/tracetool/format/h.py +++ b/scripts/tracetool/format/h.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ trace/generated-tracers.h """ diff --git a/scripts/tracetool/format/log_stap.py b/scripts/tracetool/format/log_stap.py index 02f23bfb8d..259303a189 100644 --- a/scripts/tracetool/format/log_stap.py +++ b/scripts/tracetool/format/log_stap.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ Generate .stp file that printfs log messages (DTrace with SystemTAP only). """ diff --git a/scripts/tracetool/format/simpletrace_stap.py b/scripts/tracetool/format/simpletrace_stap.py index 3c3584a931..c7bde97a85 100644 --- a/scripts/tracetool/format/simpletrace_stap.py +++ b/scripts/tracetool/format/simpletrace_stap.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ Generate .stp file that outputs simpletrace binary traces (DTrace with SystemTAP only). """ diff --git a/scripts/tracetool/format/stap.py b/scripts/tracetool/format/stap.py index 04c7a35a25..285c9203ba 100644 --- a/scripts/tracetool/format/stap.py +++ b/scripts/tracetool/format/stap.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ Generate .stp file (DTrace with SystemTAP only). """ diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/format/ust_events_c.py index ea5f0ae99f..074226bfd3 100644 --- a/scripts/tracetool/format/ust_events_c.py +++ b/scripts/tracetool/format/ust_events_c.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ trace/generated-ust.c """ diff --git a/scripts/tracetool/format/ust_events_h.py b/scripts/tracetool/format/ust_events_h.py index 242c9814fd..cee7970a40 100644 --- a/scripts/tracetool/format/ust_events_h.py +++ b/scripts/tracetool/format/ust_events_h.py @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + """ trace/generated-ust-provider.h """ From 02d4a4a674d45d41c9afd1fd161c14eca81f7a86 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 29 Sep 2025 17:49:27 +0200 Subject: [PATCH 05/16] trace/ftrace: move snprintf+write from tracepoints to ftrace.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This simplifies the Python code and reduces the size of the tracepoints. Reviewed-by: Manos Pitsidianakis Reviewed-by: Zhao Liu Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Reviewed-by: Daniel P. Berrangé Message-ID: <20250929154938.594389-6-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/backend/ftrace.py | 12 ++---------- tests/tracetool/ftrace.h | 28 ++++++---------------------- trace/ftrace.c | 15 +++++++++++++++ trace/ftrace.h | 1 + 4 files changed, 24 insertions(+), 32 deletions(-) diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py index a14aafcee6..8c0ce3f23a 100644 --- a/scripts/tracetool/backend/ftrace.py +++ b/scripts/tracetool/backend/ftrace.py @@ -28,18 +28,10 @@ def generate_h(event, group): if len(event.args) > 0: argnames = ", " + argnames - out(' {', - ' char ftrace_buf[MAX_TRACE_STRLEN];', - ' int unused __attribute__ ((unused));', - ' int trlen;', - ' if (trace_event_get_state(%(event_id)s)) {', + out(' if (trace_event_get_state(%(event_id)s)) {', '#line %(event_lineno)d "%(event_filename)s"', - ' trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,', - ' "%(name)s " %(fmt)s "\\n" %(argnames)s);', + ' ftrace_write("%(name)s " %(fmt)s "\\n" %(argnames)s);', '#line %(out_next_lineno)d "%(out_filename)s"', - ' trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);', - ' unused = write(trace_marker_fd, ftrace_buf, trlen);', - ' }', ' }', name=event.name, args=event.args, diff --git a/tests/tracetool/ftrace.h b/tests/tracetool/ftrace.h index fe22ea0f09..1dfe423941 100644 --- a/tests/tracetool/ftrace.h +++ b/tests/tracetool/ftrace.h @@ -21,18 +21,10 @@ extern uint16_t _TRACE_TEST_WIBBLE_DSTATE; static inline void trace_test_blah(void *context, const char *filename) { - { - char ftrace_buf[MAX_TRACE_STRLEN]; - int unused __attribute__ ((unused)); - int trlen; - if (trace_event_get_state(TRACE_TEST_BLAH)) { + if (trace_event_get_state(TRACE_TEST_BLAH)) { #line 4 "trace-events" - trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN, - "test_blah " "Blah context=%p filename=%s" "\n" , context, filename); -#line 33 "ftrace.h" - trlen = MIN(trlen, MAX_TRACE_STRLEN - 1); - unused = write(trace_marker_fd, ftrace_buf, trlen); - } + ftrace_write("test_blah " "Blah context=%p filename=%s" "\n" , context, filename); +#line 28 "ftrace.h" } } @@ -42,18 +34,10 @@ static inline void trace_test_blah(void *context, const char *filename) static inline void trace_test_wibble(void *context, int value) { - { - char ftrace_buf[MAX_TRACE_STRLEN]; - int unused __attribute__ ((unused)); - int trlen; - if (trace_event_get_state(TRACE_TEST_WIBBLE)) { + if (trace_event_get_state(TRACE_TEST_WIBBLE)) { #line 5 "trace-events" - trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN, - "test_wibble " "Wibble context=%p value=%d" "\n" , context, value); -#line 54 "ftrace.h" - trlen = MIN(trlen, MAX_TRACE_STRLEN - 1); - unused = write(trace_marker_fd, ftrace_buf, trlen); - } + ftrace_write("test_wibble " "Wibble context=%p value=%d" "\n" , context, value); +#line 41 "ftrace.h" } } #endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */ diff --git a/trace/ftrace.c b/trace/ftrace.c index 9749543d9b..6875faedb9 100644 --- a/trace/ftrace.c +++ b/trace/ftrace.c @@ -38,6 +38,21 @@ static int find_mount(char *mount_point, const char *fstype) return ret; } +void ftrace_write(const char *fmt, ...) +{ + char ftrace_buf[MAX_TRACE_STRLEN]; + int unused __attribute__ ((unused)); + int trlen; + va_list ap; + + va_start(ap, fmt); + trlen = vsnprintf(ftrace_buf, MAX_TRACE_STRLEN, fmt, ap); + va_end(ap); + + trlen = MIN(trlen, MAX_TRACE_STRLEN - 1); + unused = write(trace_marker_fd, ftrace_buf, trlen); +} + bool ftrace_init(void) { char mount_point[PATH_MAX]; diff --git a/trace/ftrace.h b/trace/ftrace.h index cb5e35d217..16c122816d 100644 --- a/trace/ftrace.h +++ b/trace/ftrace.h @@ -8,5 +8,6 @@ extern int trace_marker_fd; bool ftrace_init(void); +G_GNUC_PRINTF(1, 2) void ftrace_write(const char *fmt, ...); #endif /* TRACE_FTRACE_H */ From 809caa0d40a853144c02456737ed1e47859b0308 Mon Sep 17 00:00:00 2001 From: Tanish Desai Date: Mon, 29 Sep 2025 17:49:28 +0200 Subject: [PATCH 06/16] tracetool: add CHECK_TRACE_EVENT_GET_STATE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new attribute CHECK_TRACE_EVENT_GET_STATE to the backends. When present and True, the code generated by the generate function is wrapped in a conditional that checks whether the event is enabled; this removes the need for repeating the same conditional in multiple backends. Signed-off-by: Tanish Desai Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Reviewed-by: Daniel P. Berrangé Message-ID: <20250929154938.594389-7-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/backend/__init__.py | 39 ++++++++++++++++++--------- scripts/tracetool/format/h.py | 11 +++++--- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py index bf91e443e9..9109a783c7 100644 --- a/scripts/tracetool/backend/__init__.py +++ b/scripts/tracetool/backend/__init__.py @@ -19,11 +19,15 @@ All backends must generate their contents through the 'tracetool.out' routine. Backend attributes ------------------ -========= ==================================================================== -Attribute Description -========= ==================================================================== -PUBLIC If exists and is set to 'True', the backend is considered "public". -========= ==================================================================== +=========================== ==================================================== +Attribute Description +=========================== ==================================================== +PUBLIC If exists and is set to 'True', the backend is + considered "public". +CHECK_TRACE_EVENT_GET_STATE If exists and is set to 'True', the backend-specific + code inside the tracepoint is emitted within an + ``if trace_event_get_state()`` conditional. +=========================== ==================================================== Backend functions @@ -101,22 +105,33 @@ class Wrapper: def __init__(self, backends, format): self._backends = [backend.replace("-", "_") for backend in backends] self._format = format.replace("-", "_") + self.check_trace_event_get_state = False for backend in self._backends: assert exists(backend) assert tracetool.format.exists(self._format) + for backend in self.backend_modules(): + check_trace_event_get_state = getattr(backend, "CHECK_TRACE_EVENT_GET_STATE", False) + self.check_trace_event_get_state = self.check_trace_event_get_state or check_trace_event_get_state - def _run_function(self, name, *args, **kwargs): + def backend_modules(self): for backend in self._backends: - func = tracetool.try_import("tracetool.backend." + backend, - name % self._format, None)[1] - if func is not None: - func(*args, **kwargs) + module = tracetool.try_import("tracetool.backend." + backend)[1] + if module is not None: + yield module + + def _run_function(self, name, *args, check_trace_event_get_state=None, **kwargs): + for backend in self.backend_modules(): + func = getattr(backend, name % self._format, None) + if func is not None and \ + (check_trace_event_get_state is None or + check_trace_event_get_state == getattr(backend, 'CHECK_TRACE_EVENT_GET_STATE', False)): + func(*args, **kwargs) def generate_begin(self, events, group): self._run_function("generate_%s_begin", events, group) - def generate(self, event, group): - self._run_function("generate_%s", event, group) + def generate(self, event, group, check_trace_event_get_state=None): + self._run_function("generate_%s", event, group, check_trace_event_get_state=check_trace_event_get_state) def generate_backend_dstate(self, event, group): self._run_function("generate_%s_backend_dstate", event, group) diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py index be7f32e67b..dd58713a15 100644 --- a/scripts/tracetool/format/h.py +++ b/scripts/tracetool/format/h.py @@ -55,7 +55,6 @@ def generate(events, backend, group): out(' false)') - # tracer without checks out('', 'static inline void %(api)s(%(args)s)', '{', @@ -63,11 +62,17 @@ def generate(events, backend, group): args=e.args) if "disable" not in e.properties: - backend.generate(e, group) + backend.generate(e, group, check_trace_event_get_state=False) + if backend.check_trace_event_get_state: + event_id = 'TRACE_' + e.name.upper() + cond = "trace_event_get_state(%s)" % event_id + out(' if (%(cond)s) {', + cond=cond) + backend.generate(e, group, check_trace_event_get_state=True) + out(' }') out('}') - backend.generate_end(events, group) out('#endif /* TRACE_%s_GENERATED_TRACERS_H */' % group.upper()) From 494492c5c5a145e04f3ebc9eb40fd34ffbcc2061 Mon Sep 17 00:00:00 2001 From: Tanish Desai Date: Mon, 29 Sep 2025 17:49:29 +0200 Subject: [PATCH 07/16] tracetool/backend: remove redundant trace event checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use CHECK_TRACE_EVENT_GET_STATE in log, syslog, dtrace and simple backend, so that the "if (trace_event_get_state)" is created from common code and unified when multiple backends are active. When a single backend is active there is no code change (except for the log backend, as shown in tests/tracetool/log.h), but the code in the backends is simpler. Signed-off-by: Tanish Desai Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Reviewed-by: Daniel P. Berrangé Message-ID: <20250929154938.594389-8-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/backend/ftrace.py | 6 ++---- scripts/tracetool/backend/log.py | 10 ++++------ scripts/tracetool/backend/simple.py | 8 ++------ scripts/tracetool/backend/syslog.py | 8 ++------ tests/tracetool/log.h | 16 ++++++++++------ 5 files changed, 20 insertions(+), 28 deletions(-) diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py index 8c0ce3f23a..7ddd5d11a6 100644 --- a/scripts/tracetool/backend/ftrace.py +++ b/scripts/tracetool/backend/ftrace.py @@ -16,6 +16,7 @@ from tracetool import out PUBLIC = True +CHECK_TRACE_EVENT_GET_STATE = True def generate_h_begin(events, group): @@ -28,14 +29,11 @@ def generate_h(event, group): if len(event.args) > 0: argnames = ", " + argnames - out(' if (trace_event_get_state(%(event_id)s)) {', - '#line %(event_lineno)d "%(event_filename)s"', + out('#line %(event_lineno)d "%(event_filename)s"', ' ftrace_write("%(name)s " %(fmt)s "\\n" %(argnames)s);', '#line %(out_next_lineno)d "%(out_filename)s"', - ' }', name=event.name, args=event.args, - event_id="TRACE_" + event.name.upper(), event_lineno=event.lineno, event_filename=event.filename, fmt=event.fmt.rstrip("\n"), diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py index faacec4610..d01d234289 100644 --- a/scripts/tracetool/backend/log.py +++ b/scripts/tracetool/backend/log.py @@ -16,6 +16,7 @@ from tracetool import out PUBLIC = True +CHECK_TRACE_EVENT_GET_STATE = True def generate_h_begin(events, group): @@ -28,14 +29,11 @@ def generate_h(event, group): if len(event.args) > 0: argnames = ", " + argnames - cond = "trace_event_get_state(%s)" % ("TRACE_" + event.name.upper()) - - out(' if (%(cond)s && qemu_loglevel_mask(LOG_TRACE)) {', + out(' if (qemu_loglevel_mask(LOG_TRACE)) {', '#line %(event_lineno)d "%(event_filename)s"', - ' qemu_log("%(name)s " %(fmt)s "\\n"%(argnames)s);', + ' qemu_log("%(name)s " %(fmt)s "\\n"%(argnames)s);', '#line %(out_next_lineno)d "%(out_filename)s"', - ' }', - cond=cond, + ' }', event_lineno=event.lineno, event_filename=event.filename, name=event.name, diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py index 97e40495ee..b5a6b7205a 100644 --- a/scripts/tracetool/backend/simple.py +++ b/scripts/tracetool/backend/simple.py @@ -16,6 +16,7 @@ from tracetool import out PUBLIC = True +CHECK_TRACE_EVENT_GET_STATE = True def is_string(arg): @@ -36,13 +37,8 @@ def generate_h_begin(events, group): def generate_h(event, group): - event_id = 'TRACE_' + event.name.upper() - cond = "trace_event_get_state(%s)" % event_id - out(' if (%(cond)s) {', - ' _simple_%(api)s(%(args)s);', - ' }', + out(' _simple_%(api)s(%(args)s);', api=event.api(), - cond=cond, args=", ".join(event.args.names())) diff --git a/scripts/tracetool/backend/syslog.py b/scripts/tracetool/backend/syslog.py index 78ee67136b..177414d56a 100644 --- a/scripts/tracetool/backend/syslog.py +++ b/scripts/tracetool/backend/syslog.py @@ -16,6 +16,7 @@ from tracetool import out PUBLIC = True +CHECK_TRACE_EVENT_GET_STATE = True def generate_h_begin(events, group): @@ -28,14 +29,9 @@ def generate_h(event, group): if len(event.args) > 0: argnames = ", " + argnames - cond = "trace_event_get_state(%s)" % ("TRACE_" + event.name.upper()) - - out(' if (%(cond)s) {', - '#line %(event_lineno)d "%(event_filename)s"', + out('#line %(event_lineno)d "%(event_filename)s"', ' syslog(LOG_INFO, "%(name)s " %(fmt)s %(argnames)s);', '#line %(out_next_lineno)d "%(out_filename)s"', - ' }', - cond=cond, event_lineno=event.lineno, event_filename=event.filename, name=event.name, diff --git a/tests/tracetool/log.h b/tests/tracetool/log.h index edcc7f9d47..c7795871f8 100644 --- a/tests/tracetool/log.h +++ b/tests/tracetool/log.h @@ -21,10 +21,12 @@ extern uint16_t _TRACE_TEST_WIBBLE_DSTATE; static inline void trace_test_blah(void *context, const char *filename) { - if (trace_event_get_state(TRACE_TEST_BLAH) && qemu_loglevel_mask(LOG_TRACE)) { + if (trace_event_get_state(TRACE_TEST_BLAH)) { + if (qemu_loglevel_mask(LOG_TRACE)) { #line 4 "trace-events" - qemu_log("test_blah " "Blah context=%p filename=%s" "\n", context, filename); -#line 28 "log.h" + qemu_log("test_blah " "Blah context=%p filename=%s" "\n", context, filename); +#line 29 "log.h" + } } } @@ -34,10 +36,12 @@ static inline void trace_test_blah(void *context, const char *filename) static inline void trace_test_wibble(void *context, int value) { - if (trace_event_get_state(TRACE_TEST_WIBBLE) && qemu_loglevel_mask(LOG_TRACE)) { + if (trace_event_get_state(TRACE_TEST_WIBBLE)) { + if (qemu_loglevel_mask(LOG_TRACE)) { #line 5 "trace-events" - qemu_log("test_wibble " "Wibble context=%p value=%d" "\n", context, value); -#line 41 "log.h" + qemu_log("test_wibble " "Wibble context=%p value=%d" "\n", context, value); +#line 44 "log.h" + } } } #endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */ From e2e182bef73f24d885f7f2ca589d8ec004c24877 Mon Sep 17 00:00:00 2001 From: Tanish Desai Date: Mon, 29 Sep 2025 17:49:30 +0200 Subject: [PATCH 08/16] tracetool: Add Rust format support Generating .rs files makes it possible to support tracing in rust. This support comprises a new format, and common code that converts the C expressions in trace-events to Rust. In particular, types need to be converted, and PRI macros expanded. As of this commit no backend generates Rust code, but it is already possible to use tracetool to generate Rust sources; they are not functional but they compile and contain tracepoint functions. [Move Rust argument conversion from Event to Arguments; string support. - Paolo] Signed-off-by: Tanish Desai Signed-off-by: Paolo Bonzini Message-ID: <20250929154938.594389-9-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/__init__.py | 155 +++++++++++++++++++++++++++++++++ scripts/tracetool/format/rs.py | 64 ++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 scripts/tracetool/format/rs.py diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index c4fa0f74e6..74062d21a7 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -30,6 +30,49 @@ def error(*lines): error_write(*lines) sys.exit(1) +FMT_TOKEN = re.compile(r'''(?: + " ( (?: [^"\\] | \\[\\"abfnrt] | # a string literal + \\x[0-9a-fA-F][0-9a-fA-F]) *? ) " + | ( PRI [duixX] (?:8|16|32|64|PTR|MAX) ) # a PRIxxx macro + | \s+ # spaces (ignored) + )''', re.X) + +PRI_SIZE_MAP = { + '8': 'hh', + '16': 'h', + '32': '', + '64': 'll', + 'PTR': 't', + 'MAX': 'j', +} + +def expand_format_string(c_fmt, prefix=""): + def pri_macro_to_fmt(pri_macro): + assert pri_macro.startswith("PRI") + fmt_type = pri_macro[3] # 'd', 'i', 'u', or 'x' + fmt_size = pri_macro[4:] # '8', '16', '32', '64', 'PTR', 'MAX' + + size = PRI_SIZE_MAP.get(fmt_size, None) + if size is None: + raise Exception(f"unknown macro {pri_macro}") + return size + fmt_type + + result = prefix + pos = 0 + while pos < len(c_fmt): + m = FMT_TOKEN.match(c_fmt, pos) + if not m: + print("No match at position", pos, ":", repr(c_fmt[pos:]), file=sys.stderr) + raise Exception("syntax error in trace file") + if m[1]: + substr = m[1] + elif m[2]: + substr = pri_macro_to_fmt(m[2]) + else: + substr = "" + result += substr + pos = m.end() + return result out_lineno = 1 out_filename = '' @@ -89,6 +132,49 @@ ALLOWED_TYPES = [ "ptrdiff_t", ] +C_TYPE_KEYWORDS = {"char", "int", "void", "short", "long", "signed", "unsigned"} + +C_TO_RUST_TYPE_MAP = { + "int": "std::ffi::c_int", + "long": "std::ffi::c_long", + "long long": "std::ffi::c_longlong", + "short": "std::ffi::c_short", + "char": "std::ffi::c_char", + "bool": "bool", + "unsigned": "std::ffi::c_uint", + # multiple keywords, keep them sorted + "long unsigned": "std::ffi::c_long", + "long long unsigned": "std::ffi::c_ulonglong", + "short unsigned": "std::ffi::c_ushort", + "char unsigned": "u8", + "int8_t": "i8", + "uint8_t": "u8", + "int16_t": "i16", + "uint16_t": "u16", + "int32_t": "i32", + "uint32_t": "u32", + "int64_t": "i64", + "uint64_t": "u64", + "void": "()", + "size_t": "usize", + "ssize_t": "isize", + "uintptr_t": "usize", + "ptrdiff_t": "isize", +} + +# Rust requires manual casting of <32-bit types when passing them to +# variable-argument functions. +RUST_VARARGS_SMALL_TYPES = { + "std::ffi::c_short", + "std::ffi::c_ushort", + "std::ffi::c_char", + "i8", + "u8", + "i16", + "u16", + "bool", +} + def validate_type(name): bits = name.split(" ") for bit in bits: @@ -104,6 +190,38 @@ def validate_type(name): "other complex pointer types should be " "declared as 'void *'" % name) +def c_type_to_rust(name): + ptr = False + const = False + name = name.rstrip() + if name[-1] == '*': + name = name[:-1].rstrip() + ptr = True + if name[-1] == '*': + # pointers to pointers are the same as void* + name = "void" + + bits = name.split() + if "const" in bits: + const = True + bits.remove("const") + if bits[0] in C_TYPE_KEYWORDS: + if "signed" in bits: + bits.remove("signed") + if len(bits) > 1 and "int" in bits: + bits.remove("int") + bits.sort() + name = ' '.join(bits) + else: + if len(bits) > 1: + raise ValueError("Invalid type '%s'." % name) + name = bits[0] + + ty = C_TO_RUST_TYPE_MAP[name.strip()] + if ptr: + ty = f'*{"const" if const else "mut"} {ty}' + return ty + class Arguments: """Event arguments description.""" @@ -192,6 +310,43 @@ class Arguments: """List of argument names casted to their type.""" return ["(%s)%s" % (type_, name) for type_, name in self._args] + def rust_decl_extern(self): + """Return a Rust argument list for an extern "C" function""" + return ", ".join((f"_{name}: {c_type_to_rust(type_)}" + for type_, name in self._args)) + + def rust_decl(self): + """Return a Rust argument list for a tracepoint function""" + def decl_type(type_): + if type_ == "const char *": + return "&std::ffi::CStr" + return c_type_to_rust(type_) + + return ", ".join((f"_{name}: {decl_type(type_)}" + for type_, name in self._args)) + + def rust_call_extern(self): + """Return a Rust argument list for a call to an extern "C" function""" + def rust_cast(name, type_): + if type_ == "const char *": + return f"_{name}.as_ptr()" + return f"_{name}" + + return ", ".join((rust_cast(name, type_) for type_, name in self._args)) + + def rust_call_varargs(self): + """Return a Rust argument list for a call to a C varargs function""" + def rust_cast(name, type_): + if type_ == "const char *": + return f"_{name}.as_ptr()" + + type_ = c_type_to_rust(type_) + if type_ in RUST_VARARGS_SMALL_TYPES: + return f"_{name} as std::ffi::c_int" + return f"_{name} /* as {type_} */" + + return ", ".join((rust_cast(name, type_) for type_, name in self._args)) + class Event(object): """Event description. diff --git a/scripts/tracetool/format/rs.py b/scripts/tracetool/format/rs.py new file mode 100644 index 0000000000..32ac4e5977 --- /dev/null +++ b/scripts/tracetool/format/rs.py @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +""" +trace-DIR.rs +""" + +__author__ = "Tanish Desai " +__copyright__ = "Copyright 2025, Tanish Desai " +__license__ = "GPL version 2 or (at your option) any later version" + +__maintainer__ = "Stefan Hajnoczi" +__email__ = "stefanha@redhat.com" + + +from tracetool import out + + +def generate(events, backend, group): + out('// SPDX-License-Identifier: GPL-2.0-or-later', + '// This file is @generated by tracetool, do not edit.', + '', + '#[allow(unused_imports)]', + 'use std::ffi::c_char;', + '#[allow(unused_imports)]', + 'use util::bindings;', + '', + '#[inline(always)]', + 'fn trace_event_state_is_enabled(dstate: u16) -> bool {', + ' (unsafe { trace_events_enabled_count }) != 0 && dstate != 0', + '}', + '', + 'extern "C" {', + ' static mut trace_events_enabled_count: u32;', + '}',) + + out('extern "C" {') + + for e in events: + out(' static mut %s: u16;' % e.api(e.QEMU_DSTATE)) + out('}') + + backend.generate_begin(events, group) + + for e in events: + out('', + '#[inline(always)]', + '#[allow(dead_code)]', + 'pub fn %(api)s(%(args)s)', + '{', + api=e.api(e.QEMU_TRACE), + args=e.args.rust_decl()) + + if "disable" not in e.properties: + backend.generate(e, group, check_trace_event_get_state=False) + if backend.check_trace_event_get_state: + event_id = 'TRACE_' + e.name.upper() + out(' if trace_event_state_is_enabled(unsafe { _%(event_id)s_DSTATE}) {', + event_id = event_id, + api=e.api()) + backend.generate(e, group, check_trace_event_get_state=True) + out(' }') + out('}') + + backend.generate_end(events, group) From 54140102d2e57bd2e34823e4537d2191cdcd5f08 Mon Sep 17 00:00:00 2001 From: Tanish Desai Date: Mon, 29 Sep 2025 17:49:31 +0200 Subject: [PATCH 09/16] rust: add trace crate The trace crate is a minimal container for dependencies of tracepoints (so that they do not have to be imported in all the crates that use tracepoints); it also contains a macro called "include_trace!" that is able to find the right include file from the trace/ directory. [Write commit message, add #[allow()]. - Paolo] Signed-off-by: Tanish Desai Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-ID: <20250929154938.594389-10-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- rust/Cargo.lock | 4 ++++ rust/Cargo.toml | 1 + rust/meson.build | 2 +- rust/trace/Cargo.toml | 16 ++++++++++++++++ rust/trace/meson.build | 19 +++++++++++++++++++ rust/trace/src/lib.rs | 35 +++++++++++++++++++++++++++++++++++ trace/meson.build | 8 +++++++- 7 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 rust/trace/Cargo.toml create mode 100644 rust/trace/meson.build create mode 100644 rust/trace/src/lib.rs diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 8315f98c46..3428dbaf0b 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -258,6 +258,10 @@ dependencies = [ "util", ] +[[package]] +name = "trace" +version = "0.1.0" + [[package]] name = "unicode-ident" version = "1.0.12" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index d8183c614d..f372d7dbf7 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -11,6 +11,7 @@ members = [ "hw/core", "hw/char/pl011", "hw/timer/hpet", + "trace", "util", "tests", ] diff --git a/rust/meson.build b/rust/meson.build index b3ac3a7197..695d5a62de 100644 --- a/rust/meson.build +++ b/rust/meson.build @@ -34,7 +34,7 @@ subdir('system') subdir('chardev') subdir('hw/core') subdir('tests') - +subdir('trace') subdir('hw') cargo = find_program('cargo', required: false) diff --git a/rust/trace/Cargo.toml b/rust/trace/Cargo.toml new file mode 100644 index 0000000000..13ac0b33d6 --- /dev/null +++ b/rust/trace/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "trace" +version = "0.1.0" +authors = ["Tanish Desai "] +description = "QEMU tracing infrastructure support" +resolver = "2" +publish = false + +edition.workspace = true +homepage.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true + +[lints] +workspace = true diff --git a/rust/trace/meson.build b/rust/trace/meson.build new file mode 100644 index 0000000000..adca57e550 --- /dev/null +++ b/rust/trace/meson.build @@ -0,0 +1,19 @@ +rust = import('rust') + +lib_rs = configure_file( + input: 'src/lib.rs', + output: 'lib.rs', + configuration: { + 'MESON_BUILD_ROOT': meson.project_build_root(), + }) + +_trace_rs = static_library( + 'trace', # Library name, + lib_rs, + trace_rs_targets, # List of generated `.rs` custom targets + override_options: ['rust_std=2021', 'build.rust_std=2021'], + dependencies: [libc_rs], + rust_abi: 'rust', +) + +trace_rs = declare_dependency(link_with: _trace_rs) diff --git a/rust/trace/src/lib.rs b/rust/trace/src/lib.rs new file mode 100644 index 0000000000..0955461573 --- /dev/null +++ b/rust/trace/src/lib.rs @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +//! This crate provides macros that aid in using QEMU's tracepoint +//! functionality. + +#[macro_export] +/// Define the trace-points from the named directory (which should have slashes +/// replaced by underscore characters) as functions in a module called `trace`. +/// +/// ```ignore +/// ::trace::include_trace!("hw_char"); +/// // ... +/// trace::trace_pl011_read_fifo_rx_full(); +/// ``` +macro_rules! include_trace { + ($name:literal) => { + #[allow( + clippy::ptr_as_ptr, + clippy::cast_lossless, + clippy::used_underscore_binding + )] + mod trace { + #[cfg(not(MESON))] + include!(concat!( + env!("MESON_BUILD_ROOT"), + "/trace/trace-", + $name, + ".rs" + )); + + #[cfg(MESON)] + include!(concat!("@MESON_BUILD_ROOT@/trace/trace-", $name, ".rs")); + } + }; +} diff --git a/trace/meson.build b/trace/meson.build index 9c42a57a05..d89a0db82a 100644 --- a/trace/meson.build +++ b/trace/meson.build @@ -1,5 +1,5 @@ system_ss.add(files('control-target.c', 'trace-hmp-cmds.c')) - +trace_rs_targets = [] trace_events_files = [] foreach item : [ '.' ] + trace_events_subdirs + qapi_trace_events if item in qapi_trace_events @@ -24,6 +24,11 @@ foreach item : [ '.' ] + trace_events_subdirs + qapi_trace_events input: trace_events_file, command: [ tracetool, group, '--format=c', '@INPUT@', '@OUTPUT@' ], depend_files: tracetool_depends) + trace_rs = custom_target(fmt.format('trace', 'rs'), + output: fmt.format('trace', 'rs'), + input: trace_events_file, + command: [ tracetool, group, '--format=rs', '@INPUT@', '@OUTPUT@' ], + depend_files: tracetool_depends) if 'ust' in get_option('trace_backends') trace_ust_h = custom_target(fmt.format('trace-ust', 'h'), output: fmt.format('trace-ust', 'h'), @@ -34,6 +39,7 @@ foreach item : [ '.' ] + trace_events_subdirs + qapi_trace_events genh += trace_ust_h endif trace_ss.add(trace_h, trace_c) + trace_rs_targets += trace_rs if 'dtrace' in get_option('trace_backends') trace_dtrace = custom_target(fmt.format('trace-dtrace', 'dtrace'), output: fmt.format('trace-dtrace', 'dtrace'), From fe791b4004cbdc64bee6cb69ba4a98513879945d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 29 Sep 2025 17:49:32 +0200 Subject: [PATCH 10/16] rust: qdev: add minimal clock bindings Add the minimal support that is needed by pl011's event and tracepoint. Reviewed-by: Zhao Liu Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-ID: <20250929154938.594389-11-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- rust/hw/core/src/qdev.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/rust/hw/core/src/qdev.rs b/rust/hw/core/src/qdev.rs index a4493dbf01..c3097a284d 100644 --- a/rust/hw/core/src/qdev.rs +++ b/rust/hw/core/src/qdev.rs @@ -411,6 +411,39 @@ where impl DeviceMethods for R where R::Target: IsA {} +impl Clock { + pub const PERIOD_1SEC: u64 = bindings::CLOCK_PERIOD_1SEC; + + pub const fn period_from_ns(ns: u64) -> u64 { + ns * Self::PERIOD_1SEC / 1_000_000_000 + } + + pub const fn period_from_hz(hz: u64) -> u64 { + if hz == 0 { + 0 + } else { + Self::PERIOD_1SEC / hz + } + } + + pub const fn period_to_hz(period: u64) -> u64 { + if period == 0 { + 0 + } else { + Self::PERIOD_1SEC / period + } + } + + pub const fn period(&self) -> u64 { + // SAFETY: Clock is returned by init_clock_in with zero value for period + unsafe { &*self.0.as_ptr() }.period + } + + pub const fn hz(&self) -> u64 { + Self::period_to_hz(self.period()) + } +} + unsafe impl ObjectType for Clock { type Class = ObjectClass; const TYPE_NAME: &'static CStr = From 357f92697971b5a52bb38248405c40afcc355a1d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 29 Sep 2025 17:49:33 +0200 Subject: [PATCH 11/16] rust: pl011: add tracepoints Finally bring parity between C and Rust versions of the PL011 device model. Changing some types of the arguments makes for nicer Rust code; C does not care. :) Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-ID: <20250929154938.594389-12-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- hw/char/trace-events | 14 ++++---- rust/Cargo.lock | 1 + rust/hw/char/pl011/Cargo.toml | 1 + rust/hw/char/pl011/meson.build | 1 + rust/hw/char/pl011/src/device.rs | 57 ++++++++++++++++++++++---------- 5 files changed, 50 insertions(+), 24 deletions(-) diff --git a/hw/char/trace-events b/hw/char/trace-events index 05a33036c1..9e74be2c14 100644 --- a/hw/char/trace-events +++ b/hw/char/trace-events @@ -58,15 +58,15 @@ imx_serial_write(const char *chrname, uint64_t addr, uint64_t value) "%s:[0x%03" imx_serial_put_data(const char *chrname, uint32_t value) "%s: 0x%" PRIx32 # pl011.c -pl011_irq_state(int level) "irq state %d" -pl011_read(uint32_t addr, uint32_t value, const char *regname) "addr 0x%03x value 0x%08x reg %s" -pl011_read_fifo(unsigned rx_fifo_used, size_t rx_fifo_depth) "RX FIFO read, used %u/%zu" -pl011_write(uint32_t addr, uint32_t value, const char *regname) "addr 0x%03x value 0x%08x reg %s" -pl011_can_receive(uint32_t lcr, unsigned rx_fifo_used, size_t rx_fifo_depth, unsigned rx_fifo_available) "LCR 0x%02x, RX FIFO used %u/%zu, can_receive %u chars" -pl011_fifo_rx_put(uint32_t c, unsigned read_count, size_t rx_fifo_depth) "RX FIFO push char [0x%02x] %d/%zu depth used" +pl011_irq_state(bool level) "irq state %d" +pl011_read(uint64_t addr, uint32_t value, const char *regname) "addr 0x%03" PRIx64 " value 0x%08x reg %s" +pl011_read_fifo(unsigned rx_fifo_used, unsigned rx_fifo_depth) "RX FIFO read, used %u/%u" +pl011_write(uint64_t addr, uint32_t value, const char *regname) "addr 0x%03" PRIx64 " value 0x%08x reg %s" +pl011_can_receive(uint32_t lcr, unsigned rx_fifo_used, unsigned rx_fifo_depth, unsigned rx_fifo_available) "LCR 0x%02x, RX FIFO used %u/%u, can_receive %u chars" +pl011_fifo_rx_put(uint32_t c, unsigned read_count, unsigned rx_fifo_depth) "RX FIFO push char [0x%02x] %d/%u depth used" pl011_fifo_rx_full(void) "RX FIFO now full, RXFF set" pl011_baudrate_change(unsigned int baudrate, uint64_t clock, uint32_t ibrd, uint32_t fbrd) "new baudrate %u (clk: %" PRIu64 "hz, ibrd: %" PRIu32 ", fbrd: %" PRIu32 ")" -pl011_receive(int size) "recv %d chars" +pl011_receive(size_t size) "recv %zd chars" # cmsdk-apb-uart.c cmsdk_apb_uart_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB UART read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 3428dbaf0b..f84a3dd076 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -159,6 +159,7 @@ dependencies = [ "migration", "qom", "system", + "trace", "util", ] diff --git a/rust/hw/char/pl011/Cargo.toml b/rust/hw/char/pl011/Cargo.toml index b2418abc4b..dc41d0e499 100644 --- a/rust/hw/char/pl011/Cargo.toml +++ b/rust/hw/char/pl011/Cargo.toml @@ -24,6 +24,7 @@ qom = { path = "../../../qom" } chardev = { path = "../../../chardev" } system = { path = "../../../system" } hwcore = { path = "../../../hw/core" } +trace = { path = "../../../trace" } [lints] workspace = true diff --git a/rust/hw/char/pl011/meson.build b/rust/hw/char/pl011/meson.build index a33f32906e..07b3da17e8 100644 --- a/rust/hw/char/pl011/meson.build +++ b/rust/hw/char/pl011/meson.build @@ -40,6 +40,7 @@ _libpl011_rs = static_library( chardev_rs, system_rs, hwcore_rs, + trace_rs ], ) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 1b4587d5f6..8889d6e54f 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -21,6 +21,8 @@ use util::{log::Log, log_mask_ln}; use crate::registers::{self, Interrupt, RegisterOffset}; +::trace::include_trace!("hw_char"); + // TODO: You must disable the UART before any of the control registers are // reprogrammed. When the UART is disabled in the middle of transmission or // reception, it completes the current character before stopping @@ -208,13 +210,7 @@ impl PL011Registers { (update, result) } - pub(self) fn write( - &mut self, - offset: RegisterOffset, - value: u32, - char_backend: &CharBackend, - ) -> bool { - // eprintln!("write offset {offset} value {value}"); + pub(self) fn write(&mut self, offset: RegisterOffset, value: u32, device: &PL011State) -> bool { use RegisterOffset::*; match offset { DR => return self.write_data_register(value), @@ -229,9 +225,11 @@ impl PL011Registers { } IBRD => { self.ibrd = value; + device.trace_baudrate_change(self.ibrd, self.fbrd); } FBRD => { self.fbrd = value; + device.trace_baudrate_change(self.ibrd, self.fbrd); } LCR_H => { let new_val: registers::LineControl = value.into(); @@ -242,7 +240,7 @@ impl PL011Registers { } let update = (self.line_control.send_break() != new_val.send_break()) && { let break_enable = new_val.send_break(); - let _ = char_backend.send_break(break_enable); + let _ = device.char_backend.send_break(break_enable); self.loopback_break(break_enable) }; self.line_control = new_val; @@ -279,12 +277,13 @@ impl PL011Registers { } fn read_data_register(&mut self, update: &mut bool) -> u32 { + let depth = self.fifo_depth(); self.flags.set_receive_fifo_full(false); let c = self.read_fifo[self.read_pos]; if self.read_count > 0 { self.read_count -= 1; - self.read_pos = (self.read_pos + 1) & (self.fifo_depth() - 1); + self.read_pos = (self.read_pos + 1) & (depth - 1); } if self.read_count == 0 { self.flags.set_receive_fifo_empty(true); @@ -292,6 +291,7 @@ impl PL011Registers { if self.read_count + 1 == self.read_trigger { self.int_level &= !Interrupt::RX; } + trace::trace_pl011_read_fifo(self.read_count, depth); self.receive_status_error_clear.set_from_data(c); *update = true; u32::from(c) @@ -447,7 +447,9 @@ impl PL011Registers { self.read_fifo[slot] = value; self.read_count += 1; self.flags.set_receive_fifo_empty(false); + trace::trace_pl011_fifo_rx_put(value.into(), self.read_count, depth); if self.read_count == depth { + trace::trace_pl011_fifo_rx_full(); self.flags.set_receive_fifo_full(true); } @@ -516,8 +518,21 @@ impl PL011State { uninit_field_mut!(*this, clock).write(clock); } - const fn clock_update(&self, _event: ClockEvent) { - /* pl011_trace_baudrate_change(s); */ + pub fn trace_baudrate_change(&self, ibrd: u32, fbrd: u32) { + let divider = 4.0 / f64::from(ibrd * (FBRD_MASK + 1) + fbrd); + let hz = self.clock.hz(); + let rate = if ibrd == 0 { + 0 + } else { + ((hz as f64) * divider) as u32 + }; + trace::trace_pl011_baudrate_change(rate, hz, ibrd, fbrd); + } + + fn clock_update(&self, _event: ClockEvent) { + let regs = self.regs.borrow(); + let (ibrd, fbrd) = (regs.ibrd, regs.fbrd); + self.trace_baudrate_change(ibrd, fbrd) } pub fn clock_needed(&self) -> bool { @@ -543,6 +558,7 @@ impl PL011State { } Ok(field) => { let (update_irq, result) = self.regs.borrow_mut().read(field); + trace::trace_pl011_read(offset, result, c""); if update_irq { self.update(); self.char_backend.accept_input(); @@ -557,6 +573,7 @@ impl PL011State { if let Ok(field) = RegisterOffset::try_from(offset) { // qemu_chr_fe_write_all() calls into the can_receive // callback, so handle writes before entering PL011Registers. + trace::trace_pl011_write(offset, value as u32, c""); if field == RegisterOffset::DR { // ??? Check if transmitter is enabled. let ch: [u8; 1] = [value as u8]; @@ -565,10 +582,7 @@ impl PL011State { let _ = self.char_backend.write_all(&ch); } - update_irq = self - .regs - .borrow_mut() - .write(field, value as u32, &self.char_backend); + update_irq = self.regs.borrow_mut().write(field, value as u32, self); } else { log_mask_ln!( Log::GuestError, @@ -582,11 +596,19 @@ impl PL011State { fn can_receive(&self) -> u32 { let regs = self.regs.borrow(); - // trace_pl011_can_receive(s->lcr, s->read_count, r); - regs.fifo_depth() - regs.read_count + let fifo_available = regs.fifo_depth() - regs.read_count; + trace::trace_pl011_can_receive( + regs.line_control.into(), + regs.read_count, + regs.fifo_depth(), + fifo_available, + ); + fifo_available } fn receive(&self, buf: &[u8]) { + trace::trace_pl011_receive(buf.len()); + let mut regs = self.regs.borrow_mut(); if regs.loopback_enabled() { // In loopback mode, the RX input signal is internally disconnected @@ -635,6 +657,7 @@ impl PL011State { fn update(&self) { let regs = self.regs.borrow(); let flags = regs.int_level & regs.int_enabled; + trace::trace_pl011_irq_state(flags != 0); for (irq, i) in self.interrupts.iter().zip(IRQMASK) { irq.set(flags.any_set(i)); } From 42f73f264a9fc0b1d38d84e8e716e69e929d6697 Mon Sep 17 00:00:00 2001 From: Tanish Desai Date: Mon, 29 Sep 2025 17:49:34 +0200 Subject: [PATCH 12/16] tracetool/simple: add Rust support Signed-off-by: Tanish Desai Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-ID: <20250929154938.594389-13-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/backend/simple.py | 7 +++++ tests/tracetool/simple.rs | 40 +++++++++++++++++++++++++++++ tests/tracetool/tracetool-test.py | 2 ++ 3 files changed, 49 insertions(+) create mode 100644 tests/tracetool/simple.rs diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py index b5a6b7205a..b131e4fc19 100644 --- a/scripts/tracetool/backend/simple.py +++ b/scripts/tracetool/backend/simple.py @@ -98,3 +98,10 @@ def generate_c(event, group): out(' trace_record_finish(&rec);', '}', '') + +def generate_rs(event, group): + out(' extern "C" { fn _simple_%(api)s(%(rust_args)s); }', + ' unsafe { _simple_%(api)s(%(args)s); }', + api=event.api(), + rust_args=event.args.rust_decl_extern(), + args=event.args.rust_call_extern()) diff --git a/tests/tracetool/simple.rs b/tests/tracetool/simple.rs new file mode 100644 index 0000000000..9ee39495e3 --- /dev/null +++ b/tests/tracetool/simple.rs @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// This file is @generated by tracetool, do not edit. + +#[allow(unused_imports)] +use std::ffi::c_char; +#[allow(unused_imports)] +use util::bindings; + +#[inline(always)] +fn trace_event_state_is_enabled(dstate: u16) -> bool { + (unsafe { trace_events_enabled_count }) != 0 && dstate != 0 +} + +extern "C" { + static mut trace_events_enabled_count: u32; +} +extern "C" { + static mut _TRACE_TEST_BLAH_DSTATE: u16; + static mut _TRACE_TEST_WIBBLE_DSTATE: u16; +} + +#[inline(always)] +#[allow(dead_code)] +pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr) +{ + if trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) { + extern "C" { fn _simple_trace_test_blah(_context: *mut (), _filename: *const std::ffi::c_char); } + unsafe { _simple_trace_test_blah(_context, _filename.as_ptr()); } + } +} + +#[inline(always)] +#[allow(dead_code)] +pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int) +{ + if trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) { + extern "C" { fn _simple_trace_test_wibble(_context: *mut (), _value: std::ffi::c_int); } + unsafe { _simple_trace_test_wibble(_context, _value); } + } +} diff --git a/tests/tracetool/tracetool-test.py b/tests/tracetool/tracetool-test.py index 65430fdedc..3e37890476 100755 --- a/tests/tracetool/tracetool-test.py +++ b/tests/tracetool/tracetool-test.py @@ -14,6 +14,8 @@ def get_formats(backend): "c", "h", ] + if backend in {"simple"}: + formats += ["rs"] if backend == "dtrace": formats += [ "d", From 75871d88d3ddf310dd5ffb1d36c8476959692726 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 29 Sep 2025 17:49:35 +0200 Subject: [PATCH 13/16] log: change qemu_loglevel to unsigned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bindgen makes the LOG_* constants unsigned, even if they are defined as (1 << 15): pub const LOG_TRACE: u32 = 32768; Make them unsigned in C as well through the BIT() macro, and also change the type of the variable that they are used with. Reviewed-by: Manos Pitsidianakis Reviewed-by: Zhao Liu Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-ID: <20250929154938.594389-14-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- include/qemu/log-for-trace.h | 4 ++-- include/qemu/log.h | 44 ++++++++++++++++++------------------ rust/util/src/log.rs | 2 +- util/log.c | 2 +- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/include/qemu/log-for-trace.h b/include/qemu/log-for-trace.h index d47c9cd446..f3a8791f1d 100644 --- a/include/qemu/log-for-trace.h +++ b/include/qemu/log-for-trace.h @@ -19,9 +19,9 @@ #define QEMU_LOG_FOR_TRACE_H /* Private global variable, don't use */ -extern int qemu_loglevel; +extern unsigned qemu_loglevel; -#define LOG_TRACE (1 << 15) +#define LOG_TRACE (1u << 15) /* Returns true if a bit is set in the current loglevel mask */ static inline bool qemu_loglevel_mask(int mask) diff --git a/include/qemu/log.h b/include/qemu/log.h index aae72985f0..7effba4da4 100644 --- a/include/qemu/log.h +++ b/include/qemu/log.h @@ -14,30 +14,30 @@ bool qemu_log_enabled(void); /* Returns true if qemu_log() will write somewhere other than stderr. */ bool qemu_log_separate(void); -#define CPU_LOG_TB_OUT_ASM (1 << 0) -#define CPU_LOG_TB_IN_ASM (1 << 1) -#define CPU_LOG_TB_OP (1 << 2) -#define CPU_LOG_TB_OP_OPT (1 << 3) -#define CPU_LOG_INT (1 << 4) -#define CPU_LOG_EXEC (1 << 5) -#define CPU_LOG_PCALL (1 << 6) -#define CPU_LOG_TB_CPU (1 << 8) -#define CPU_LOG_RESET (1 << 9) -#define LOG_UNIMP (1 << 10) -#define LOG_GUEST_ERROR (1 << 11) -#define CPU_LOG_MMU (1 << 12) -#define CPU_LOG_TB_NOCHAIN (1 << 13) -#define CPU_LOG_PAGE (1 << 14) +#define CPU_LOG_TB_OUT_ASM (1u << 0) +#define CPU_LOG_TB_IN_ASM (1u << 1) +#define CPU_LOG_TB_OP (1u << 2) +#define CPU_LOG_TB_OP_OPT (1u << 3) +#define CPU_LOG_INT (1u << 4) +#define CPU_LOG_EXEC (1u << 5) +#define CPU_LOG_PCALL (1u << 6) +#define CPU_LOG_TB_CPU (1u << 8) +#define CPU_LOG_RESET (1u << 9) +#define LOG_UNIMP (1u << 10) +#define LOG_GUEST_ERROR (1u << 11) +#define CPU_LOG_MMU (1u << 12) +#define CPU_LOG_TB_NOCHAIN (1u << 13) +#define CPU_LOG_PAGE (1u << 14) /* LOG_TRACE (1 << 15) is defined in log-for-trace.h */ -#define CPU_LOG_TB_OP_IND (1 << 16) -#define CPU_LOG_TB_FPU (1 << 17) -#define CPU_LOG_PLUGIN (1 << 18) +#define CPU_LOG_TB_OP_IND (1u << 16) +#define CPU_LOG_TB_FPU (1u << 17) +#define CPU_LOG_PLUGIN (1u << 18) /* LOG_STRACE is used for user-mode strace logging. */ -#define LOG_STRACE (1 << 19) -#define LOG_PER_THREAD (1 << 20) -#define CPU_LOG_TB_VPU (1 << 21) -#define LOG_TB_OP_PLUGIN (1 << 22) -#define LOG_INVALID_MEM (1 << 23) +#define LOG_STRACE (1u << 19) +#define LOG_PER_THREAD (1u << 20) +#define CPU_LOG_TB_VPU (1u << 21) +#define LOG_TB_OP_PLUGIN (1u << 22) +#define LOG_INVALID_MEM (1u << 23) /* Lock/unlock output. */ diff --git a/rust/util/src/log.rs b/rust/util/src/log.rs index af9a3e9123..0a4bc4249a 100644 --- a/rust/util/src/log.rs +++ b/rust/util/src/log.rs @@ -142,7 +142,7 @@ macro_rules! log_mask_ln { let _: $crate::log::Log = $mask; if unsafe { - ($crate::bindings::qemu_loglevel & ($mask as std::os::raw::c_int)) != 0 + ($crate::bindings::qemu_loglevel & ($mask as std::os::raw::c_uint)) != 0 } { _ = $crate::log::LogGuard::log_fmt( format_args!("{}\n", format_args!($fmt $($args)*))); diff --git a/util/log.c b/util/log.c index abdcb6b311..41f78ce86b 100644 --- a/util/log.c +++ b/util/log.c @@ -44,7 +44,7 @@ static FILE *global_file; static __thread FILE *thread_file; static __thread Notifier qemu_log_thread_cleanup_notifier; -int qemu_loglevel; +unsigned qemu_loglevel; static bool log_per_thread; static GArray *debug_regions; From c4e8d44bac5cecebba9bb7293b4256bd57e9f52e Mon Sep 17 00:00:00 2001 From: Tanish Desai Date: Mon, 29 Sep 2025 17:49:36 +0200 Subject: [PATCH 14/16] tracetool/log: add Rust support Signed-off-by: Tanish Desai Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-ID: <20250929154938.594389-15-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/backend/log.py | 10 ++++++- tests/tracetool/log.rs | 44 +++++++++++++++++++++++++++++++ tests/tracetool/tracetool-test.py | 2 +- 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 tests/tracetool/log.rs diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py index d01d234289..9e3e5046f5 100644 --- a/scripts/tracetool/backend/log.py +++ b/scripts/tracetool/backend/log.py @@ -12,7 +12,7 @@ __maintainer__ = "Stefan Hajnoczi" __email__ = "stefanha@redhat.com" -from tracetool import out +from tracetool import out, expand_format_string PUBLIC = True @@ -44,3 +44,11 @@ def generate_h(event, group): def generate_h_backend_dstate(event, group): out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\', event_id="TRACE_" + event.name.upper()) + +def generate_rs(event, group): + out(' let format_string = c"%(fmt)s\\n";', + ' if (unsafe { bindings::qemu_loglevel } & bindings::LOG_TRACE) != 0 {', + ' unsafe { bindings::qemu_log(format_string.as_ptr() as *const c_char, %(args)s);}', + ' }', + fmt=expand_format_string(event.fmt, event.name + " "), + args=event.args.rust_call_varargs()) diff --git a/tests/tracetool/log.rs b/tests/tracetool/log.rs new file mode 100644 index 0000000000..c191895c8f --- /dev/null +++ b/tests/tracetool/log.rs @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// This file is @generated by tracetool, do not edit. + +#[allow(unused_imports)] +use std::ffi::c_char; +#[allow(unused_imports)] +use util::bindings; + +#[inline(always)] +fn trace_event_state_is_enabled(dstate: u16) -> bool { + (unsafe { trace_events_enabled_count }) != 0 && dstate != 0 +} + +extern "C" { + static mut trace_events_enabled_count: u32; +} +extern "C" { + static mut _TRACE_TEST_BLAH_DSTATE: u16; + static mut _TRACE_TEST_WIBBLE_DSTATE: u16; +} + +#[inline(always)] +#[allow(dead_code)] +pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr) +{ + if trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) { + let format_string = c"test_blah Blah context=%p filename=%s\n"; + if (unsafe { bindings::qemu_loglevel } & bindings::LOG_TRACE) != 0 { + unsafe { bindings::qemu_log(format_string.as_ptr() as *const c_char, _context /* as *mut () */, _filename.as_ptr());} + } + } +} + +#[inline(always)] +#[allow(dead_code)] +pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int) +{ + if trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) { + let format_string = c"test_wibble Wibble context=%p value=%d\n"; + if (unsafe { bindings::qemu_loglevel } & bindings::LOG_TRACE) != 0 { + unsafe { bindings::qemu_log(format_string.as_ptr() as *const c_char, _context /* as *mut () */, _value /* as std::ffi::c_int */);} + } + } +} diff --git a/tests/tracetool/tracetool-test.py b/tests/tracetool/tracetool-test.py index 3e37890476..f58f3b795e 100755 --- a/tests/tracetool/tracetool-test.py +++ b/tests/tracetool/tracetool-test.py @@ -14,7 +14,7 @@ def get_formats(backend): "c", "h", ] - if backend in {"simple"}: + if backend in {"log", "simple"}: formats += ["rs"] if backend == "dtrace": formats += [ From 7dbee1274266b802456c7f07dc10184af2dc1ec0 Mon Sep 17 00:00:00 2001 From: Tanish Desai Date: Mon, 29 Sep 2025 17:49:37 +0200 Subject: [PATCH 15/16] tracetool/ftrace: add Rust support Signed-off-by: Tanish Desai Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-ID: <20250929154938.594389-16-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/backend/ftrace.py | 8 +++++- tests/tracetool/ftrace.rs | 40 +++++++++++++++++++++++++++++ tests/tracetool/tracetool-test.py | 2 +- 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 tests/tracetool/ftrace.rs diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py index 7ddd5d11a6..e03698a2ed 100644 --- a/scripts/tracetool/backend/ftrace.py +++ b/scripts/tracetool/backend/ftrace.py @@ -12,7 +12,7 @@ __maintainer__ = "Stefan Hajnoczi" __email__ = "stefanha@redhat.com" -from tracetool import out +from tracetool import out, expand_format_string PUBLIC = True @@ -43,3 +43,9 @@ def generate_h(event, group): def generate_h_backend_dstate(event, group): out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\', event_id="TRACE_" + event.name.upper()) + +def generate_rs(event, group): + out(' let format_string = c"%(fmt)s";', + ' unsafe {bindings::ftrace_write(format_string.as_ptr() as *const c_char, %(args)s);}', + fmt=expand_format_string(event.fmt), + args=event.args.rust_call_varargs()) diff --git a/tests/tracetool/ftrace.rs b/tests/tracetool/ftrace.rs new file mode 100644 index 0000000000..07b9259cf2 --- /dev/null +++ b/tests/tracetool/ftrace.rs @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// This file is @generated by tracetool, do not edit. + +#[allow(unused_imports)] +use std::ffi::c_char; +#[allow(unused_imports)] +use util::bindings; + +#[inline(always)] +fn trace_event_state_is_enabled(dstate: u16) -> bool { + (unsafe { trace_events_enabled_count }) != 0 && dstate != 0 +} + +extern "C" { + static mut trace_events_enabled_count: u32; +} +extern "C" { + static mut _TRACE_TEST_BLAH_DSTATE: u16; + static mut _TRACE_TEST_WIBBLE_DSTATE: u16; +} + +#[inline(always)] +#[allow(dead_code)] +pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr) +{ + if trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) { + let format_string = c"Blah context=%p filename=%s"; + unsafe {bindings::ftrace_write(format_string.as_ptr() as *const c_char, _context /* as *mut () */, _filename.as_ptr());} + } +} + +#[inline(always)] +#[allow(dead_code)] +pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int) +{ + if trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) { + let format_string = c"Wibble context=%p value=%d"; + unsafe {bindings::ftrace_write(format_string.as_ptr() as *const c_char, _context /* as *mut () */, _value /* as std::ffi::c_int */);} + } +} diff --git a/tests/tracetool/tracetool-test.py b/tests/tracetool/tracetool-test.py index f58f3b795e..3341fb18f9 100755 --- a/tests/tracetool/tracetool-test.py +++ b/tests/tracetool/tracetool-test.py @@ -14,7 +14,7 @@ def get_formats(backend): "c", "h", ] - if backend in {"log", "simple"}: + if backend in {"ftrace", "log", "simple"}: formats += ["rs"] if backend == "dtrace": formats += [ From 1461752f0fa4bcd7e60d51fe47e3430f8a81cdd8 Mon Sep 17 00:00:00 2001 From: Tanish Desai Date: Mon, 29 Sep 2025 17:49:38 +0200 Subject: [PATCH 16/16] tracetool/syslog: add Rust support The syslog backend needs the syslog function from libc and the LOG_INFO enum value; they are re-exported as "::trace::syslog" and "::trace::LOG_INFO" so that device crates do not all have to add the libc dependency, but otherwise there is nothing special. Signed-off-by: Tanish Desai Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-ID: <20250929154938.594389-17-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- rust/Cargo.lock | 3 +++ rust/trace/Cargo.toml | 3 +++ rust/trace/src/lib.rs | 4 +++ scripts/tracetool/backend/syslog.py | 7 ++++- tests/tracetool/syslog.rs | 40 +++++++++++++++++++++++++++++ tests/tracetool/tracetool-test.py | 2 +- 6 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 tests/tracetool/syslog.rs diff --git a/rust/Cargo.lock b/rust/Cargo.lock index f84a3dd076..444ef516a7 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -262,6 +262,9 @@ dependencies = [ [[package]] name = "trace" version = "0.1.0" +dependencies = [ + "libc", +] [[package]] name = "unicode-ident" diff --git a/rust/trace/Cargo.toml b/rust/trace/Cargo.toml index 13ac0b33d6..fc81bce580 100644 --- a/rust/trace/Cargo.toml +++ b/rust/trace/Cargo.toml @@ -12,5 +12,8 @@ license.workspace = true repository.workspace = true rust-version.workspace = true +[dependencies] +libc = { workspace = true } + [lints] workspace = true diff --git a/rust/trace/src/lib.rs b/rust/trace/src/lib.rs index 0955461573..e03bce43c4 100644 --- a/rust/trace/src/lib.rs +++ b/rust/trace/src/lib.rs @@ -3,6 +3,10 @@ //! This crate provides macros that aid in using QEMU's tracepoint //! functionality. +#[doc(hidden)] +/// Re-exported item to avoid adding libc as a dependency everywhere. +pub use libc::{syslog, LOG_INFO}; + #[macro_export] /// Define the trace-points from the named directory (which should have slashes /// replaced by underscore characters) as functions in a module called `trace`. diff --git a/scripts/tracetool/backend/syslog.py b/scripts/tracetool/backend/syslog.py index 177414d56a..12b826593d 100644 --- a/scripts/tracetool/backend/syslog.py +++ b/scripts/tracetool/backend/syslog.py @@ -12,7 +12,7 @@ __maintainer__ = "Stefan Hajnoczi" __email__ = "stefanha@redhat.com" -from tracetool import out +from tracetool import out, expand_format_string PUBLIC = True @@ -38,6 +38,11 @@ def generate_h(event, group): fmt=event.fmt.rstrip("\n"), argnames=argnames) +def generate_rs(event, group): + out(' let format_string = c"%(fmt)s";', + ' unsafe {::trace::syslog(::trace::LOG_INFO, format_string.as_ptr() as *const c_char, %(args)s);}', + fmt=expand_format_string(event.fmt), + args=event.args.rust_call_varargs()) def generate_h_backend_dstate(event, group): out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\', diff --git a/tests/tracetool/syslog.rs b/tests/tracetool/syslog.rs new file mode 100644 index 0000000000..9d3675a0b5 --- /dev/null +++ b/tests/tracetool/syslog.rs @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// This file is @generated by tracetool, do not edit. + +#[allow(unused_imports)] +use std::ffi::c_char; +#[allow(unused_imports)] +use util::bindings; + +#[inline(always)] +fn trace_event_state_is_enabled(dstate: u16) -> bool { + (unsafe { trace_events_enabled_count }) != 0 && dstate != 0 +} + +extern "C" { + static mut trace_events_enabled_count: u32; +} +extern "C" { + static mut _TRACE_TEST_BLAH_DSTATE: u16; + static mut _TRACE_TEST_WIBBLE_DSTATE: u16; +} + +#[inline(always)] +#[allow(dead_code)] +pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr) +{ + if trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) { + let format_string = c"Blah context=%p filename=%s"; + unsafe {::trace::syslog(::trace::LOG_INFO, format_string.as_ptr() as *const c_char, _context /* as *mut () */, _filename.as_ptr());} + } +} + +#[inline(always)] +#[allow(dead_code)] +pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int) +{ + if trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) { + let format_string = c"Wibble context=%p value=%d"; + unsafe {::trace::syslog(::trace::LOG_INFO, format_string.as_ptr() as *const c_char, _context /* as *mut () */, _value /* as std::ffi::c_int */);} + } +} diff --git a/tests/tracetool/tracetool-test.py b/tests/tracetool/tracetool-test.py index 3341fb18f9..786083ad7f 100755 --- a/tests/tracetool/tracetool-test.py +++ b/tests/tracetool/tracetool-test.py @@ -14,7 +14,7 @@ def get_formats(backend): "c", "h", ] - if backend in {"ftrace", "log", "simple"}: + if backend in {"ftrace", "log", "simple", "syslog"}: formats += ["rs"] if backend == "dtrace": formats += [