* [PATCH 0/2] Initial logging support for Rust @ 2025-03-30 20:58 Bernhard Beschow 2025-03-30 20:58 ` [PATCH 1/2] rust/qemu-api: Add initial logging support based on C API Bernhard Beschow 2025-03-30 20:58 ` [PATCH 2/2] rust/hw/char/pl011/src/device: Implement logging Bernhard Beschow 0 siblings, 2 replies; 18+ messages in thread From: Bernhard Beschow @ 2025-03-30 20:58 UTC (permalink / raw) To: qemu-devel Cc: Manos Pitsidianakis, qemu-rust, Paolo Bonzini, Bernhard Beschow This series introduces a qemu_log_mask!() macro which works similar to the C version while catering to Rust expectations. It is just a thin wrapper around qemu_log(). The macro then gets used in the pl011 device which either had its logging commented out or relied on eprintln!() which can't be silenced by users. Note that this is my first Rust contribution, so please check if the usage of `unsafe` is sound. Bernhard Beschow (2): rust/qemu-api: Add initial logging support based on C API rust/hw/char/pl011/src/device: Implement logging docs/devel/rust.rst | 1 + rust/wrapper.h | 2 ++ rust/hw/char/pl011/src/device.rs | 12 ++++--- rust/qemu-api/meson.build | 1 + rust/qemu-api/src/lib.rs | 1 + rust/qemu-api/src/log.rs | 55 ++++++++++++++++++++++++++++++++ 6 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 rust/qemu-api/src/log.rs -- 2.49.0 ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/2] rust/qemu-api: Add initial logging support based on C API 2025-03-30 20:58 [PATCH 0/2] Initial logging support for Rust Bernhard Beschow @ 2025-03-30 20:58 ` Bernhard Beschow 2025-03-31 9:53 ` Paolo Bonzini 2025-03-30 20:58 ` [PATCH 2/2] rust/hw/char/pl011/src/device: Implement logging Bernhard Beschow 1 sibling, 1 reply; 18+ messages in thread From: Bernhard Beschow @ 2025-03-30 20:58 UTC (permalink / raw) To: qemu-devel Cc: Manos Pitsidianakis, qemu-rust, Paolo Bonzini, Bernhard Beschow A qemu_log_mask!() macro is provided which expects similar arguments as the C version. However, the formatting works as one would expect from Rust. To maximize code reuse the macro is just a thin wrapper around qemu_log(). Also, just the bare minimum of logging masks is provided which should suffice for the current use case of Rust in QEMU. Signed-off-by: Bernhard Beschow <shentey@gmail.com> --- docs/devel/rust.rst | 1 + rust/wrapper.h | 2 ++ rust/qemu-api/meson.build | 1 + rust/qemu-api/src/lib.rs | 1 + rust/qemu-api/src/log.rs | 55 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 60 insertions(+) create mode 100644 rust/qemu-api/src/log.rs diff --git a/docs/devel/rust.rst b/docs/devel/rust.rst index 88bdec1eb2..bc50216dc6 100644 --- a/docs/devel/rust.rst +++ b/docs/devel/rust.rst @@ -187,6 +187,7 @@ module status ``c_str`` complete ``errno`` complete ``irq`` complete +``log`` proof of concept ``memory`` stable ``module`` complete ``offset_of`` stable diff --git a/rust/wrapper.h b/rust/wrapper.h index d4fec54657..9518face53 100644 --- a/rust/wrapper.h +++ b/rust/wrapper.h @@ -48,6 +48,8 @@ typedef enum memory_order { #endif /* __CLANG_STDATOMIC_H */ #include "qemu/osdep.h" +#include "qemu/log.h" +#include "qemu/log-for-trace.h" #include "qemu/module.h" #include "qemu-io.h" #include "system/system.h" diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build index 858685ddd4..112f6735a9 100644 --- a/rust/qemu-api/meson.build +++ b/rust/qemu-api/meson.build @@ -26,6 +26,7 @@ _qemu_api_rs = static_library( 'src/c_str.rs', 'src/errno.rs', 'src/irq.rs', + 'src/log.rs', 'src/memory.rs', 'src/module.rs', 'src/offset_of.rs', diff --git a/rust/qemu-api/src/lib.rs b/rust/qemu-api/src/lib.rs index 05f38b51d3..b54989a243 100644 --- a/rust/qemu-api/src/lib.rs +++ b/rust/qemu-api/src/lib.rs @@ -21,6 +21,7 @@ pub mod chardev; pub mod errno; pub mod irq; +pub mod log; pub mod memory; pub mod module; pub mod offset_of; diff --git a/rust/qemu-api/src/log.rs b/rust/qemu-api/src/log.rs new file mode 100644 index 0000000000..3103a86efa --- /dev/null +++ b/rust/qemu-api/src/log.rs @@ -0,0 +1,55 @@ +// Copyright 2025 Bernhard Beschow <shentey@gmail.com> +// SPDX-License-Identifier: GPL-2.0-or-later + +pub use crate::bindings::{LOG_GUEST_ERROR, LOG_INVALID_MEM, LOG_UNIMP}; + +/// A macro to log messages conditionally based on a provided mask. +/// +/// The `qemu_log_mask` macro checks whether the given mask matches the +/// current log level and, if so, formats and logs the message. +/// +/// # Parameters +/// +/// - `$mask`: The log mask to check. This should be an integer value +/// indicating the log level mask. +/// - `$fmt`: A format string following the syntax and rules of the `format!` +/// macro. It specifies the structure of the log message. +/// - `$args`: Optional arguments to be interpolated into the format string. +/// +/// # Example +/// +/// ``` +/// use qemu_api::log::LOG_GUEST_ERROR; +/// +/// qemu_log_mask!( +/// LOG_GUEST_ERROR, +/// "Address 0x{error_address:x} out of range\n" +/// ); +/// ``` +/// +/// It is also possible to use printf style: +/// +/// ``` +/// use qemu_api::log::LOG_GUEST_ERROR; +/// +/// qemu_log_mask!( +/// LOG_GUEST_ERROR, +/// "Address 0x{:x} out of range\n", +/// error_address +/// ); +/// ``` +#[macro_export] +macro_rules! qemu_log_mask { + ($mask:expr, $fmt:expr $(, $args:expr)*) => {{ + if unsafe { + (::qemu_api::bindings::qemu_loglevel & ($mask as std::os::raw::c_int)) != 0 + } { + let formatted_string = format!($fmt, $($args),*); + let c_string = std::ffi::CString::new(formatted_string).unwrap(); + + unsafe { + ::qemu_api::bindings::qemu_log(c_string.as_ptr()); + } + } + }}; +} -- 2.49.0 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 1/2] rust/qemu-api: Add initial logging support based on C API 2025-03-30 20:58 ` [PATCH 1/2] rust/qemu-api: Add initial logging support based on C API Bernhard Beschow @ 2025-03-31 9:53 ` Paolo Bonzini 2025-04-01 10:51 ` Bernhard Beschow 0 siblings, 1 reply; 18+ messages in thread From: Paolo Bonzini @ 2025-03-31 9:53 UTC (permalink / raw) To: Bernhard Beschow, qemu-devel; +Cc: Manos Pitsidianakis, qemu-rust On 3/30/25 22:58, Bernhard Beschow wrote: > A qemu_log_mask!() macro is provided which expects similar arguments as the C > version. However, the formatting works as one would expect from Rust. > > To maximize code reuse the macro is just a thin wrapper around qemu_log(). > Also, just the bare minimum of logging masks is provided which should suffice > for the current use case of Rust in QEMU. It's probably better to use an enum for this. One possibility is also to change the #defines to a C enum, and see which enum translation of the several allowed by bindgen is best. Also, while this is good for now, later on we probably want to reimplement logging at a lower level via the std::fmt::Write trait. But that's just for efficiency and your macro is indeed good enough to define what the API would look like. Right now I have a project for GSoC that will look at that, and the student can look into it later on. This means answering the following two questions: - the mapping the LOG_* constants into Rust - whether to keep the "qemu" prefix for the API (personal opinion: no) - whether it makes sense to add more macros such as log_guest_error! or log_unimp! for the most common LOG_* values > +#[macro_export] > +macro_rules! qemu_log_mask { > + ($mask:expr, $fmt:expr $(, $args:expr)*) => {{ Looking at https://doc.rust-lang.org/std/macro.write.html they just use $($arg:tt)* for what is passed to format_args! (or in your case format!), so we can do the same here too. The main advantage is that it allows giving a trailing comma to qemu_log_mask!. Paolo > + if unsafe { > + (::qemu_api::bindings::qemu_loglevel & ($mask as std::os::raw::c_int)) != 0 > + } { > + let formatted_string = format!($fmt, $($args),*); > + let c_string = std::ffi::CString::new(formatted_string).unwrap(); > + > + unsafe { > + ::qemu_api::bindings::qemu_log(c_string.as_ptr()); > + } > + } > + }}; > +} ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/2] rust/qemu-api: Add initial logging support based on C API 2025-03-31 9:53 ` Paolo Bonzini @ 2025-04-01 10:51 ` Bernhard Beschow 2025-04-08 20:58 ` Bernhard Beschow 0 siblings, 1 reply; 18+ messages in thread From: Bernhard Beschow @ 2025-04-01 10:51 UTC (permalink / raw) To: Paolo Bonzini, qemu-devel; +Cc: Manos Pitsidianakis, qemu-rust Am 31. März 2025 09:53:41 UTC schrieb Paolo Bonzini <pbonzini@redhat.com>: >On 3/30/25 22:58, Bernhard Beschow wrote: >> A qemu_log_mask!() macro is provided which expects similar arguments as the C >> version. However, the formatting works as one would expect from Rust. >> >> To maximize code reuse the macro is just a thin wrapper around qemu_log(). >> Also, just the bare minimum of logging masks is provided which should suffice >> for the current use case of Rust in QEMU. > >It's probably better to use an enum for this. One possibility is also to change the #defines to a C enum, and see which enum translation of the several allowed by bindgen is best. Currently the #defines contain some holes for "private" mask bits. Turning these into an enum without exposing all publicly, and changing the type of qemu_loglevel for consistency, would result in undefined behavior. Or do you suggest to convert just the public #defines into an enum to expose them to Rust, and keep the rest of the C API including the type of qemu_loglevel as is? There are surely several tradeoffs and/or cleanups possible here, but that's way beyond for what I wanted to achieve -- which is closing a gap between C and Rust. My main goal is just to get my feet wet with Rust. > >Also, while this is good for now, later on we probably want to reimplement logging at a lower level via the std::fmt::Write trait. But that's just for efficiency and your macro is indeed good enough to define what the API would look like. Can we live with an easy solution then for now? As you suggest below, further abstractions like log_guest_error! can be built on top which further insulates client code from implementation details such as the representation of the mask bits. > Right now I have a project for GSoC that will look at that, and the student can look into it later on. Whoops, I didn't intend to spoil the project. > >This means answering the following two questions: > >- the mapping the LOG_* constants into Rust > >- whether to keep the "qemu" prefix for the API (personal opinion: no) > >- whether it makes sense to add more macros such as log_guest_error! or log_unimp! for the most common LOG_* values > >> +#[macro_export] >> +macro_rules! qemu_log_mask { >> + ($mask:expr, $fmt:expr $(, $args:expr)*) => {{ > >Looking at https://doc.rust-lang.org/std/macro.write.html they just use $($arg:tt)* for what is passed to format_args! (or in your case format!), so we can do the same here too. The main advantage is that it allows giving a trailing comma to qemu_log_mask!. Easy to fix. Before proceeding I'd like to see a solution for the topic above. Best regards, Bernhard > >Paolo > >> + if unsafe { >> + (::qemu_api::bindings::qemu_loglevel & ($mask as std::os::raw::c_int)) != 0 >> + } { >> + let formatted_string = format!($fmt, $($args),*); >> + let c_string = std::ffi::CString::new(formatted_string).unwrap(); >> + >> + unsafe { >> + ::qemu_api::bindings::qemu_log(c_string.as_ptr()); >> + } >> + } >> + }}; >> +} > ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/2] rust/qemu-api: Add initial logging support based on C API 2025-04-01 10:51 ` Bernhard Beschow @ 2025-04-08 20:58 ` Bernhard Beschow 2025-05-12 15:32 ` Paolo Bonzini 0 siblings, 1 reply; 18+ messages in thread From: Bernhard Beschow @ 2025-04-08 20:58 UTC (permalink / raw) To: Paolo Bonzini, qemu-devel; +Cc: Manos Pitsidianakis, qemu-rust Am 1. April 2025 10:51:06 UTC schrieb Bernhard Beschow <shentey@gmail.com>: > > >Am 31. März 2025 09:53:41 UTC schrieb Paolo Bonzini <pbonzini@redhat.com>: >>On 3/30/25 22:58, Bernhard Beschow wrote: >>> A qemu_log_mask!() macro is provided which expects similar arguments as the C >>> version. However, the formatting works as one would expect from Rust. >>> >>> To maximize code reuse the macro is just a thin wrapper around qemu_log(). >>> Also, just the bare minimum of logging masks is provided which should suffice >>> for the current use case of Rust in QEMU. >> >>It's probably better to use an enum for this. One possibility is also to change the #defines to a C enum, and see which enum translation of the several allowed by bindgen is best. > >Currently the #defines contain some holes for "private" mask bits. Turning these into an enum without exposing all publicly, and changing the type of qemu_loglevel for consistency, would result in undefined behavior. Or do you suggest to convert just the public #defines into an enum to expose them to Rust, and keep the rest of the C API including the type of qemu_loglevel as is? > >There are surely several tradeoffs and/or cleanups possible here, but that's way beyond for what I wanted to achieve -- which is closing a gap between C and Rust. My main goal is just to get my feet wet with Rust. > >> >>Also, while this is good for now, later on we probably want to reimplement logging at a lower level via the std::fmt::Write trait. But that's just for efficiency and your macro is indeed good enough to define what the API would look like. > >Can we live with an easy solution then for now? As you suggest below, further abstractions like log_guest_error! can be built on top which further insulates client code from implementation details such as the representation of the mask bits. Ping > >> Right now I have a project for GSoC that will look at that, and the student can look into it later on. > >Whoops, I didn't intend to spoil the project. > >> >>This means answering the following two questions: >> >>- the mapping the LOG_* constants into Rust >> >>- whether to keep the "qemu" prefix for the API (personal opinion: no) >> >>- whether it makes sense to add more macros such as log_guest_error! or log_unimp! for the most common LOG_* values >> >>> +#[macro_export] >>> +macro_rules! qemu_log_mask { >>> + ($mask:expr, $fmt:expr $(, $args:expr)*) => {{ >> >>Looking at https://doc.rust-lang.org/std/macro.write.html they just use $($arg:tt)* for what is passed to format_args! (or in your case format!), so we can do the same here too. The main advantage is that it allows giving a trailing comma to qemu_log_mask!. > >Easy to fix. Before proceeding I'd like to see a solution for the topic above. > >Best regards, >Bernhard > >> >>Paolo >> >>> + if unsafe { >>> + (::qemu_api::bindings::qemu_loglevel & ($mask as std::os::raw::c_int)) != 0 >>> + } { >>> + let formatted_string = format!($fmt, $($args),*); >>> + let c_string = std::ffi::CString::new(formatted_string).unwrap(); >>> + >>> + unsafe { >>> + ::qemu_api::bindings::qemu_log(c_string.as_ptr()); >>> + } >>> + } >>> + }}; >>> +} >> ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/2] rust/qemu-api: Add initial logging support based on C API 2025-04-08 20:58 ` Bernhard Beschow @ 2025-05-12 15:32 ` Paolo Bonzini 2025-05-19 8:13 ` Manos Pitsidianakis 2025-06-10 20:51 ` Bernhard Beschow 0 siblings, 2 replies; 18+ messages in thread From: Paolo Bonzini @ 2025-05-12 15:32 UTC (permalink / raw) To: Bernhard Beschow; +Cc: qemu-devel, Manos Pitsidianakis, qemu-rust Hi, now that GSoC selection is over I'm back. Sorry for the delay; Tanish Desai will work mostly on tracing, so logging can remain yours. On Tue, Apr 8, 2025 at 10:59 PM Bernhard Beschow <shentey@gmail.com> wrote: > >Currently the #defines contain some holes for "private" mask bits. Turning these into an > >enum without exposing all publicly, and changing the type of qemu_loglevel for > >consistency, would result in undefined behavior. Or do you suggest to convert just > >the public #defines into an enum to expose them to Rust, and keep the rest of > >the C API including the type of qemu_loglevel as is? Yes, only in Rust. > >There are surely several tradeoffs and/or cleanups possible here, but that's way beyond for > >what I wanted to achieve -- which is closing a gap between C and Rust. My main goal is just > >to get my feet wet with Rust. I understand, however there is no point in defining an API and then changing it. So we need to answer the questions I wrote a few messages ago, namely: - the mapping the LOG_* constants into Rust (e.g. whether to keep the uppercase SNAKE_CASE or switch to something like Log::GuestError). - whether to keep the "qemu" prefix for the API (personal opinion: no) I agree with not having macros such as log_guest_error! for now, or not wrapping functions like qemu_log_trylock/qemu_log_unlock that would be implemented as RAII (i.e. returning a "guard" object) in Rust. > >>Also, while this is good for now, later on we probably want to reimplement logging at a lower level via the std::fmt::Write trait. But that's just for efficiency and your macro is indeed good enough to define what the API would look like. > > > >Can we live with an easy solution then for now? As you suggest below, further abstractions like log_guest_error! can be built on top which further insulates client code from implementation details such as the representation of the mask bits. Yes, of course. Paolo ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/2] rust/qemu-api: Add initial logging support based on C API 2025-05-12 15:32 ` Paolo Bonzini @ 2025-05-19 8:13 ` Manos Pitsidianakis 2025-05-20 9:57 ` Paolo Bonzini 2025-06-10 20:51 ` Bernhard Beschow 1 sibling, 1 reply; 18+ messages in thread From: Manos Pitsidianakis @ 2025-05-19 8:13 UTC (permalink / raw) To: Paolo Bonzini; +Cc: Bernhard Beschow, qemu-devel, qemu-rust Hello Paolo, Bernhard, On Mon, May 12, 2025 at 6:32 PM Paolo Bonzini <pbonzini@redhat.com> wrote: > > Hi, now that GSoC selection is over I'm back. Sorry for the delay; > Tanish Desai will work mostly on tracing, so logging can remain yours. > > On Tue, Apr 8, 2025 at 10:59 PM Bernhard Beschow <shentey@gmail.com> wrote: > > >Currently the #defines contain some holes for "private" mask bits. Turning these into an > > >enum without exposing all publicly, and changing the type of qemu_loglevel for > > >consistency, would result in undefined behavior. Or do you suggest to convert just > > >the public #defines into an enum to expose them to Rust, and keep the rest of > > >the C API including the type of qemu_loglevel as is? > > Yes, only in Rust. > > > >There are surely several tradeoffs and/or cleanups possible here, but that's way beyond for > > >what I wanted to achieve -- which is closing a gap between C and Rust. My main goal is just > > >to get my feet wet with Rust. > > I understand, however there is no point in defining an API and then changing it. > > So we need to answer the questions I wrote a few messages ago, namely: > > - the mapping the LOG_* constants into Rust (e.g. whether to keep the > uppercase SNAKE_CASE or switch to something like Log::GuestError). > > - whether to keep the "qemu" prefix for the API (personal opinion: no) > > I agree with not having macros such as log_guest_error! for now, or > not wrapping functions like qemu_log_trylock/qemu_log_unlock that > would be implemented as RAII (i.e. returning a "guard" object) in > Rust. > > > >>Also, while this is good for now, later on we probably want to reimplement logging at a lower level via the std::fmt::Write trait. But that's just for efficiency and your macro is indeed good enough to define what the API would look like. > > > > > >Can we live with an easy solution then for now? As you suggest below, further abstractions like log_guest_error! can be built on top which further insulates client code from implementation details such as the representation of the mask bits. > > Yes, of course. > > Paolo There's also the `tracing` framework https://docs.rs/tracing/latest/tracing/ that is quite nice for defining tracing events **and** spans for logs. I find it confusing that it still ties tracing events with log level filters though (info/warn/error/debug/trace). Perhaps this is also a good opportunity to restructure QEMU's logging in general. As was said in other threads about tracing, most log items are essentially traces, except guest_error, unimp and maybe I'm missing a few others. If we align QEMU's general logging to use log levels, we can convert guest error logs to "Error" level logs of type: "guest", and unimp logs to "Error" logs of type "unimplemented". Or, "Warn" instead of "Error". Then, all trace_* items become straightforwardly Trace level log items. Then, all we have to do in the Rust side is implement a `tracing` subscriber that consumes these traces and pushes them into QEMU's C implementation. -- Manos Pitsidianakis Emulation and Virtualization Engineer at Linaro Ltd ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/2] rust/qemu-api: Add initial logging support based on C API 2025-05-19 8:13 ` Manos Pitsidianakis @ 2025-05-20 9:57 ` Paolo Bonzini 0 siblings, 0 replies; 18+ messages in thread From: Paolo Bonzini @ 2025-05-20 9:57 UTC (permalink / raw) To: Manos Pitsidianakis; +Cc: Bernhard Beschow, qemu-devel, qemu-rust On Mon, May 19, 2025 at 10:14 AM Manos Pitsidianakis <manos.pitsidianakis@linaro.org> wrote: > There's also the `tracing` framework > https://docs.rs/tracing/latest/tracing/ that is quite nice for > defining tracing events **and** spans for logs. I find it confusing > that it still ties tracing events with log level filters though > (info/warn/error/debug/trace). I like the overall look of the tracing crate API a lot. One thing that I don't like is that it's very string-heavy. In general it seems to have more overhead than tracetool if you use `Interest::Sometimes`; it uses Strings for event names and targets but not ids (the default event name is even "event FILE:LINE" which is not really usable except for development), making matches (especially "enabled()" checks) slow. Secondarily, built-in support for fmt::Debug/fmt::Display lets you get away with not thinking of *which* fields you want to record. But it's powerful, easy to use and it also has very few dependencies, which is nice. > Perhaps this is also a good opportunity to restructure QEMU's logging > in general. [...] > If we align QEMU's general logging to use log levels, we can convert > guest error logs to "Error" level logs of type: "guest", and unimp > logs to "Error" logs of type "unimplemented". Or, "Warn" instead of > "Error". Then, all trace_* items become straightforwardly Trace level > log items. Focusing for a second on guest and unimp items, do you think that there would be macros like `guest_error!` and `unimp!` (similar to how `tracing` has shortcuts `error!` or `warn!`)? If so, we could add them even now, so that any future changes to the implementation would be transparent. > Then, all we have to do in the Rust side is implement a `tracing` > subscriber that consumes these traces and pushes them into QEMU's C > implementation. As I said above, I am a bit worried about performance implications of having Strings for event names and targets but yes, using the tracing crate is definitely something to think about! As you say, it provides an opportunity to add structure to QEMU's logging and maybe we can get the best of both worlds from both `tracing` and tracetool. Do you think util/log.c could become a wrapper around event!() and tracing_subscriber::FmtSubscriber (with log levels based on LOG_* constants, as you mentioned)? Then the `log` backend for tracetool could generate Rust code that calls trace!() instead of C code that calls qemu_log(). Or you could do the same thing to the error_vprintf/error_printf implementations, and then Rust code could use error! and warn! where C code uses error_report() and warn_report(). It's a common complaint that error_report() and warn_report() get lost in logs for example, and `tracing` could add some structure there. It could also be a very good starting point for thinking about C->Rust FFI (i.e. implementing in Rust functionality that is used by C code). In the meanwhile, another thing that could be done is take inspiration from the `tracing` API, for example adding an #[instrument] macro to qemu_api_macros: impl PL011Registers { #[instrument(target = "hw_char", name = "pl011_write", fields(offset = offset as u32, value)) pub(self) fn write(...) { } } This way, even if tracetool and trace-events file remain part of the architecture, the API is more familiar to Rust developers. It'd be a nice addition to Tanish's work (he's my student that's working on Rust tracepoints. Paolo ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/2] rust/qemu-api: Add initial logging support based on C API 2025-05-12 15:32 ` Paolo Bonzini 2025-05-19 8:13 ` Manos Pitsidianakis @ 2025-06-10 20:51 ` Bernhard Beschow 1 sibling, 0 replies; 18+ messages in thread From: Bernhard Beschow @ 2025-06-10 20:51 UTC (permalink / raw) To: Paolo Bonzini; +Cc: qemu-devel, Manos Pitsidianakis, qemu-rust Am 12. Mai 2025 15:32:08 UTC schrieb Paolo Bonzini <pbonzini@redhat.com>: >Hi, now that GSoC selection is over I'm back. Sorry for the delay; >Tanish Desai will work mostly on tracing, so logging can remain yours. > >On Tue, Apr 8, 2025 at 10:59 PM Bernhard Beschow <shentey@gmail.com> wrote: >> >Currently the #defines contain some holes for "private" mask bits. Turning these into an >> >enum without exposing all publicly, and changing the type of qemu_loglevel for >> >consistency, would result in undefined behavior. Or do you suggest to convert just >> >the public #defines into an enum to expose them to Rust, and keep the rest of >> >the C API including the type of qemu_loglevel as is? > >Yes, only in Rust. > >> >There are surely several tradeoffs and/or cleanups possible here, but that's way beyond for >> >what I wanted to achieve -- which is closing a gap between C and Rust. My main goal is just >> >to get my feet wet with Rust. > >I understand, however there is no point in defining an API and then changing it. > >So we need to answer the questions I wrote a few messages ago, namely: > >- the mapping the LOG_* constants into Rust (e.g. whether to keep the >uppercase SNAKE_CASE or switch to something like Log::GuestError). > >- whether to keep the "qemu" prefix for the API (personal opinion: no) Sorry for the long delay, the imx8mp desired my attention. Paolo, I tried both of your suggestions and found them to be convincing enough that I sent a v2: <https://lore.kernel.org/qemu-devel/20250610202110.2243-1-shentey@gmail.com/T/#t> Best regards, Bernhard > >I agree with not having macros such as log_guest_error! for now, or >not wrapping functions like qemu_log_trylock/qemu_log_unlock that >would be implemented as RAII (i.e. returning a "guard" object) in >Rust. > >> >>Also, while this is good for now, later on we probably want to reimplement logging at a lower level via the std::fmt::Write trait. But that's just for efficiency and your macro is indeed good enough to define what the API would look like. >> > >> >Can we live with an easy solution then for now? As you suggest below, further abstractions like log_guest_error! can be built on top which further insulates client code from implementation details such as the representation of the mask bits. > >Yes, of course. > >Paolo > ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 2/2] rust/hw/char/pl011/src/device: Implement logging 2025-03-30 20:58 [PATCH 0/2] Initial logging support for Rust Bernhard Beschow 2025-03-30 20:58 ` [PATCH 1/2] rust/qemu-api: Add initial logging support based on C API Bernhard Beschow @ 2025-03-30 20:58 ` Bernhard Beschow 2025-03-31 9:18 ` Daniel P. Berrangé 1 sibling, 1 reply; 18+ messages in thread From: Bernhard Beschow @ 2025-03-30 20:58 UTC (permalink / raw) To: qemu-devel Cc: Manos Pitsidianakis, qemu-rust, Paolo Bonzini, Bernhard Beschow Now that there is logging support in Rust for QEMU, use it in the pl011 device. Signed-off-by: Bernhard Beschow <shentey@gmail.com> --- rust/hw/char/pl011/src/device.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index bf88e0b00a..d5470fae11 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -8,9 +8,11 @@ chardev::{CharBackend, Chardev, Event}, impl_vmstate_forward, irq::{IRQState, InterruptSource}, + log::{LOG_GUEST_ERROR, LOG_UNIMP}, memory::{hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder}, prelude::*, qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property, ResetType, ResettablePhasesImpl}, + qemu_log_mask, qom::{ObjectImpl, Owned, ParentField}, static_assert, sysbus::{SysBusDevice, SysBusDeviceImpl}, @@ -298,8 +300,7 @@ pub(self) fn write( DMACR => { self.dmacr = value; if value & 3 > 0 { - // qemu_log_mask(LOG_UNIMP, "pl011: DMA not implemented\n"); - eprintln!("pl011: DMA not implemented"); + qemu_log_mask!(LOG_UNIMP, "pl011: DMA not implemented\n"); } } } @@ -535,7 +536,7 @@ fn read(&self, offset: hwaddr, _size: u32) -> u64 { u64::from(device_id[(offset - 0xfe0) >> 2]) } Err(_) => { - // qemu_log_mask(LOG_GUEST_ERROR, "pl011_read: Bad offset 0x%x\n", (int)offset); + qemu_log_mask!(LOG_GUEST_ERROR, "pl011_read: Bad offset {offset}\n"); 0 } Ok(field) => { @@ -567,7 +568,10 @@ fn write(&self, offset: hwaddr, value: u64, _size: u32) { .borrow_mut() .write(field, value as u32, &self.char_backend); } else { - eprintln!("write bad offset {offset} value {value}"); + qemu_log_mask!( + LOG_GUEST_ERROR, + "pl011_write: Bad offset {offset} value {value}\n" + ); } if update_irq { self.update(); -- 2.49.0 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] rust/hw/char/pl011/src/device: Implement logging 2025-03-30 20:58 ` [PATCH 2/2] rust/hw/char/pl011/src/device: Implement logging Bernhard Beschow @ 2025-03-31 9:18 ` Daniel P. Berrangé 2025-04-02 9:33 ` Bernhard Beschow 0 siblings, 1 reply; 18+ messages in thread From: Daniel P. Berrangé @ 2025-03-31 9:18 UTC (permalink / raw) To: Bernhard Beschow Cc: qemu-devel, Manos Pitsidianakis, qemu-rust, Paolo Bonzini On Sun, Mar 30, 2025 at 10:58:57PM +0200, Bernhard Beschow wrote: > Now that there is logging support in Rust for QEMU, use it in the pl011 device. > > Signed-off-by: Bernhard Beschow <shentey@gmail.com> > --- > rust/hw/char/pl011/src/device.rs | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs > index bf88e0b00a..d5470fae11 100644 > --- a/rust/hw/char/pl011/src/device.rs > +++ b/rust/hw/char/pl011/src/device.rs > @@ -8,9 +8,11 @@ > chardev::{CharBackend, Chardev, Event}, > impl_vmstate_forward, > irq::{IRQState, InterruptSource}, > + log::{LOG_GUEST_ERROR, LOG_UNIMP}, > memory::{hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder}, > prelude::*, > qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property, ResetType, ResettablePhasesImpl}, > + qemu_log_mask, > qom::{ObjectImpl, Owned, ParentField}, > static_assert, > sysbus::{SysBusDevice, SysBusDeviceImpl}, > @@ -298,8 +300,7 @@ pub(self) fn write( > DMACR => { > self.dmacr = value; > if value & 3 > 0 { > - // qemu_log_mask(LOG_UNIMP, "pl011: DMA not implemented\n"); > - eprintln!("pl011: DMA not implemented"); > + qemu_log_mask!(LOG_UNIMP, "pl011: DMA not implemented\n"); > } > } > } > @@ -535,7 +536,7 @@ fn read(&self, offset: hwaddr, _size: u32) -> u64 { > u64::from(device_id[(offset - 0xfe0) >> 2]) > } > Err(_) => { > - // qemu_log_mask(LOG_GUEST_ERROR, "pl011_read: Bad offset 0x%x\n", (int)offset); > + qemu_log_mask!(LOG_GUEST_ERROR, "pl011_read: Bad offset {offset}\n"); > 0 > } > Ok(field) => { > @@ -567,7 +568,10 @@ fn write(&self, offset: hwaddr, value: u64, _size: u32) { > .borrow_mut() > .write(field, value as u32, &self.char_backend); > } else { > - eprintln!("write bad offset {offset} value {value}"); > + qemu_log_mask!( > + LOG_GUEST_ERROR, > + "pl011_write: Bad offset {offset} value {value}\n" > + ); > } General conceptual question ..... I've never understood what the dividing line is between use of 'qemu_log_mask' and trace points. The latter can be optionally built to feed into qemu log, as well as the other dynamic trace backends. Is there a compelling reason to use 'qemu_log', that isn't acceptable for trace probe points ? This is an indirect way of asking whether qemu_log_mask should be exposed to rust, or would exposing tracing be sufficient ? 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] 18+ messages in thread
* Re: [PATCH 2/2] rust/hw/char/pl011/src/device: Implement logging 2025-03-31 9:18 ` Daniel P. Berrangé @ 2025-04-02 9:33 ` Bernhard Beschow 2025-04-02 13:27 ` Daniel P. Berrangé 2025-04-02 14:13 ` BALATON Zoltan 0 siblings, 2 replies; 18+ messages in thread From: Bernhard Beschow @ 2025-04-02 9:33 UTC (permalink / raw) To: Daniel P. Berrangé Cc: qemu-devel, Manos Pitsidianakis, qemu-rust, Paolo Bonzini Am 31. März 2025 09:18:05 UTC schrieb "Daniel P. Berrangé" <berrange@redhat.com>: >On Sun, Mar 30, 2025 at 10:58:57PM +0200, Bernhard Beschow wrote: >> Now that there is logging support in Rust for QEMU, use it in the pl011 device. >> >> Signed-off-by: Bernhard Beschow <shentey@gmail.com> >> --- >> rust/hw/char/pl011/src/device.rs | 12 ++++++++---- >> 1 file changed, 8 insertions(+), 4 deletions(-) >> >> diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs >> index bf88e0b00a..d5470fae11 100644 >> --- a/rust/hw/char/pl011/src/device.rs >> +++ b/rust/hw/char/pl011/src/device.rs >> @@ -8,9 +8,11 @@ >> chardev::{CharBackend, Chardev, Event}, >> impl_vmstate_forward, >> irq::{IRQState, InterruptSource}, >> + log::{LOG_GUEST_ERROR, LOG_UNIMP}, >> memory::{hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder}, >> prelude::*, >> qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property, ResetType, ResettablePhasesImpl}, >> + qemu_log_mask, >> qom::{ObjectImpl, Owned, ParentField}, >> static_assert, >> sysbus::{SysBusDevice, SysBusDeviceImpl}, >> @@ -298,8 +300,7 @@ pub(self) fn write( >> DMACR => { >> self.dmacr = value; >> if value & 3 > 0 { >> - // qemu_log_mask(LOG_UNIMP, "pl011: DMA not implemented\n"); >> - eprintln!("pl011: DMA not implemented"); >> + qemu_log_mask!(LOG_UNIMP, "pl011: DMA not implemented\n"); >> } >> } >> } >> @@ -535,7 +536,7 @@ fn read(&self, offset: hwaddr, _size: u32) -> u64 { >> u64::from(device_id[(offset - 0xfe0) >> 2]) >> } >> Err(_) => { >> - // qemu_log_mask(LOG_GUEST_ERROR, "pl011_read: Bad offset 0x%x\n", (int)offset); >> + qemu_log_mask!(LOG_GUEST_ERROR, "pl011_read: Bad offset {offset}\n"); >> 0 >> } >> Ok(field) => { >> @@ -567,7 +568,10 @@ fn write(&self, offset: hwaddr, value: u64, _size: u32) { >> .borrow_mut() >> .write(field, value as u32, &self.char_backend); >> } else { >> - eprintln!("write bad offset {offset} value {value}"); >> + qemu_log_mask!( >> + LOG_GUEST_ERROR, >> + "pl011_write: Bad offset {offset} value {value}\n" >> + ); >> } > >General conceptual question ..... I've never understood what the dividing >line is between use of 'qemu_log_mask' and trace points. I *think* it's the perspective: If you want to see any issues, regardless of which device, use the -l option, i.e. qemu_log_mask(). If, however, you want to see what a particular device does, use tracepoints. >The latter can be >optionally built to feed into qemu log, as well as the other dynamic trace >backends. The use of qemu_log() in qemu_log_mask() seems like an implementation detail to me. Theoretically, qemu_log_mask() could use a different backend if this got implemented, and wouldn't require code changes throughout QEMU. Best regards, Bernhard > >Is there a compelling reason to use 'qemu_log', that isn't acceptable for >trace probe points ? > >This is an indirect way of asking whether qemu_log_mask should be exposed >to rust, or would exposing tracing be sufficient ? > >With regards, >Daniel ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] rust/hw/char/pl011/src/device: Implement logging 2025-04-02 9:33 ` Bernhard Beschow @ 2025-04-02 13:27 ` Daniel P. Berrangé 2025-04-03 9:46 ` Bernhard Beschow 2025-05-02 16:48 ` Peter Maydell 2025-04-02 14:13 ` BALATON Zoltan 1 sibling, 2 replies; 18+ messages in thread From: Daniel P. Berrangé @ 2025-04-02 13:27 UTC (permalink / raw) To: Bernhard Beschow Cc: qemu-devel, Manos Pitsidianakis, qemu-rust, Paolo Bonzini On Wed, Apr 02, 2025 at 09:33:16AM +0000, Bernhard Beschow wrote: > > > Am 31. März 2025 09:18:05 UTC schrieb "Daniel P. Berrangé" <berrange@redhat.com>: > >On Sun, Mar 30, 2025 at 10:58:57PM +0200, Bernhard Beschow wrote: > >> Now that there is logging support in Rust for QEMU, use it in the pl011 device. > >> > >> Signed-off-by: Bernhard Beschow <shentey@gmail.com> > >> --- > >> rust/hw/char/pl011/src/device.rs | 12 ++++++++---- > >> 1 file changed, 8 insertions(+), 4 deletions(-) > >> > >> diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs > >> index bf88e0b00a..d5470fae11 100644 > >> --- a/rust/hw/char/pl011/src/device.rs > >> +++ b/rust/hw/char/pl011/src/device.rs > >> @@ -8,9 +8,11 @@ > >> chardev::{CharBackend, Chardev, Event}, > >> impl_vmstate_forward, > >> irq::{IRQState, InterruptSource}, > >> + log::{LOG_GUEST_ERROR, LOG_UNIMP}, > >> memory::{hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder}, > >> prelude::*, > >> qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property, ResetType, ResettablePhasesImpl}, > >> + qemu_log_mask, > >> qom::{ObjectImpl, Owned, ParentField}, > >> static_assert, > >> sysbus::{SysBusDevice, SysBusDeviceImpl}, > >> @@ -298,8 +300,7 @@ pub(self) fn write( > >> DMACR => { > >> self.dmacr = value; > >> if value & 3 > 0 { > >> - // qemu_log_mask(LOG_UNIMP, "pl011: DMA not implemented\n"); > >> - eprintln!("pl011: DMA not implemented"); > >> + qemu_log_mask!(LOG_UNIMP, "pl011: DMA not implemented\n"); > >> } > >> } > >> } > >> @@ -535,7 +536,7 @@ fn read(&self, offset: hwaddr, _size: u32) -> u64 { > >> u64::from(device_id[(offset - 0xfe0) >> 2]) > >> } > >> Err(_) => { > >> - // qemu_log_mask(LOG_GUEST_ERROR, "pl011_read: Bad offset 0x%x\n", (int)offset); > >> + qemu_log_mask!(LOG_GUEST_ERROR, "pl011_read: Bad offset {offset}\n"); > >> 0 > >> } > >> Ok(field) => { > >> @@ -567,7 +568,10 @@ fn write(&self, offset: hwaddr, value: u64, _size: u32) { > >> .borrow_mut() > >> .write(field, value as u32, &self.char_backend); > >> } else { > >> - eprintln!("write bad offset {offset} value {value}"); > >> + qemu_log_mask!( > >> + LOG_GUEST_ERROR, > >> + "pl011_write: Bad offset {offset} value {value}\n" > >> + ); > >> } > > > >General conceptual question ..... I've never understood what the dividing > >line is between use of 'qemu_log_mask' and trace points. > > I *think* it's the perspective: If you want to see any issues, regardless > of which device, use the -l option, i.e. qemu_log_mask(). If, however, > you want to see what a particular device does, use tracepoints. I guess I'd say that the latter ought to be capable of satisfying the former use case too, given a suitable trace point selection. If it can't, then perhaps that's telling us the way we select trace points is insufficiently expressive ? 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] 18+ messages in thread
* Re: [PATCH 2/2] rust/hw/char/pl011/src/device: Implement logging 2025-04-02 13:27 ` Daniel P. Berrangé @ 2025-04-03 9:46 ` Bernhard Beschow 2025-05-02 16:48 ` Peter Maydell 1 sibling, 0 replies; 18+ messages in thread From: Bernhard Beschow @ 2025-04-03 9:46 UTC (permalink / raw) To: Daniel P. Berrangé Cc: qemu-devel, Manos Pitsidianakis, qemu-rust, Paolo Bonzini Am 2. April 2025 13:27:53 UTC schrieb "Daniel P. Berrangé" <berrange@redhat.com>: >On Wed, Apr 02, 2025 at 09:33:16AM +0000, Bernhard Beschow wrote: >> >> >> Am 31. März 2025 09:18:05 UTC schrieb "Daniel P. Berrangé" <berrange@redhat.com>: >> >On Sun, Mar 30, 2025 at 10:58:57PM +0200, Bernhard Beschow wrote: >> >> Now that there is logging support in Rust for QEMU, use it in the pl011 device. >> >> >> >> Signed-off-by: Bernhard Beschow <shentey@gmail.com> >> >> --- >> >> rust/hw/char/pl011/src/device.rs | 12 ++++++++---- >> >> 1 file changed, 8 insertions(+), 4 deletions(-) >> >> >> >> diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs >> >> index bf88e0b00a..d5470fae11 100644 >> >> --- a/rust/hw/char/pl011/src/device.rs >> >> +++ b/rust/hw/char/pl011/src/device.rs >> >> @@ -8,9 +8,11 @@ >> >> chardev::{CharBackend, Chardev, Event}, >> >> impl_vmstate_forward, >> >> irq::{IRQState, InterruptSource}, >> >> + log::{LOG_GUEST_ERROR, LOG_UNIMP}, >> >> memory::{hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder}, >> >> prelude::*, >> >> qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property, ResetType, ResettablePhasesImpl}, >> >> + qemu_log_mask, >> >> qom::{ObjectImpl, Owned, ParentField}, >> >> static_assert, >> >> sysbus::{SysBusDevice, SysBusDeviceImpl}, >> >> @@ -298,8 +300,7 @@ pub(self) fn write( >> >> DMACR => { >> >> self.dmacr = value; >> >> if value & 3 > 0 { >> >> - // qemu_log_mask(LOG_UNIMP, "pl011: DMA not implemented\n"); >> >> - eprintln!("pl011: DMA not implemented"); >> >> + qemu_log_mask!(LOG_UNIMP, "pl011: DMA not implemented\n"); >> >> } >> >> } >> >> } >> >> @@ -535,7 +536,7 @@ fn read(&self, offset: hwaddr, _size: u32) -> u64 { >> >> u64::from(device_id[(offset - 0xfe0) >> 2]) >> >> } >> >> Err(_) => { >> >> - // qemu_log_mask(LOG_GUEST_ERROR, "pl011_read: Bad offset 0x%x\n", (int)offset); >> >> + qemu_log_mask!(LOG_GUEST_ERROR, "pl011_read: Bad offset {offset}\n"); >> >> 0 >> >> } >> >> Ok(field) => { >> >> @@ -567,7 +568,10 @@ fn write(&self, offset: hwaddr, value: u64, _size: u32) { >> >> .borrow_mut() >> >> .write(field, value as u32, &self.char_backend); >> >> } else { >> >> - eprintln!("write bad offset {offset} value {value}"); >> >> + qemu_log_mask!( >> >> + LOG_GUEST_ERROR, >> >> + "pl011_write: Bad offset {offset} value {value}\n" >> >> + ); >> >> } >> > >> >General conceptual question ..... I've never understood what the dividing >> >line is between use of 'qemu_log_mask' and trace points. >> >> I *think* it's the perspective: If you want to see any issues, regardless >> of which device, use the -l option, i.e. qemu_log_mask(). If, however, >> you want to see what a particular device does, use tracepoints. > >I guess I'd say that the latter ought to be capable of satisfying the >former use case too, given a suitable trace point selection. If it >can't, then perhaps that's telling us the way we select trace points >is insufficiently expressive ? Tracepoints often encode some context in the function name, e.g. the device name and the operation being performed. One could give up this context information in the function names and pass it as arguments to generic trace_unimp() and trace_guest_error() functions. The drawback is that this doesn't provide any advantage over the current logging functionality such as device filtering. That could be achieved by trace_$device_$operation_{unimp,guest_error} functions which is a convention that has to be enforced manually. Best regards, Bernhard > >With regards, >Daniel ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] rust/hw/char/pl011/src/device: Implement logging 2025-04-02 13:27 ` Daniel P. Berrangé 2025-04-03 9:46 ` Bernhard Beschow @ 2025-05-02 16:48 ` Peter Maydell 2025-05-08 17:14 ` Daniel P. Berrangé 1 sibling, 1 reply; 18+ messages in thread From: Peter Maydell @ 2025-05-02 16:48 UTC (permalink / raw) To: Daniel P. Berrangé Cc: Bernhard Beschow, qemu-devel, Manos Pitsidianakis, qemu-rust, Paolo Bonzini On Wed, 2 Apr 2025 at 14:28, Daniel P. Berrangé <berrange@redhat.com> wrote: > On Wed, Apr 02, 2025 at 09:33:16AM +0000, Bernhard Beschow wrote: > > Am 31. März 2025 09:18:05 UTC schrieb "Daniel P. Berrangé" <berrange@redhat.com>: > > >General conceptual question ..... I've never understood what the dividing > > >line is between use of 'qemu_log_mask' and trace points. > > > > I *think* it's the perspective: If you want to see any issues, regardless > > of which device, use the -l option, i.e. qemu_log_mask(). If, however, > > you want to see what a particular device does, use tracepoints. > > I guess I'd say that the latter ought to be capable of satisfying the > former use case too, given a suitable trace point selection. If it > can't, then perhaps that's telling us the way we select trace points > is insufficiently expressive ? Yeah; you can turn on and off a tracepoint, and you can select them by wildcard, but there's no categorization of them (into eg "this is basically the equivalent of a debug printf" vs "this is something that is a guest error you probably want to know about"). There's also no way to say "turn on this logging with one switch, and it will print multiple lines or more than one thing" (at least not in the spirit of what the tracepoint API expects; you could have a trace_in_asm tracepoint that took a "%s" and output whatever you liked as the string, of course). And debug-logging is more documented: '-d help' shows what you can turn on and off and has at least a brief description of what it is you're getting. For tracepoints you're hoping that the name is vaguely descriptive and also hoping that the device/subsystem/etc named its tracepoints in a way that lets you usefully wildcard them. Also, the qemu_log() logging assumes "we're sending text to a logfile, we can format e.g. register dumps and disassembly as arbitrary laid out plaintext". That's fine if your tracepoint backend is also "we just send the text to a logfile/etc", but I don't know if all of the tracepoint backends would be so happy with that. thanks -- PMM ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] rust/hw/char/pl011/src/device: Implement logging 2025-05-02 16:48 ` Peter Maydell @ 2025-05-08 17:14 ` Daniel P. Berrangé 2025-05-12 10:45 ` Peter Maydell 0 siblings, 1 reply; 18+ messages in thread From: Daniel P. Berrangé @ 2025-05-08 17:14 UTC (permalink / raw) To: Peter Maydell Cc: Bernhard Beschow, qemu-devel, Manos Pitsidianakis, qemu-rust, Paolo Bonzini On Fri, May 02, 2025 at 05:48:02PM +0100, Peter Maydell wrote: > On Wed, 2 Apr 2025 at 14:28, Daniel P. Berrangé <berrange@redhat.com> wrote: > > On Wed, Apr 02, 2025 at 09:33:16AM +0000, Bernhard Beschow wrote: > > > Am 31. März 2025 09:18:05 UTC schrieb "Daniel P. Berrangé" <berrange@redhat.com>: > > > >General conceptual question ..... I've never understood what the dividing > > > >line is between use of 'qemu_log_mask' and trace points. > > > > > > I *think* it's the perspective: If you want to see any issues, regardless > > > of which device, use the -l option, i.e. qemu_log_mask(). If, however, > > > you want to see what a particular device does, use tracepoints. > > > > I guess I'd say that the latter ought to be capable of satisfying the > > former use case too, given a suitable trace point selection. If it > > can't, then perhaps that's telling us the way we select trace points > > is insufficiently expressive ? > > Yeah; you can turn on and off a tracepoint, and you can select > them by wildcard, but there's no categorization of them > (into eg "this is basically the equivalent of a debug printf" > vs "this is something that is a guest error you probably > want to know about"). I wonder if there's any value in enhancing the trace support to let us tag certain probes with some kind of "severity"/"level" concept, such that when the 'log' trace backend is enabled we can wire them through to the logging backend with useful categorization ? > There's also no way to say "turn on > this logging with one switch, and it will print multiple lines > or more than one thing" (at least not in the spirit of what > the tracepoint API expects; you could have a trace_in_asm > tracepoint that took a "%s" and output whatever you liked as > the string, of course). And debug-logging is more documented: > '-d help' shows what you can turn on and off and has at least > a brief description of what it is you're getting. IMHO the documentation benefit of '-d help' is somewhat inconsistent. I tried a crude grep for different usage of logging 2 CPU_LOG_EXEC 122 CPU_LOG_INT 103 CPU_LOG_MMU 6 CPU_LOG_PAGE 1 CPU_LOG_PLUGIN 8 CPU_LOG_RESET 10 CPU_LOG_TB_IN_ASM 4 CPU_LOG_TB_OP 1715 LOG_GUEST_ERROR 4 LOG_INVALID_MEM 753 LOG_UNIMP So the overwhealming majority of usage is accumulated under two "catch all" categories - "guest error" and "unimplemented" with no ability to filter - its all or nothing. We ought to be able to do a better job at documentation the trace events than we do today, given we have them in an easily extractable format and can associate them with particular files easily. The 'qemu-trace-stap list' command can list all available probes in a binary, but it only works for the systemtap backend. We ought to do better with other backends. > For tracepoints > you're hoping that the name is vaguely descriptive and also > hoping that the device/subsystem/etc named its tracepoints in > a way that lets you usefully wildcard them. Yep, we're somewhat inconsistent in our prefix naming conventions. It would be nice to try to enforce some greater standard there, but its hard to do programmatically. > Also, the qemu_log() logging assumes "we're sending text to > a logfile, we can format e.g. register dumps and disassembly > as arbitrary laid out plaintext". That's fine if your tracepoint > backend is also "we just send the text to a logfile/etc", but > I don't know if all of the tracepoint backends would be so happy > with that. I think emitting multi-line blocks of text probably ought to be considered out of scope for tracing. The 'log' backend is the only one where that would be a reasonable semantic match. 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] 18+ messages in thread
* Re: [PATCH 2/2] rust/hw/char/pl011/src/device: Implement logging 2025-05-08 17:14 ` Daniel P. Berrangé @ 2025-05-12 10:45 ` Peter Maydell 0 siblings, 0 replies; 18+ messages in thread From: Peter Maydell @ 2025-05-12 10:45 UTC (permalink / raw) To: Daniel P. Berrangé Cc: Bernhard Beschow, qemu-devel, Manos Pitsidianakis, qemu-rust, Paolo Bonzini On Thu, 8 May 2025 at 18:14, Daniel P. Berrangé <berrange@redhat.com> wrote: > > On Fri, May 02, 2025 at 05:48:02PM +0100, Peter Maydell wrote: > > On Wed, 2 Apr 2025 at 14:28, Daniel P. Berrangé <berrange@redhat.com> wrote: > > > On Wed, Apr 02, 2025 at 09:33:16AM +0000, Bernhard Beschow wrote: > > > > Am 31. März 2025 09:18:05 UTC schrieb "Daniel P. Berrangé" <berrange@redhat.com>: > > > > >General conceptual question ..... I've never understood what the dividing > > > > >line is between use of 'qemu_log_mask' and trace points. > > > > > > > > I *think* it's the perspective: If you want to see any issues, regardless > > > > of which device, use the -l option, i.e. qemu_log_mask(). If, however, > > > > you want to see what a particular device does, use tracepoints. > > > > > > I guess I'd say that the latter ought to be capable of satisfying the > > > former use case too, given a suitable trace point selection. If it > > > can't, then perhaps that's telling us the way we select trace points > > > is insufficiently expressive ? > > > > Yeah; you can turn on and off a tracepoint, and you can select > > them by wildcard, but there's no categorization of them > > (into eg "this is basically the equivalent of a debug printf" > > vs "this is something that is a guest error you probably > > want to know about"). > > I wonder if there's any value in enhancing the trace support to > let us tag certain probes with some kind of "severity"/"level" > concept, such that when the 'log' trace backend is enabled we > can wire them through to the logging backend with useful > categorization ? If we wanted to merge the two subsystems I think we'd need that; and also a "kind of log" tagging. > > There's also no way to say "turn on > > this logging with one switch, and it will print multiple lines > > or more than one thing" (at least not in the spirit of what > > the tracepoint API expects; you could have a trace_in_asm > > tracepoint that took a "%s" and output whatever you liked as > > the string, of course). And debug-logging is more documented: > > '-d help' shows what you can turn on and off and has at least > > a brief description of what it is you're getting. > > IMHO the documentation benefit of '-d help' is somewhat > inconsistent. > > I tried a crude grep for different usage of logging > > 2 CPU_LOG_EXEC > 122 CPU_LOG_INT > 103 CPU_LOG_MMU > 6 CPU_LOG_PAGE > 1 CPU_LOG_PLUGIN > 8 CPU_LOG_RESET > 10 CPU_LOG_TB_IN_ASM > 4 CPU_LOG_TB_OP > 1715 LOG_GUEST_ERROR > 4 LOG_INVALID_MEM > 753 LOG_UNIMP > > So the overwhealming majority of usage is accumulated under > two "catch all" categories - "guest error" and "unimplemented" > with no ability to filter - its all or nothing. True, but both those categories are for log messages that are "in normal operation never happens". So it's not like the message you're interested in is buried under a ton of irrelevant logging. > We ought to be able to do a better job at documentation the > trace events than we do today, given we have them in an > easily extractable format and can associate them with > particular files easily. > > The 'qemu-trace-stap list' command can list all available > probes in a binary, but it only works for the systemtap > backend. We ought to do better with other backends. The '-d' backend also lets you list them all with qemu-system-arm -d trace:help > > For tracepoints > > you're hoping that the name is vaguely descriptive and also > > hoping that the device/subsystem/etc named its tracepoints in > > a way that lets you usefully wildcard them. > > Yep, we're somewhat inconsistent in our prefix naming > conventions. It would be nice to try to enforce some > greater standard there, but its hard to do programmatically. > > > Also, the qemu_log() logging assumes "we're sending text to > > a logfile, we can format e.g. register dumps and disassembly > > as arbitrary laid out plaintext". That's fine if your tracepoint > > backend is also "we just send the text to a logfile/etc", but > > I don't know if all of the tracepoint backends would be so happy > > with that. > > I think emitting multi-line blocks of text probably ought to be > considered out of scope for tracing. The 'log' backend is the > only one where that would be a reasonable semantic match. But it's one of the key things -d does: "-d in_asm" for listing the input guest instructions is a super common use case, for instance. If we want to merge qemu_log with tracepoint logs then we need to have some answer to this. (Of course, we could leave the two logging/tracing subsystems the way they are now: there's not really a super strong motivation for refactoring everything to be able to drop the qemu_log stuff.) thanks -- PMM ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] rust/hw/char/pl011/src/device: Implement logging 2025-04-02 9:33 ` Bernhard Beschow 2025-04-02 13:27 ` Daniel P. Berrangé @ 2025-04-02 14:13 ` BALATON Zoltan 1 sibling, 0 replies; 18+ messages in thread From: BALATON Zoltan @ 2025-04-02 14:13 UTC (permalink / raw) To: Bernhard Beschow Cc: Daniel P. Berrangé, qemu-devel, Manos Pitsidianakis, qemu-rust, Paolo Bonzini [-- Attachment #1: Type: text/plain, Size: 2005 bytes --] On Wed, 2 Apr 2025, Bernhard Beschow wrote: > Am 31. März 2025 09:18:05 UTC schrieb "Daniel P. Berrangé" <berrange@redhat.com>: >> General conceptual question ..... I've never understood what the dividing >> line is between use of 'qemu_log_mask' and trace points. > > I *think* it's the perspective: If you want to see any issues, > regardless of which device, use the -l option, i.e. qemu_log_mask(). If, > however, you want to see what a particular device does, use tracepoints. I'd say that traces are like debug printfs that you don't normally want to see but may be interesting for developers for debugging a specific device model or QEMU part so you can enable the relevant ones for that device or part. Logs are something you want to notify the user or admin about and is not tracing internal operation of a device. But there may be some overlap as some logs could be converted to traces but they are under log for historical reasons as previously there were debug printfs controlled by defines in devices that were later converted to traces and logs that could be controlled in run time which were used for some traces before trace points existed. Then were probably kept as logs just to not change the command line because it's easier to type -d in_asm then say -trace enable="tcg_in_asm" or something like that. Regards, BALATON Zoltan >> The latter can be >> optionally built to feed into qemu log, as well as the other dynamic trace >> backends. > > The use of qemu_log() in qemu_log_mask() seems like an implementation detail to me. Theoretically, qemu_log_mask() could use a different backend if this got implemented, and wouldn't require code changes throughout QEMU. > > Best regards, > Bernhard > >> >> Is there a compelling reason to use 'qemu_log', that isn't acceptable for >> trace probe points ? >> >> This is an indirect way of asking whether qemu_log_mask should be exposed >> to rust, or would exposing tracing be sufficient ? >> >> With regards, >> Daniel > > ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2025-06-10 20:52 UTC | newest] Thread overview: 18+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-03-30 20:58 [PATCH 0/2] Initial logging support for Rust Bernhard Beschow 2025-03-30 20:58 ` [PATCH 1/2] rust/qemu-api: Add initial logging support based on C API Bernhard Beschow 2025-03-31 9:53 ` Paolo Bonzini 2025-04-01 10:51 ` Bernhard Beschow 2025-04-08 20:58 ` Bernhard Beschow 2025-05-12 15:32 ` Paolo Bonzini 2025-05-19 8:13 ` Manos Pitsidianakis 2025-05-20 9:57 ` Paolo Bonzini 2025-06-10 20:51 ` Bernhard Beschow 2025-03-30 20:58 ` [PATCH 2/2] rust/hw/char/pl011/src/device: Implement logging Bernhard Beschow 2025-03-31 9:18 ` Daniel P. Berrangé 2025-04-02 9:33 ` Bernhard Beschow 2025-04-02 13:27 ` Daniel P. Berrangé 2025-04-03 9:46 ` Bernhard Beschow 2025-05-02 16:48 ` Peter Maydell 2025-05-08 17:14 ` Daniel P. Berrangé 2025-05-12 10:45 ` Peter Maydell 2025-04-02 14:13 ` BALATON Zoltan
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).