On Thu, Aug 7, 2025 at 3:09 PM Zhao Liu <[email protected]> wrote:
>
> Add rcu_read_lock() & rcu_read_unlock() bindings, then they can be used
> in memory access.
>
> Suggested-by: Paolo Bonzini <[email protected]>
> Signed-off-by: Zhao Liu <[email protected]>
> ---
> rust/qemu-api/meson.build | 1 +
> rust/qemu-api/src/lib.rs | 1 +
> rust/qemu-api/src/rcu.rs | 26 ++++++++++++++++++++++++++
> rust/qemu-api/wrapper.h | 1 +
> 4 files changed, 29 insertions(+)
> create mode 100644 rust/qemu-api/src/rcu.rs
>
> diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build
> index a362d44ed396..d40472092248 100644
> --- a/rust/qemu-api/meson.build
> +++ b/rust/qemu-api/meson.build
> @@ -68,6 +68,7 @@ _qemu_api_rs = static_library(
> 'src/prelude.rs',
> 'src/qdev.rs',
> 'src/qom.rs',
> + 'src/rcu.rs',
> 'src/sysbus.rs',
> 'src/timer.rs',
> 'src/uninit.rs',
> diff --git a/rust/qemu-api/src/lib.rs b/rust/qemu-api/src/lib.rs
> index 86dcd8ef17a9..4705cf9ccbc5 100644
> --- a/rust/qemu-api/src/lib.rs
> +++ b/rust/qemu-api/src/lib.rs
> @@ -26,6 +26,7 @@
> pub mod module;
> pub mod qdev;
> pub mod qom;
> +pub mod rcu;
> pub mod sysbus;
> pub mod timer;
> pub mod uninit;
> diff --git a/rust/qemu-api/src/rcu.rs b/rust/qemu-api/src/rcu.rs
> new file mode 100644
> index 000000000000..30d8b9e43967
> --- /dev/null
> +++ b/rust/qemu-api/src/rcu.rs
> @@ -0,0 +1,26 @@
> +// Copyright (C) 2025 Intel Corporation.
> +// Author(s): Zhao Liu <[email protected]>
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +//! Bindings for `rcu_read_lock` and `rcu_read_unlock`.
> +//! More details about RCU in QEMU, please refer docs/devel/rcu.rst.
> +
How about a RAII guard type? e.g. RCUGuard and runs `rcu_read_unlock` on Drop.
Destructors are not guaranteed to run or run only once, but the former
should happen when things go wrong e.g. crashes/aborts. You can add a
flag in the RCUGuard to make sure Drop runs unlock only once (since it
takes &mut and not ownership)
> +use crate::bindings;
> +
> +/// Used by a reader to inform the reclaimer that the reader is
> +/// entering an RCU read-side critical section.
> +pub fn rcu_read_lock() {
> + // SAFETY: no return and no argument, everything is done at C side.
> + unsafe { bindings::rcu_read_lock() }
> +}
> +
> +/// Used by a reader to inform the reclaimer that the reader is
> +/// exiting an RCU read-side critical section. Note that RCU
> +/// read-side critical sections may be nested and/or overlapping.
> +pub fn rcu_read_unlock() {
> + // SAFETY: no return and no argument, everything is done at C side.
> + unsafe { bindings::rcu_read_unlock() }
> +}
> +
> +// FIXME: maybe we need rcu_read_lock_held() to check the rcu context,
> +// then make it possible to add assertion at any RCU critical section.
This would be less necessary with Drop, maybe.
> diff --git a/rust/qemu-api/wrapper.h b/rust/qemu-api/wrapper.h
> index 15a1b19847f2..ce0ac8d3f550 100644
> --- a/rust/qemu-api/wrapper.h
> +++ b/rust/qemu-api/wrapper.h
> @@ -69,3 +69,4 @@ typedef enum memory_order {
> #include "qemu/timer.h"
> #include "system/address-spaces.h"
> #include "hw/char/pl011.h"
> +#include "qemu/rcu.h"
> --
> 2.34.1
>