* [PATCH 01/16] tracetool: fix usage of try_import()
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-23 19:06 ` Stefan Hajnoczi
2025-09-19 11:25 ` [PATCH 02/16] tracetool: remove dead code Paolo Bonzini
` (15 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
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.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 7bfcc86cc53..6c6344deddb 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 2dc46f3dd93..042fe7d103c 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):
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [PATCH 01/16] tracetool: fix usage of try_import()
2025-09-19 11:25 ` [PATCH 01/16] tracetool: fix usage of try_import() Paolo Bonzini
@ 2025-09-23 19:06 ` Stefan Hajnoczi
0 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:06 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 550 bytes --]
On Fri, Sep 19, 2025 at 01:25:21PM +0200, Paolo Bonzini wrote:
> 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.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> scripts/tracetool/backend/__init__.py | 2 +-
> scripts/tracetool/format/__init__.py | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 02/16] tracetool: remove dead code
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
2025-09-19 11:25 ` [PATCH 01/16] tracetool: fix usage of try_import() Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-23 19:06 ` Stefan Hajnoczi
2025-09-19 11:25 ` [PATCH 03/16] treewide: remove unnessary "coding" header Paolo Bonzini
` (14 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
There are no tcg-exec events anymore and the sub-event functionality was
only used for it. Excise it from tracetool.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
scripts/tracetool/__init__.py | 44 +++++------------------------------
scripts/tracetool/format/h.py | 5 ----
2 files changed, 6 insertions(+), 43 deletions(-)
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 1d5238a0843..afa889e759e 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -122,10 +122,6 @@ def __init__(self, args):
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 +218,12 @@ class Event(object):
r"(?P<name>\w+)"
r"\((?P<args>[^)]*)\)"
r"\s*"
- r"(?:(?:(?P<fmt_trans>\".+),)?\s*(?P<fmt>\".+))?"
+ r"(?P<fmt>\".+)?"
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 +231,14 @@ def __init__(self, name, props, fmt, args, lineno, filename, orig=None,
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 +247,16 @@ def __init__(self, name, props, fmt, args, lineno, filename, orig=None,
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 +278,7 @@ def build(line_str, lineno, filename):
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 +287,22 @@ def build(line_str, lineno, filename):
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 b42a8268a81..bd9e0ca7f23 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)
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [PATCH 02/16] tracetool: remove dead code
2025-09-19 11:25 ` [PATCH 02/16] tracetool: remove dead code Paolo Bonzini
@ 2025-09-23 19:06 ` Stefan Hajnoczi
0 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:06 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 480 bytes --]
On Fri, Sep 19, 2025 at 01:25:22PM +0200, Paolo Bonzini wrote:
> There are no tcg-exec events anymore and the sub-event functionality was
> only used for it. Excise it from tracetool.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> scripts/tracetool/__init__.py | 44 +++++------------------------------
> scripts/tracetool/format/h.py | 5 ----
> 2 files changed, 6 insertions(+), 43 deletions(-)
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 03/16] treewide: remove unnessary "coding" header
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
2025-09-19 11:25 ` [PATCH 01/16] tracetool: fix usage of try_import() Paolo Bonzini
2025-09-19 11:25 ` [PATCH 02/16] tracetool: remove dead code Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-23 19:06 ` Stefan Hajnoczi
2025-09-19 11:25 ` [PATCH 04/16] tracetool: add SPDX headers Paolo Bonzini
` (13 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
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 <manos.pitsidianakis@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 e09769e5f83..0c9ec74097f 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 b225bf706f5..f312e9b57e4 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 d650dd71408..bd04cd43c94 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 48bd92bd618..6ebaea989db 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 b1538fcced7..aaf23544c46 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 d1f3990c16a..414a6d91dd8 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 e8ef76b3413..0df96cf9587 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 b154a25508f..8af0d5d9c4e 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 6bcadce1500..43c70302873 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 e35e4ddb26a..f73bc553db6 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 cae0a083591..f40b247f8b6 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 d3c56d45c89..0c9b8db3b02 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 2529edf81aa..9fbf80a5410 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 3abddea3525..8d88b40de2e 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 e285ebb8f9e..69644979c19 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 16c03c06a94..22529c72775 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 46537b27cf0..5714f92cc21 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 4ce7ff51cc7..097636570dd 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 5de9ce96d30..0fdc9cb9477 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 afa889e759e..4f262d3394d 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 6c6344deddb..70401309196 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 e17edc9b9d8..4835454193d 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 5fa30ccc08e..e6317ca4bfb 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 eb50ceea34c..9842522b184 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 7c84c06b200..066e5e9f11f 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 3f82e54aabf..74af0380899 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 c857516f212..6cc651646dd 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 042fe7d103c..94a37bfce9f 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 e473fb6c6eb..3c4398c2373 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 a5e096e214b..684598c1835 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 bd9e0ca7f23..2119753be10 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 710d62bffe4..c6577b52c3a 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 72971133bf0..863187c806e 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 4d77fbc11a9..04c7a35a25f 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 569754a3048..ea5f0ae99fa 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 2a31fefeca1..242c9814fdc 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
"""
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [PATCH 03/16] treewide: remove unnessary "coding" header
2025-09-19 11:25 ` [PATCH 03/16] treewide: remove unnessary "coding" header Paolo Bonzini
@ 2025-09-23 19:06 ` Stefan Hajnoczi
0 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:06 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 2615 bytes --]
On Fri, Sep 19, 2025 at 01:25:23PM +0200, Paolo Bonzini wrote:
> 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 <manos.pitsidianakis@linaro.org>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> 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(-)
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 04/16] tracetool: add SPDX headers
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (2 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 03/16] treewide: remove unnessary "coding" header Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-23 19:06 ` Stefan Hajnoczi
2025-09-19 11:25 ` [PATCH 05/16] trace/ftrace: move snprintf+write from tracepoints to ftrace.c Paolo Bonzini
` (12 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 4f262d3394d..a58d7938658 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 70401309196..bf91e443e99 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 4835454193d..b4af403025c 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 e6317ca4bfb..a14aafcee62 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 9842522b184..faacec46105 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 066e5e9f11f..97e40495ee9 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 74af0380899..78ee67136b8 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 6cc651646dd..3aa9bb1da29 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 94a37bfce9f..7b9d1b57826 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 3c4398c2373..50e03313cbf 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 684598c1835..e9e33dfe30a 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 2119753be10..be7f32e67b9 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 c6577b52c3a..e45d614ed47 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 863187c806e..d33bae757ff 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 04c7a35a25f..285c9203ba7 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 ea5f0ae99fa..074226bfd37 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 242c9814fdc..cee7970a403 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
"""
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [PATCH 04/16] tracetool: add SPDX headers
2025-09-19 11:25 ` [PATCH 04/16] tracetool: add SPDX headers Paolo Bonzini
@ 2025-09-23 19:06 ` Stefan Hajnoczi
0 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:06 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 1147 bytes --]
On Fri, Sep 19, 2025 at 01:25:24PM +0200, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> 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(+)
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 05/16] trace/ftrace: move snprintf+write from tracepoints to ftrace.c
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (3 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 04/16] tracetool: add SPDX headers Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-19 11:25 ` [PATCH 06/16] tracetool: add CHECK_TRACE_EVENT_GET_STATE Paolo Bonzini
` (11 subsequent siblings)
16 siblings, 0 replies; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
This simplifies the Python code and reduces the size of the tracepoints.
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
tests/tracetool/ftrace.h | 28 ++++++----------------------
trace/ftrace.h | 1 +
trace/ftrace.c | 15 +++++++++++++++
scripts/tracetool/backend/ftrace.py | 12 ++----------
4 files changed, 24 insertions(+), 32 deletions(-)
diff --git a/tests/tracetool/ftrace.h b/tests/tracetool/ftrace.h
index fe22ea0f09f..1dfe4239413 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.h b/trace/ftrace.h
index cb5e35d2171..16c122816d1 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 */
diff --git a/trace/ftrace.c b/trace/ftrace.c
index 9749543d9b2..6875faedb9c 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/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py
index a14aafcee62..8c0ce3f23a0 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,
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* [PATCH 06/16] tracetool: add CHECK_TRACE_EVENT_GET_STATE
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (4 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 05/16] trace/ftrace: move snprintf+write from tracepoints to ftrace.c Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-19 11:25 ` [PATCH 07/16] tracetool/backend: remove redundant trace event checks Paolo Bonzini
` (10 subsequent siblings)
16 siblings, 0 replies; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
From: Tanish Desai <tanishdesai37@gmail.com>
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 <tanishdesai37@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 bf91e443e99..9109a783c72 100644
--- a/scripts/tracetool/backend/__init__.py
+++ b/scripts/tracetool/backend/__init__.py
@@ -19,11 +19,15 @@
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 be7f32e67b9..dd58713a158 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())
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* [PATCH 07/16] tracetool/backend: remove redundant trace event checks
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (5 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 06/16] tracetool: add CHECK_TRACE_EVENT_GET_STATE Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-19 11:25 ` [PATCH 08/16] tracetool: Add Rust format support Paolo Bonzini
` (9 subsequent siblings)
16 siblings, 0 replies; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
From: Tanish Desai <tanishdesai37@gmail.com>
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 <tanishdesai37@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
tests/tracetool/log.h | 16 ++++++++++------
scripts/tracetool/backend/ftrace.py | 6 ++----
scripts/tracetool/backend/log.py | 10 ++++------
scripts/tracetool/backend/simple.py | 8 ++------
scripts/tracetool/backend/syslog.py | 8 ++------
5 files changed, 20 insertions(+), 28 deletions(-)
diff --git a/tests/tracetool/log.h b/tests/tracetool/log.h
index edcc7f9d47c..c7795871f85 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 */
diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py
index 8c0ce3f23a0..7ddd5d11a66 100644
--- a/scripts/tracetool/backend/ftrace.py
+++ b/scripts/tracetool/backend/ftrace.py
@@ -16,6 +16,7 @@
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 faacec46105..d01d234289f 100644
--- a/scripts/tracetool/backend/log.py
+++ b/scripts/tracetool/backend/log.py
@@ -16,6 +16,7 @@
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 97e40495ee9..b5a6b7205a3 100644
--- a/scripts/tracetool/backend/simple.py
+++ b/scripts/tracetool/backend/simple.py
@@ -16,6 +16,7 @@
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 78ee67136b8..177414d56a6 100644
--- a/scripts/tracetool/backend/syslog.py
+++ b/scripts/tracetool/backend/syslog.py
@@ -16,6 +16,7 @@
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,
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* [PATCH 08/16] tracetool: Add Rust format support
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (6 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 07/16] tracetool/backend: remove redundant trace event checks Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-23 19:23 ` Stefan Hajnoczi
2025-09-19 11:25 ` [PATCH 09/16] rust: add trace crate Paolo Bonzini
` (8 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
From: Tanish Desai <tanishdesai37@gmail.com>
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.
Signed-off-by: Tanish Desai <tanishdesai37@gmail.com>
[Move Rust argument conversion from Event to Arguments; string
support. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
scripts/tracetool/__init__.py | 155 +++++++++++++++++++++++++++++++++
scripts/tracetool/format/rs.py | 71 +++++++++++++++
2 files changed, 226 insertions(+)
create mode 100644 scripts/tracetool/format/rs.py
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index a58d7938658..ea3e83f5adf 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -31,6 +31,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 = '<none>'
@@ -90,6 +133,49 @@ def out(*lines, **kwargs):
"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:
@@ -105,6 +191,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."""
@@ -193,6 +311,43 @@ def casted(self):
"""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 00000000000..c4ab0e59d85
--- /dev/null
+++ b/scripts/tracetool/format/rs.py
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+"""
+trace-DIR.rs
+"""
+
+__author__ = "Tanish Desai <tanishdesai37@gmail.com>"
+__copyright__ = "Copyright 2025, Tanish Desai <tanishdesai37@gmail.com>"
+__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_get_state_dynamic_by_id(_id: u16) -> bool {',
+ ' unsafe { (trace_events_enabled_count != 0) && (_id != 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('}')
+
+ # static state
+ for e in events:
+ if 'disable' in e.properties:
+ enabled = "false"
+ else:
+ enabled = "true"
+
+ 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_get_state_dynamic_by_id(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)
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [PATCH 08/16] tracetool: Add Rust format support
2025-09-19 11:25 ` [PATCH 08/16] tracetool: Add Rust format support Paolo Bonzini
@ 2025-09-23 19:23 ` Stefan Hajnoczi
2025-09-24 7:13 ` Paolo Bonzini
0 siblings, 1 reply; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:23 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 10556 bytes --]
On Fri, Sep 19, 2025 at 01:25:28PM +0200, Paolo Bonzini wrote:
> From: Tanish Desai <tanishdesai37@gmail.com>
>
> 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.
>
> Signed-off-by: Tanish Desai <tanishdesai37@gmail.com>
> [Move Rust argument conversion from Event to Arguments; string
> support. - Paolo]
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> scripts/tracetool/__init__.py | 155 +++++++++++++++++++++++++++++++++
> scripts/tracetool/format/rs.py | 71 +++++++++++++++
> 2 files changed, 226 insertions(+)
> create mode 100644 scripts/tracetool/format/rs.py
>
> diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
> index a58d7938658..ea3e83f5adf 100644
> --- a/scripts/tracetool/__init__.py
> +++ b/scripts/tracetool/__init__.py
> @@ -31,6 +31,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 = '<none>'
> @@ -90,6 +133,49 @@ def out(*lines, **kwargs):
> "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:
> @@ -105,6 +191,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."""
>
> @@ -193,6 +311,43 @@ def casted(self):
> """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 00000000000..c4ab0e59d85
> --- /dev/null
> +++ b/scripts/tracetool/format/rs.py
> @@ -0,0 +1,71 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +
> +"""
> +trace-DIR.rs
> +"""
> +
> +__author__ = "Tanish Desai <tanishdesai37@gmail.com>"
> +__copyright__ = "Copyright 2025, Tanish Desai <tanishdesai37@gmail.com>"
> +__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_get_state_dynamic_by_id(_id: u16) -> bool {',
> + ' unsafe { (trace_events_enabled_count != 0) && (_id != 0) }',
> + '}',
This was translated to Rust from:
/* it's on fast path, avoid consistency checks (asserts) */
#define trace_event_get_state_dynamic_by_id(id) \
(unlikely(trace_events_enabled_count) && _ ## id ## _DSTATE)
The _id != 0 expression is incorrect. The purpose was to check whether
the trace event is currently enabled (i.e. dynamically at runtime).
> + '',
> + '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('}')
> +
> + # static state
> + for e in events:
> + if 'disable' in e.properties:
> + enabled = "false"
> + else:
> + enabled = "true"
What is the purpose of this loop? The variable enabled is unused so I
think it can be deleted.
> +
> + backend.generate_begin(events, group)
> +
> + for e in events:
> + out('',
> + '#[inline(always)]',
Tabs snuck in here. This should be indented with spaces.
> + '#[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_get_state_dynamic_by_id(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)
> --
> 2.51.0
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread* Re: [PATCH 08/16] tracetool: Add Rust format support
2025-09-23 19:23 ` Stefan Hajnoczi
@ 2025-09-24 7:13 ` Paolo Bonzini
2025-09-24 7:50 ` Daniel P. Berrangé
2025-09-24 18:10 ` Stefan Hajnoczi
0 siblings, 2 replies; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-24 7:13 UTC (permalink / raw)
To: Stefan Hajnoczi
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P. Berrangé, Mads Ynddal
On 9/23/25 21:23, Stefan Hajnoczi wrote:
>> + 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_get_state_dynamic_by_id(_id: u16) -> bool {',
>> + ' unsafe { (trace_events_enabled_count != 0) && (_id != 0) }',
>> + '}',
>
> This was translated to Rust from:
>
> /* it's on fast path, avoid consistency checks (asserts) */
> #define trace_event_get_state_dynamic_by_id(id) \
> (unlikely(trace_events_enabled_count) && _ ## id ## _DSTATE)
>
> The _id != 0 expression is incorrect. The purpose was to check whether
> the trace event is currently enabled (i.e. dynamically at runtime).
The expression is correct, but the function and argument names are not.
It should be
fn trace_event_state_is_enabled(dstate: u16) -> bool {
unsafe { trace_events_enabled_count } != 0 && dstate != 0
}
>> + # static state
>> + for e in events:
>> + if 'disable' in e.properties:
>> + enabled = "false"
>> + else:
>> + enabled = "true"
>
> What is the purpose of this loop? The variable enabled is unused so I
> think it can be deleted.
The Rust code generator is not emitting any code for disabled
tracepoints. Unlike C, where the disabled tracepoints can produce e.g.
-Wformat warnings, there's no real benefit here.
In the RFC the "enabled" variable was used to produce a const for the
static state; it had no user so I removed it, but I left behind this
dead Python code. Sorry about that!
Paolo
^ permalink raw reply [flat|nested] 42+ messages in thread* Re: [PATCH 08/16] tracetool: Add Rust format support
2025-09-24 7:13 ` Paolo Bonzini
@ 2025-09-24 7:50 ` Daniel P. Berrangé
2025-09-24 11:49 ` Stefan Hajnoczi
2025-09-24 18:10 ` Stefan Hajnoczi
1 sibling, 1 reply; 42+ messages in thread
From: Daniel P. Berrangé @ 2025-09-24 7:50 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Stefan Hajnoczi, qemu-devel, Tanish Desai, Zhao Liu,
Manos Pitsidianakis, Mads Ynddal
On Wed, Sep 24, 2025 at 09:13:15AM +0200, Paolo Bonzini wrote:
> On 9/23/25 21:23, Stefan Hajnoczi wrote:
> > > + 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_get_state_dynamic_by_id(_id: u16) -> bool {',
> > > + ' unsafe { (trace_events_enabled_count != 0) && (_id != 0) }',
> > > + '}',
> >
> > This was translated to Rust from:
> >
> > /* it's on fast path, avoid consistency checks (asserts) */
> > #define trace_event_get_state_dynamic_by_id(id) \
> > (unlikely(trace_events_enabled_count) && _ ## id ## _DSTATE)
> >
> > The _id != 0 expression is incorrect. The purpose was to check whether
> > the trace event is currently enabled (i.e. dynamically at runtime).
>
> The expression is correct, but the function and argument names are not. It
> should be
>
> fn trace_event_state_is_enabled(dstate: u16) -> bool {
> unsafe { trace_events_enabled_count } != 0 && dstate != 0
> }
>
> > > + # static state
> > > + for e in events:
> > > + if 'disable' in e.properties:
> > > + enabled = "false"
> > > + else:
> > > + enabled = "true"
> >
> > What is the purpose of this loop? The variable enabled is unused so I
> > think it can be deleted.
>
> The Rust code generator is not emitting any code for disabled tracepoints.
> Unlike C, where the disabled tracepoints can produce e.g. -Wformat warnings,
> there's no real benefit here.
>
> In the RFC the "enabled" variable was used to produce a const for the static
> state; it had no user so I removed it, but I left behind this dead Python
> code. Sorry about that!
Is the concept of build time 'disabled' tracepoints actually useful to
still support ? AFAICT we use it in only places, which doesn't make it
sound too compelling:
$ find -name trace-events | xargs grep '^disable'
./target/hppa/trace-events:disable hppa_tlb_flush_ent(void *env, void *ent, uint64_t va_b, uint64_t va_e, uint64_t pa) "env=%p ent=%p va_b=0x%lx va_e=0x%lx pa=0x%lx"
./target/hppa/trace-events:disable hppa_tlb_find_entry(void *env, void *ent, int valid, uint64_t va_b, uint64_t va_e, uint64_t pa) "env=%p ent=%p valid=%d va_b=0x%lx va_e=0x%lx pa=0x%lx"
./target/hppa/trace-events:disable hppa_tlb_find_entry_not_found(void *env, uint64_t addr) "env=%p addr=%08lx"
...snip...
./target/hppa/trace-events:disable hppa_tlb_lpa_success(void *env, uint64_t addr, uint64_t phys) "env=%p addr=0x%lx phys=0x%lx"
./target/hppa/trace-events:disable hppa_tlb_lpa_failed(void *env, uint64_t addr) "env=%p addr=0x%lx"
./target/hppa/trace-events:disable hppa_tlb_probe(uint64_t addr, int level, int want) "addr=0x%lx level=%d want=%d"
./hw/display/trace-events:disable qxl_io_write_vga(int qid, const char *mode, uint32_t addr, uint32_t val) "%d %s addr=%u val=%u"
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 42+ messages in thread* Re: [PATCH 08/16] tracetool: Add Rust format support
2025-09-24 7:50 ` Daniel P. Berrangé
@ 2025-09-24 11:49 ` Stefan Hajnoczi
2025-09-24 11:56 ` Daniel P. Berrangé
0 siblings, 1 reply; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-24 11:49 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: Paolo Bonzini, Stefan Hajnoczi, qemu-devel, Tanish Desai,
Zhao Liu, Manos Pitsidianakis, Mads Ynddal
On Wed, Sep 24, 2025 at 3:51 AM Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> On Wed, Sep 24, 2025 at 09:13:15AM +0200, Paolo Bonzini wrote:
> > On 9/23/25 21:23, Stefan Hajnoczi wrote:
> > > > + 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_get_state_dynamic_by_id(_id: u16) -> bool {',
> > > > + ' unsafe { (trace_events_enabled_count != 0) && (_id != 0) }',
> > > > + '}',
> > >
> > > This was translated to Rust from:
> > >
> > > /* it's on fast path, avoid consistency checks (asserts) */
> > > #define trace_event_get_state_dynamic_by_id(id) \
> > > (unlikely(trace_events_enabled_count) && _ ## id ## _DSTATE)
> > >
> > > The _id != 0 expression is incorrect. The purpose was to check whether
> > > the trace event is currently enabled (i.e. dynamically at runtime).
> >
> > The expression is correct, but the function and argument names are not. It
> > should be
> >
> > fn trace_event_state_is_enabled(dstate: u16) -> bool {
> > unsafe { trace_events_enabled_count } != 0 && dstate != 0
> > }
> >
> > > > + # static state
> > > > + for e in events:
> > > > + if 'disable' in e.properties:
> > > > + enabled = "false"
> > > > + else:
> > > > + enabled = "true"
> > >
> > > What is the purpose of this loop? The variable enabled is unused so I
> > > think it can be deleted.
> >
> > The Rust code generator is not emitting any code for disabled tracepoints.
> > Unlike C, where the disabled tracepoints can produce e.g. -Wformat warnings,
> > there's no real benefit here.
> >
> > In the RFC the "enabled" variable was used to produce a const for the static
> > state; it had no user so I removed it, but I left behind this dead Python
> > code. Sorry about that!
>
> Is the concept of build time 'disabled' tracepoints actually useful to
> still support ? AFAICT we use it in only places, which doesn't make it
> sound too compelling:
>
> $ find -name trace-events | xargs grep '^disable'
> ./target/hppa/trace-events:disable hppa_tlb_flush_ent(void *env, void *ent, uint64_t va_b, uint64_t va_e, uint64_t pa) "env=%p ent=%p va_b=0x%lx va_e=0x%lx pa=0x%lx"
> ./target/hppa/trace-events:disable hppa_tlb_find_entry(void *env, void *ent, int valid, uint64_t va_b, uint64_t va_e, uint64_t pa) "env=%p ent=%p valid=%d va_b=0x%lx va_e=0x%lx pa=0x%lx"
> ./target/hppa/trace-events:disable hppa_tlb_find_entry_not_found(void *env, uint64_t addr) "env=%p addr=%08lx"
> ...snip...
> ./target/hppa/trace-events:disable hppa_tlb_lpa_success(void *env, uint64_t addr, uint64_t phys) "env=%p addr=0x%lx phys=0x%lx"
> ./target/hppa/trace-events:disable hppa_tlb_lpa_failed(void *env, uint64_t addr) "env=%p addr=0x%lx"
> ./target/hppa/trace-events:disable hppa_tlb_probe(uint64_t addr, int level, int want) "addr=0x%lx level=%d want=%d"
> ./hw/display/trace-events:disable qxl_io_write_vga(int qid, const char *mode, uint32_t addr, uint32_t val) "%d %s addr=%u val=%u"
My recollection is that disabled events were supposed to eliminate the
cost of trace events. Downstreams could disable trace events that they
didn't need.
I'm not aware of any users besides the ones that your grep identified.
We could probably remove the disable keyword without any real impact
on users.
Stefan
^ permalink raw reply [flat|nested] 42+ messages in thread* Re: [PATCH 08/16] tracetool: Add Rust format support
2025-09-24 11:49 ` Stefan Hajnoczi
@ 2025-09-24 11:56 ` Daniel P. Berrangé
0 siblings, 0 replies; 42+ messages in thread
From: Daniel P. Berrangé @ 2025-09-24 11:56 UTC (permalink / raw)
To: Stefan Hajnoczi
Cc: Paolo Bonzini, Stefan Hajnoczi, qemu-devel, Tanish Desai,
Zhao Liu, Manos Pitsidianakis, Mads Ynddal
On Wed, Sep 24, 2025 at 07:49:49AM -0400, Stefan Hajnoczi wrote:
> On Wed, Sep 24, 2025 at 3:51 AM Daniel P. Berrangé <berrange@redhat.com> wrote:
> >
> > On Wed, Sep 24, 2025 at 09:13:15AM +0200, Paolo Bonzini wrote:
> > > On 9/23/25 21:23, Stefan Hajnoczi wrote:
> > > > > + 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_get_state_dynamic_by_id(_id: u16) -> bool {',
> > > > > + ' unsafe { (trace_events_enabled_count != 0) && (_id != 0) }',
> > > > > + '}',
> > > >
> > > > This was translated to Rust from:
> > > >
> > > > /* it's on fast path, avoid consistency checks (asserts) */
> > > > #define trace_event_get_state_dynamic_by_id(id) \
> > > > (unlikely(trace_events_enabled_count) && _ ## id ## _DSTATE)
> > > >
> > > > The _id != 0 expression is incorrect. The purpose was to check whether
> > > > the trace event is currently enabled (i.e. dynamically at runtime).
> > >
> > > The expression is correct, but the function and argument names are not. It
> > > should be
> > >
> > > fn trace_event_state_is_enabled(dstate: u16) -> bool {
> > > unsafe { trace_events_enabled_count } != 0 && dstate != 0
> > > }
> > >
> > > > > + # static state
> > > > > + for e in events:
> > > > > + if 'disable' in e.properties:
> > > > > + enabled = "false"
> > > > > + else:
> > > > > + enabled = "true"
> > > >
> > > > What is the purpose of this loop? The variable enabled is unused so I
> > > > think it can be deleted.
> > >
> > > The Rust code generator is not emitting any code for disabled tracepoints.
> > > Unlike C, where the disabled tracepoints can produce e.g. -Wformat warnings,
> > > there's no real benefit here.
> > >
> > > In the RFC the "enabled" variable was used to produce a const for the static
> > > state; it had no user so I removed it, but I left behind this dead Python
> > > code. Sorry about that!
> >
> > Is the concept of build time 'disabled' tracepoints actually useful to
> > still support ? AFAICT we use it in only places, which doesn't make it
> > sound too compelling:
> >
> > $ find -name trace-events | xargs grep '^disable'
> > ./target/hppa/trace-events:disable hppa_tlb_flush_ent(void *env, void *ent, uint64_t va_b, uint64_t va_e, uint64_t pa) "env=%p ent=%p va_b=0x%lx va_e=0x%lx pa=0x%lx"
> > ./target/hppa/trace-events:disable hppa_tlb_find_entry(void *env, void *ent, int valid, uint64_t va_b, uint64_t va_e, uint64_t pa) "env=%p ent=%p valid=%d va_b=0x%lx va_e=0x%lx pa=0x%lx"
> > ./target/hppa/trace-events:disable hppa_tlb_find_entry_not_found(void *env, uint64_t addr) "env=%p addr=%08lx"
> > ...snip...
> > ./target/hppa/trace-events:disable hppa_tlb_lpa_success(void *env, uint64_t addr, uint64_t phys) "env=%p addr=0x%lx phys=0x%lx"
> > ./target/hppa/trace-events:disable hppa_tlb_lpa_failed(void *env, uint64_t addr) "env=%p addr=0x%lx"
> > ./target/hppa/trace-events:disable hppa_tlb_probe(uint64_t addr, int level, int want) "addr=0x%lx level=%d want=%d"
> > ./hw/display/trace-events:disable qxl_io_write_vga(int qid, const char *mode, uint32_t addr, uint32_t val) "%d %s addr=%u val=%u"
>
> My recollection is that disabled events were supposed to eliminate the
> cost of trace events. Downstreams could disable trace events that they
> didn't need.
IMHO if that is a required use case, then the dtrace backend is the
answer.
The main premise of tracing is that you can rarely predict what info
will be needed ahead of time, so you need runtime controls. dtrace
gives that with near zero overhead, while QEMU's other backends have
that at the cost of a branch to check the enabled state. Disabling
events at build time feels at odds with the intended use case of
tracing.
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH 08/16] tracetool: Add Rust format support
2025-09-24 7:13 ` Paolo Bonzini
2025-09-24 7:50 ` Daniel P. Berrangé
@ 2025-09-24 18:10 ` Stefan Hajnoczi
2025-09-24 19:58 ` Paolo Bonzini
1 sibling, 1 reply; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-24 18:10 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P. Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 1651 bytes --]
On Wed, Sep 24, 2025 at 09:13:15AM +0200, Paolo Bonzini wrote:
> On 9/23/25 21:23, Stefan Hajnoczi wrote:
> > > + 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_get_state_dynamic_by_id(_id: u16) -> bool {',
> > > + ' unsafe { (trace_events_enabled_count != 0) && (_id != 0) }',
> > > + '}',
> >
> > This was translated to Rust from:
> >
> > /* it's on fast path, avoid consistency checks (asserts) */
> > #define trace_event_get_state_dynamic_by_id(id) \
> > (unlikely(trace_events_enabled_count) && _ ## id ## _DSTATE)
> >
> > The _id != 0 expression is incorrect. The purpose was to check whether
> > the trace event is currently enabled (i.e. dynamically at runtime).
>
> The expression is correct, but the function and argument names are not. It
> should be
>
> fn trace_event_state_is_enabled(dstate: u16) -> bool {
> unsafe { trace_events_enabled_count } != 0 && dstate != 0
> }
The generated code is missing DTrace's SDT semaphore (see
generate_h_backend_dstate() in scripts/tracetool/backend/dtrace.py). The
conditional must be taken when a tool like SystemTap or GDB sets the SDT
semaphore. Right now it will not be taken because the conditional only
looks at _ ## id ## _DSTATE and not the SDT semaphore.
Stefan
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread* Re: [PATCH 08/16] tracetool: Add Rust format support
2025-09-24 18:10 ` Stefan Hajnoczi
@ 2025-09-24 19:58 ` Paolo Bonzini
2025-09-25 11:50 ` Stefan Hajnoczi
0 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-24 19:58 UTC (permalink / raw)
To: Stefan Hajnoczi
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P. Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 739 bytes --]
On Wed, Sep 24, 2025, 20:10 Stefan Hajnoczi <stefanha@redhat.com> wrote:
> > fn trace_event_state_is_enabled(dstate: u16) -> bool {
> > unsafe { trace_events_enabled_count } != 0 && dstate != 0
> > }
>
> The generated code is missing DTrace's SDT semaphore (see
> generate_h_backend_dstate() in scripts/tracetool/backend/dtrace.py). The
> conditional must be taken when a tool like SystemTap or GDB sets the SDT
> semaphore. Right now it will not be taken because the conditional only
> looks at _ ## id ## _DSTATE and not the SDT semaphore.
>
This is private code to trace-*.rs, for use within the tracepoint functions
only; it's not a public "is the tracepoint active" API. The public side in
C does look at the semaphore.
Paolo
[-- Attachment #2: Type: text/html, Size: 1207 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread* Re: [PATCH 08/16] tracetool: Add Rust format support
2025-09-24 19:58 ` Paolo Bonzini
@ 2025-09-25 11:50 ` Stefan Hajnoczi
2025-09-25 12:38 ` Paolo Bonzini
0 siblings, 1 reply; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-25 11:50 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P. Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 920 bytes --]
On Wed, Sep 24, 2025 at 09:58:04PM +0200, Paolo Bonzini wrote:
> On Wed, Sep 24, 2025, 20:10 Stefan Hajnoczi <stefanha@redhat.com> wrote:
>
> > > fn trace_event_state_is_enabled(dstate: u16) -> bool {
> > > unsafe { trace_events_enabled_count } != 0 && dstate != 0
> > > }
> >
> > The generated code is missing DTrace's SDT semaphore (see
> > generate_h_backend_dstate() in scripts/tracetool/backend/dtrace.py). The
> > conditional must be taken when a tool like SystemTap or GDB sets the SDT
> > semaphore. Right now it will not be taken because the conditional only
> > looks at _ ## id ## _DSTATE and not the SDT semaphore.
> >
>
> This is private code to trace-*.rs, for use within the tracepoint functions
> only; it's not a public "is the tracepoint active" API. The public side in
> C does look at the semaphore.
You're right, the code is fine just with the function renamed.
Stefan
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread* Re: [PATCH 08/16] tracetool: Add Rust format support
2025-09-25 11:50 ` Stefan Hajnoczi
@ 2025-09-25 12:38 ` Paolo Bonzini
2025-09-25 15:09 ` Stefan Hajnoczi
0 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-25 12:38 UTC (permalink / raw)
To: Stefan Hajnoczi
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P. Berrangé, Mads Ynddal
On 9/25/25 13:50, Stefan Hajnoczi wrote:
> On Wed, Sep 24, 2025 at 09:58:04PM +0200, Paolo Bonzini wrote:
>> On Wed, Sep 24, 2025, 20:10 Stefan Hajnoczi <stefanha@redhat.com> wrote:
>>
>>>> fn trace_event_state_is_enabled(dstate: u16) -> bool {
>>>> unsafe { trace_events_enabled_count } != 0 && dstate != 0
>>>> }
>>>
>>> The generated code is missing DTrace's SDT semaphore (see
>>> generate_h_backend_dstate() in scripts/tracetool/backend/dtrace.py). The
>>> conditional must be taken when a tool like SystemTap or GDB sets the SDT
>>> semaphore. Right now it will not be taken because the conditional only
>>> looks at _ ## id ## _DSTATE and not the SDT semaphore.
>>>
>>
>> This is private code to trace-*.rs, for use within the tracepoint functions
>> only; it's not a public "is the tracepoint active" API. The public side in
>> C does look at the semaphore.
>
> You're right, the code is fine just with the function renamed.
No problem---in fact I have now realized that, for systemtap, I have to
ensure that the semaphore is shared between C and Rust!
Paolo
^ permalink raw reply [flat|nested] 42+ messages in thread* Re: [PATCH 08/16] tracetool: Add Rust format support
2025-09-25 12:38 ` Paolo Bonzini
@ 2025-09-25 15:09 ` Stefan Hajnoczi
2025-09-25 15:37 ` Paolo Bonzini
0 siblings, 1 reply; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-25 15:09 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Stefan Hajnoczi, qemu-devel, Tanish Desai, Zhao Liu,
Manos Pitsidianakis, Daniel P. Berrangé, Mads Ynddal
On Thu, Sep 25, 2025 at 8:40 AM Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> On 9/25/25 13:50, Stefan Hajnoczi wrote:
> > On Wed, Sep 24, 2025 at 09:58:04PM +0200, Paolo Bonzini wrote:
> >> On Wed, Sep 24, 2025, 20:10 Stefan Hajnoczi <stefanha@redhat.com> wrote:
> >>
> >>>> fn trace_event_state_is_enabled(dstate: u16) -> bool {
> >>>> unsafe { trace_events_enabled_count } != 0 && dstate != 0
> >>>> }
> >>>
> >>> The generated code is missing DTrace's SDT semaphore (see
> >>> generate_h_backend_dstate() in scripts/tracetool/backend/dtrace.py). The
> >>> conditional must be taken when a tool like SystemTap or GDB sets the SDT
> >>> semaphore. Right now it will not be taken because the conditional only
> >>> looks at _ ## id ## _DSTATE and not the SDT semaphore.
> >>>
> >>
> >> This is private code to trace-*.rs, for use within the tracepoint functions
> >> only; it's not a public "is the tracepoint active" API. The public side in
> >> C does look at the semaphore.
> >
> > You're right, the code is fine just with the function renamed.
>
> No problem---in fact I have now realized that, for systemtap, I have to
> ensure that the semaphore is shared between C and Rust!
Is anyone working on the DTrace support? If not, I'll keep it in mind
in case I get some time over the next few weeks.
Stefan
^ permalink raw reply [flat|nested] 42+ messages in thread* Re: [PATCH 08/16] tracetool: Add Rust format support
2025-09-25 15:09 ` Stefan Hajnoczi
@ 2025-09-25 15:37 ` Paolo Bonzini
2025-09-25 17:16 ` Stefan Hajnoczi
0 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-25 15:37 UTC (permalink / raw)
To: Stefan Hajnoczi
Cc: Stefan Hajnoczi, qemu-devel, Tanish Desai, Zhao Liu,
Manos Pitsidianakis, Daniel P. Berrangé, Mads Ynddal
On 9/25/25 17:09, Stefan Hajnoczi wrote:
> On Thu, Sep 25, 2025 at 8:40 AM Paolo Bonzini <pbonzini@redhat.com> wrote:
>> No problem---in fact I have now realized that, for systemtap, I have to
>> ensure that the semaphore is shared between C and Rust!
>
> Is anyone working on the DTrace support? If not, I'll keep it in mind
> in case I get some time over the next few weeks.
No, the plan was to use the probe-rs crate, which is almost trivial
except that it does not support the shared semaphore.
For the shared semaphore probe-rs needs modifications. It's also
possible to just import its single file with magic asm[1] into QEMU's
trace crate and modify it as needed; and contribute the changes upstream
later.
There is also the usdt crate, which recently grew support for systemtap
SDT as well. It takes a much more complex approach and has many
dependencies, as it almost completely reimplements the dtrace compiler.
It may be interesting for the future since it is more portable, but for
the time being I'd stick with the lower-level probe-rs.
Paolo
[1]
https://github.com/bonzini/probe-rs/blob/extern-semaphore/src/platform/systemtap.rs
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH 08/16] tracetool: Add Rust format support
2025-09-25 15:37 ` Paolo Bonzini
@ 2025-09-25 17:16 ` Stefan Hajnoczi
0 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-25 17:16 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Stefan Hajnoczi, qemu-devel, Tanish Desai, Zhao Liu,
Manos Pitsidianakis, Daniel P. Berrangé, Mads Ynddal
On Thu, Sep 25, 2025 at 11:37 AM Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> On 9/25/25 17:09, Stefan Hajnoczi wrote:
> > On Thu, Sep 25, 2025 at 8:40 AM Paolo Bonzini <pbonzini@redhat.com> wrote:
> >> No problem---in fact I have now realized that, for systemtap, I have to
> >> ensure that the semaphore is shared between C and Rust!
> >
> > Is anyone working on the DTrace support? If not, I'll keep it in mind
> > in case I get some time over the next few weeks.
> No, the plan was to use the probe-rs crate, which is almost trivial
> except that it does not support the shared semaphore.
>
> For the shared semaphore probe-rs needs modifications. It's also
> possible to just import its single file with magic asm[1] into QEMU's
> trace crate and modify it as needed; and contribute the changes upstream
> later.
>
> There is also the usdt crate, which recently grew support for systemtap
> SDT as well. It takes a much more complex approach and has many
> dependencies, as it almost completely reimplements the dtrace compiler.
> It may be interesting for the future since it is more portable, but for
> the time being I'd stick with the lower-level probe-rs.
Okay, thanks for the link to your semaphore changes. I should be able
to play with it at the end of next week.
Stefan
>
> Paolo
>
> [1]
> https://github.com/bonzini/probe-rs/blob/extern-semaphore/src/platform/systemtap.rs
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 09/16] rust: add trace crate
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (7 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 08/16] tracetool: Add Rust format support Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-23 19:29 ` Stefan Hajnoczi
2025-09-19 11:25 ` [PATCH 10/16] rust: qdev: add minimal clock bindings Paolo Bonzini
` (7 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
From: Tanish Desai <tanishdesai37@gmail.com>
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.
Signed-off-by: Tanish Desai <tanishdesai37@gmail.com>
[Write commit message, add #[allow()]. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 8315f98c46f..3428dbaf0b3 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 d8183c614d4..f372d7dbf70 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 b3ac3a71970..695d5a62de9 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 00000000000..13ac0b33d6f
--- /dev/null
+++ b/rust/trace/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "trace"
+version = "0.1.0"
+authors = ["Tanish Desai <tanishdesai37@gmail.com>"]
+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 00000000000..adca57e5507
--- /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 00000000000..0955461573d
--- /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 9c42a57a053..d89a0db82a1 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'),
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [PATCH 09/16] rust: add trace crate
2025-09-19 11:25 ` [PATCH 09/16] rust: add trace crate Paolo Bonzini
@ 2025-09-23 19:29 ` Stefan Hajnoczi
0 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:29 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 1134 bytes --]
On Fri, Sep 19, 2025 at 01:25:29PM +0200, Paolo Bonzini wrote:
> From: Tanish Desai <tanishdesai37@gmail.com>
>
> 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.
>
> Signed-off-by: Tanish Desai <tanishdesai37@gmail.com>
> [Write commit message, add #[allow()]. - Paolo]
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> 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
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 10/16] rust: qdev: add minimal clock bindings
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (8 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 09/16] rust: add trace crate Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-23 19:31 ` Stefan Hajnoczi
2025-09-19 11:25 ` [PATCH 11/16] rust: pl011: add tracepoints Paolo Bonzini
` (6 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
Add the minimal support that is needed by pl011's event and tracepoint.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 71b9ef141c3..e384cad4d26 100644
--- a/rust/hw/core/src/qdev.rs
+++ b/rust/hw/core/src/qdev.rs
@@ -448,6 +448,39 @@ fn init_gpio_out(&self, pins: &[InterruptSource]) {
impl<R: ObjectDeref> DeviceMethods for R where R::Target: IsA<DeviceState> {}
+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 =
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [PATCH 10/16] rust: qdev: add minimal clock bindings
2025-09-19 11:25 ` [PATCH 10/16] rust: qdev: add minimal clock bindings Paolo Bonzini
@ 2025-09-23 19:31 ` Stefan Hajnoczi
0 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:31 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 410 bytes --]
On Fri, Sep 19, 2025 at 01:25:30PM +0200, Paolo Bonzini wrote:
> Add the minimal support that is needed by pl011's event and tracepoint.
>
> Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> rust/hw/core/src/qdev.rs | 33 +++++++++++++++++++++++++++++++++
> 1 file changed, 33 insertions(+)
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 11/16] rust: pl011: add tracepoints
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (9 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 10/16] rust: qdev: add minimal clock bindings Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-23 19:04 ` Stefan Hajnoczi
2025-09-19 11:25 ` [PATCH 12/16] tracetool/simple: add Rust support Paolo Bonzini
` (5 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
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. :)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 05a33036c12..9e74be2c14f 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 3428dbaf0b3..f84a3dd0764 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 b2418abc4bf..dc41d0e499e 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 ffdc8af53f1..ed28b158add 100644
--- a/rust/hw/char/pl011/meson.build
+++ b/rust/hw/char/pl011/meson.build
@@ -39,6 +39,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 1b4587d5f60..8889d6e54fb 100644
--- a/rust/hw/char/pl011/src/device.rs
+++ b/rust/hw/char/pl011/src/device.rs
@@ -21,6 +21,8 @@
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 @@ pub(self) fn read(&mut self, offset: RegisterOffset) -> (bool, u32) {
(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 @@ pub(self) fn write(
}
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 @@ pub(self) fn write(
}
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 @@ pub(self) fn write(
}
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 @@ fn read_data_register(&mut self, update: &mut bool) -> u32 {
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 @@ pub fn fifo_rx_put(&mut self, value: registers::Data) -> bool {
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 @@ unsafe fn init(mut this: ParentInit<Self>) {
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 @@ fn read(&self, offset: hwaddr, _size: u32) -> u64 {
}
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 @@ fn write(&self, offset: hwaddr, value: u64, _size: u32) {
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 @@ fn write(&self, offset: hwaddr, value: u64, _size: u32) {
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 @@ fn write(&self, offset: hwaddr, value: u64, _size: u32) {
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 @@ fn reset_hold(&self, _type: ResetType) {
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));
}
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [PATCH 11/16] rust: pl011: add tracepoints
2025-09-19 11:25 ` [PATCH 11/16] rust: pl011: add tracepoints Paolo Bonzini
@ 2025-09-23 19:04 ` Stefan Hajnoczi
0 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:04 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 665 bytes --]
On Fri, Sep 19, 2025 at 01:25:31PM +0200, Paolo Bonzini wrote:
> 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. :)
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> 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(-)
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 12/16] tracetool/simple: add Rust support
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (10 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 11/16] rust: pl011: add tracepoints Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-23 19:35 ` Stefan Hajnoczi
2025-09-19 11:25 ` [PATCH 13/16] log: change qemu_loglevel to unsigned Paolo Bonzini
` (4 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
From: Tanish Desai <tanishdesai37@gmail.com>
Signed-off-by: Tanish Desai <tanishdesai37@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 b5a6b7205a3..b131e4fc194 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 00000000000..73f75e04dc7
--- /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_get_state_dynamic_by_id(_id: u16) -> bool {
+ unsafe { (trace_events_enabled_count != 0) && (_id != 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_get_state_dynamic_by_id(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_get_state_dynamic_by_id(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 65430fdedc1..3e37890476d 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",
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [PATCH 12/16] tracetool/simple: add Rust support
2025-09-19 11:25 ` [PATCH 12/16] tracetool/simple: add Rust support Paolo Bonzini
@ 2025-09-23 19:35 ` Stefan Hajnoczi
0 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:35 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 549 bytes --]
On Fri, Sep 19, 2025 at 01:25:32PM +0200, Paolo Bonzini wrote:
> From: Tanish Desai <tanishdesai37@gmail.com>
>
> Signed-off-by: Tanish Desai <tanishdesai37@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> 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
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 13/16] log: change qemu_loglevel to unsigned
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (11 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 12/16] tracetool/simple: add Rust support Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-23 19:06 ` Stefan Hajnoczi
2025-09-19 11:25 ` [PATCH 14/16] tracetool/log: add Rust support Paolo Bonzini
` (3 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal,
Philippe Mathieu-Daudé
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 <manos.pitsidianakis@linaro.org>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qemu/log-for-trace.h | 4 ++--
include/qemu/log.h | 44 ++++++++++++++++++------------------
util/log.c | 2 +-
rust/util/src/log.rs | 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 d47c9cd4462..f3a8791f1d4 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 aae72985f0d..7effba4da4c 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/util/log.c b/util/log.c
index abdcb6b3111..41f78ce86b2 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;
diff --git a/rust/util/src/log.rs b/rust/util/src/log.rs
index af9a3e91234..0a4bc4249a1 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)*)));
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [PATCH 13/16] log: change qemu_loglevel to unsigned
2025-09-19 11:25 ` [PATCH 13/16] log: change qemu_loglevel to unsigned Paolo Bonzini
@ 2025-09-23 19:06 ` Stefan Hajnoczi
0 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:06 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal,
Philippe Mathieu-Daudé
[-- Attachment #1: Type: text/plain, Size: 879 bytes --]
On Fri, Sep 19, 2025 at 01:25:33PM +0200, Paolo Bonzini wrote:
> 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 <manos.pitsidianakis@linaro.org>
> Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> include/qemu/log-for-trace.h | 4 ++--
> include/qemu/log.h | 44 ++++++++++++++++++------------------
> util/log.c | 2 +-
> rust/util/src/log.rs | 2 +-
> 4 files changed, 26 insertions(+), 26 deletions(-)
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 14/16] tracetool/log: add Rust support
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (12 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 13/16] log: change qemu_loglevel to unsigned Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-23 19:36 ` Stefan Hajnoczi
2025-09-19 11:25 ` [PATCH 15/16] tracetool/ftrace: " Paolo Bonzini
` (2 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
From: Tanish Desai <tanishdesai37@gmail.com>
Signed-off-by: Tanish Desai <tanishdesai37@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 d01d234289f..9e3e5046f5f 100644
--- a/scripts/tracetool/backend/log.py
+++ b/scripts/tracetool/backend/log.py
@@ -12,7 +12,7 @@
__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 00000000000..8b93aaa367f
--- /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_get_state_dynamic_by_id(_id: u16) -> bool {
+ unsafe { (trace_events_enabled_count != 0) && (_id != 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_get_state_dynamic_by_id(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_get_state_dynamic_by_id(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 3e37890476d..f58f3b795e7 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 += [
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [PATCH 14/16] tracetool/log: add Rust support
2025-09-19 11:25 ` [PATCH 14/16] tracetool/log: add Rust support Paolo Bonzini
@ 2025-09-23 19:36 ` Stefan Hajnoczi
0 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:36 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 560 bytes --]
On Fri, Sep 19, 2025 at 01:25:34PM +0200, Paolo Bonzini wrote:
> From: Tanish Desai <tanishdesai37@gmail.com>
>
> Signed-off-by: Tanish Desai <tanishdesai37@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> 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
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 15/16] tracetool/ftrace: add Rust support
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (13 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 14/16] tracetool/log: add Rust support Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-23 19:36 ` Stefan Hajnoczi
2025-09-19 11:25 ` [PATCH 16/16] tracetool/syslog: " Paolo Bonzini
2025-09-23 19:43 ` [PATCH 00/16] tracetool: " Stefan Hajnoczi
16 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
From: Tanish Desai <tanishdesai37@gmail.com>
Signed-off-by: Tanish Desai <tanishdesai37@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 7ddd5d11a66..e03698a2edf 100644
--- a/scripts/tracetool/backend/ftrace.py
+++ b/scripts/tracetool/backend/ftrace.py
@@ -12,7 +12,7 @@
__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 00000000000..7811056f673
--- /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_get_state_dynamic_by_id(_id: u16) -> bool {
+ unsafe { (trace_events_enabled_count != 0) && (_id != 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_get_state_dynamic_by_id(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_get_state_dynamic_by_id(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 f58f3b795e7..3341fb18f90 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 += [
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [PATCH 15/16] tracetool/ftrace: add Rust support
2025-09-19 11:25 ` [PATCH 15/16] tracetool/ftrace: " Paolo Bonzini
@ 2025-09-23 19:36 ` Stefan Hajnoczi
0 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:36 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 566 bytes --]
On Fri, Sep 19, 2025 at 01:25:35PM +0200, Paolo Bonzini wrote:
> From: Tanish Desai <tanishdesai37@gmail.com>
>
> Signed-off-by: Tanish Desai <tanishdesai37@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> 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
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 16/16] tracetool/syslog: add Rust support
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (14 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 15/16] tracetool/ftrace: " Paolo Bonzini
@ 2025-09-19 11:25 ` Paolo Bonzini
2025-09-23 19:37 ` Stefan Hajnoczi
2025-09-23 19:43 ` [PATCH 00/16] tracetool: " Stefan Hajnoczi
16 siblings, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2025-09-19 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Tanish Desai, Zhao Liu, Stefan Hajnoczi, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
From: Tanish Desai <tanishdesai37@gmail.com>
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 <tanishdesai37@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 f84a3dd0764..444ef516a70 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 13ac0b33d6f..fc81bce5803 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 0955461573d..e03bce43c47 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 177414d56a6..12b826593db 100644
--- a/scripts/tracetool/backend/syslog.py
+++ b/scripts/tracetool/backend/syslog.py
@@ -12,7 +12,7 @@
__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 00000000000..15160e4c7c0
--- /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_get_state_dynamic_by_id(_id: u16) -> bool {
+ unsafe { (trace_events_enabled_count != 0) && (_id != 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_get_state_dynamic_by_id(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_get_state_dynamic_by_id(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 3341fb18f90..786083ad7fb 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 += [
--
2.51.0
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [PATCH 16/16] tracetool/syslog: add Rust support
2025-09-19 11:25 ` [PATCH 16/16] tracetool/syslog: " Paolo Bonzini
@ 2025-09-23 19:37 ` Stefan Hajnoczi
0 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:37 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 984 bytes --]
On Fri, Sep 19, 2025 at 01:25:36PM +0200, Paolo Bonzini wrote:
> From: Tanish Desai <tanishdesai37@gmail.com>
>
> 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 <tanishdesai37@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> 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
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH 00/16] tracetool: add Rust support
2025-09-19 11:25 [PATCH 00/16] tracetool: add Rust support Paolo Bonzini
` (15 preceding siblings ...)
2025-09-19 11:25 ` [PATCH 16/16] tracetool/syslog: " Paolo Bonzini
@ 2025-09-23 19:43 ` Stefan Hajnoczi
16 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2025-09-23 19:43 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Tanish Desai, Zhao Liu, Manos Pitsidianakis,
Daniel P . Berrangé, Mads Ynddal
[-- Attachment #1: Type: text/plain, Size: 7467 bytes --]
On Fri, Sep 19, 2025 at 01:25:20PM +0200, Paolo Bonzini wrote:
> This is the result of the summer project of Tanish Desai. It mostly
> consists of changes to tracetool, which I used to add tracepoint support
> to the pl011 device. All the backends are supported except dtrace and
> ust; support for Linux in dtrace should be easy using the "probe" crate,
> the rest (ust, and dtrace on macOS or Solaris) less so. For ust, the
> plan is to deprecate it, since LTTng can use uprobes. For dtrace on
> macOS or Solaris, support would have to be added to the "probe" crate.
>
> Patches 1-5 are cleanups that could be committed separately.
>
> Patches 6-7 are tracetool patches that have been posted before, now
> rebased on top of the "make check-tracetool" series. Their purpose
> is to simplify .h code generation for tracetool backends, and these
> simplifications translate directly to the new .rs code generation.
>
> Patches 8-9 add the minimal support for adding tracepoint functions
> in Rust, albeit with no content and thus no actual tracing.
>
> Patches 10-11 add back tracepoints to the Rust pl011 device model.
>
> Patches 12-16 finally add Rust code generation to the supported
> tracing backends.
>
> The tracetool testsuite is now part of QEMU and is extended to
> cover the generated Rust code.
Looks very close. The main issue I noticed in the Rust code is that the
dynamic state of trace events is not being checked correctly
(trace_event_get_state_dynamic_by_id()).
>
> Paolo
>
> v1->v2:
> - new patch "tracetool: fix usage of try_import()"
> - new patch "tracetool: remove dead code" [Manos]
> - new patch "treewide: remove unnessary "coding" header" [Manos]
> - new patch "tracetool: add SPDX headers" [Manos]
> - dropped patch "treewide: write "unsigned long int" instead of "long unsigned int""
> - merge patch "rust: move dependencies to rust/Cargo.toml"
> - gathered Reviewed-by tags
> - sort keywords for primitive C types [Manos]
> - fix incorrect string "_{name}" in "tracetool: Add Rust format support" [Manos, Daniel]
> - adjust for moved crates
> - add SPDX headers to generated file [Daniel]
> - add @generated tag to generated file [Manos]
> - add #[allow()] to include_trace macro, in order to pacify clippy
> - tweaks to trace/Cargo.toml [Manos]
> - fix more clippy issues in generated code
> - change include_trace! macro to not require the "trace-" prefix [Zhao]
> - rename Clock::get() and get_hz() methods to period() and hz() respectively [Zhao]
> - drop the "..._ENABLED" symbols [Daniel]
>
> Paolo Bonzini (8):
> tracetool: fix usage of try_import()
> tracetool: remove dead code
> treewide: remove unnessary "coding" header
> tracetool: add SPDX headers
> trace/ftrace: move snprintf+write from tracepoints to ftrace.c
> rust: qdev: add minimal clock bindings
> rust: pl011: add tracepoints
> log: change qemu_loglevel to unsigned
>
> Tanish Desai (8):
> tracetool: add CHECK_TRACE_EVENT_GET_STATE
> tracetool/backend: remove redundant trace event checks
> tracetool: Add Rust format support
> rust: add trace crate
> tracetool/simple: add Rust support
> tracetool/log: add Rust support
> tracetool/ftrace: add Rust support
> tracetool/syslog: add Rust support
>
> docs/conf.py | 2 -
> docs/sphinx-static/theme_overrides.css | 3 +-
> include/qemu/log-for-trace.h | 4 +-
> include/qemu/log.h | 44 ++--
> tests/tracetool/ftrace.h | 28 +--
> tests/tracetool/log.h | 16 +-
> trace/ftrace.h | 1 +
> trace/ftrace.c | 15 ++
> util/log.c | 2 +-
> hw/char/trace-events | 14 +-
> rust/Cargo.lock | 8 +
> rust/Cargo.toml | 1 +
> rust/hw/char/pl011/Cargo.toml | 1 +
> rust/hw/char/pl011/meson.build | 1 +
> rust/hw/char/pl011/src/device.rs | 57 +++--
> rust/hw/core/src/qdev.rs | 33 +++
> rust/meson.build | 2 +-
> rust/trace/Cargo.toml | 19 ++
> rust/trace/meson.build | 19 ++
> rust/trace/src/lib.rs | 39 ++++
> rust/util/src/log.rs | 2 +-
> 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 -
> .../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 | 201 ++++++++++++++----
> scripts/tracetool/backend/__init__.py | 43 ++--
> scripts/tracetool/backend/dtrace.py | 2 +-
> scripts/tracetool/backend/ftrace.py | 26 +--
> scripts/tracetool/backend/log.py | 22 +-
> scripts/tracetool/backend/simple.py | 17 +-
> scripts/tracetool/backend/syslog.py | 17 +-
> scripts/tracetool/backend/ust.py | 2 +-
> scripts/tracetool/format/__init__.py | 4 +-
> scripts/tracetool/format/c.py | 2 +-
> scripts/tracetool/format/d.py | 2 +-
> scripts/tracetool/format/h.py | 18 +-
> scripts/tracetool/format/log_stap.py | 2 +-
> scripts/tracetool/format/rs.py | 71 +++++++
> 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 +-
> tests/tracetool/ftrace.rs | 40 ++++
> tests/tracetool/log.rs | 44 ++++
> tests/tracetool/simple.rs | 40 ++++
> tests/tracetool/syslog.rs | 40 ++++
> tests/tracetool/tracetool-test.py | 2 +
> trace/meson.build | 8 +-
> 62 files changed, 727 insertions(+), 218 deletions(-)
> create mode 100644 rust/trace/Cargo.toml
> create mode 100644 rust/trace/meson.build
> create mode 100644 rust/trace/src/lib.rs
> create mode 100644 scripts/tracetool/format/rs.py
> create mode 100644 tests/tracetool/ftrace.rs
> create mode 100644 tests/tracetool/log.rs
> create mode 100644 tests/tracetool/simple.rs
> create mode 100644 tests/tracetool/syslog.rs
>
> --
> 2.51.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread