qemu-rust.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Zhao Liu <zhao1.liu@intel.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-devel@nongnu.org, qemu-rust@nongnu.org
Subject: Re: [PATCH 07/10] rust: pl011: wrap registers with BqlRefCell
Date: Thu, 23 Jan 2025 13:47:04 +0800	[thread overview]
Message-ID: <Z5HX2G0+bt+3vzVB@intel.com> (raw)
In-Reply-To: <20250117092657.1051233-8-pbonzini@redhat.com>

On Fri, Jan 17, 2025 at 10:26:54AM +0100, Paolo Bonzini wrote:
> Date: Fri, 17 Jan 2025 10:26:54 +0100
> From: Paolo Bonzini <pbonzini@redhat.com>
> Subject: [PATCH 07/10] rust: pl011: wrap registers with BqlRefCell
> X-Mailer: git-send-email 2.47.1
> 
> This is a step towards making memory ops use a shared reference to the
> device type; it's not yet possible due to the calls to character device
> functions.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  rust/hw/char/pl011/src/device.rs       | 38 +++++++++++++-------------
>  rust/hw/char/pl011/src/device_class.rs |  8 +++---
>  rust/hw/char/pl011/src/memory_ops.rs   |  2 +-
>  3 files changed, 24 insertions(+), 24 deletions(-)
> 
> diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs
> index 476abe765a9..1d3da59e481 100644
> --- a/rust/hw/char/pl011/src/device.rs
> +++ b/rust/hw/char/pl011/src/device.rs
> @@ -102,14 +102,14 @@ pub struct PL011Registers {
>  }
>  
>  #[repr(C)]
> -#[derive(Debug, qemu_api_macros::Object, qemu_api_macros::offsets)]

This is the issue I also met, so why not drive "Debug" for BqlRefCell?

I tried to do this in [*]. Do we need to reconsider this?

[*]: https://lore.kernel.org/qemu-devel/20241205060714.256270-3-zhao1.liu@intel.com/

> +#[derive(qemu_api_macros::Object, qemu_api_macros::offsets)]
>  /// PL011 Device Model in QEMU
>  pub struct PL011State {
>      pub parent_obj: ParentField<SysBusDevice>,
>      pub iomem: MemoryRegion,
>      #[doc(alias = "chr")]
>      pub char_backend: CharBackend,
> -    pub regs: PL011Registers,
> +    pub regs: BqlRefCell<PL011Registers>,

This is a good example on the usage of BqlRefCell!

//! `BqlRefCell` is best suited for data that is primarily accessed by the
//! device's own methods, where multiple reads and writes can be grouped within
//! a single borrow and a mutable reference can be passed around. "

>      /// QEMU interrupts
>      ///
>      /// ```text
> @@ -530,8 +530,8 @@ fn post_init(&self) {
>          }
>      }
>  
> +    #[allow(clippy::needless_pass_by_ref_mut)]

How did you trigger this lint error? I switched to 1.84 and didn't get
any errors (I noticed that 1.84 fixed the issue of ignoring `self` [*],
but it still doesn't seem to work on my side).

[*]: https://github.com/rust-lang/rust-clippy/pull/12693

>      pub fn read(&mut self, offset: hwaddr, _size: u32) -> ControlFlow<u64, u64> {
> -        let regs = &mut self.regs;
>          match RegisterOffset::try_from(offset) {
>              Err(v) if (0x3f8..0x400).contains(&(v >> 2)) => {
>                  let device_id = self.get_class().device_id;
> @@ -541,7 +541,7 @@ pub fn read(&mut self, offset: hwaddr, _size: u32) -> ControlFlow<u64, u64> {
>                  // qemu_log_mask(LOG_GUEST_ERROR, "pl011_read: Bad offset 0x%x\n", (int)offset);
>                  ControlFlow::Break(0)
>              }
> -            Ok(field) => match regs.read(field) {
> +            Ok(field) => match self.regs.borrow_mut().read(field) {
>                  ControlFlow::Break(value) => ControlFlow::Break(value.into()),
>                  ControlFlow::Continue(value) => {
>                      self.update();

[snip]

> @@ -603,19 +603,19 @@ pub fn realize(&mut self) {
>      }
>  
>      pub fn reset(&mut self) {

In principle, this place should also trigger `needless_pass_by_ref_mut`.

> -        self.regs.reset();
> +        self.regs.borrow_mut().reset();
>      }

[snip]

> @@ -657,10 +657,10 @@ pub fn post_load(&mut self, _version_id: u32) -> Result<(), ()> {
>  pub unsafe extern "C" fn pl011_receive(opaque: *mut c_void, buf: *const u8, size: c_int) {
>      unsafe {
>          debug_assert!(!opaque.is_null());
> -        let mut state = NonNull::new_unchecked(opaque.cast::<PL011State>());
> +        let state = NonNull::new_unchecked(opaque.cast::<PL011State>());

Perhaps we can use NonNull::new and unwrap()? Then debug_assert! is
unnecessary.

let state = unsafe { NonNull::new(opaque.cast::<PL011State>()).unwrap().as_ref() };

>          if size > 0 {
>              debug_assert!(!buf.is_null());
> -            state.as_mut().receive(u32::from(buf.read_volatile()));
> +            state.as_ref().receive(u32::from(buf.read_volatile()));
>          }
>      }
>  }
> @@ -673,8 +673,8 @@ pub fn post_load(&mut self, _version_id: u32) -> Result<(), ()> {
>  pub unsafe extern "C" fn pl011_event(opaque: *mut c_void, event: QEMUChrEvent) {
>      unsafe {

I think we could narrow the unsafe scope next.

>          debug_assert!(!opaque.is_null());
> -        let mut state = NonNull::new_unchecked(opaque.cast::<PL011State>());
> -        state.as_mut().event(event)
> +        let state = NonNull::new_unchecked(opaque.cast::<PL011State>());
> +        state.as_ref().event(event)
>      }
>  }
  
[snip]

> diff --git a/rust/hw/char/pl011/src/memory_ops.rs b/rust/hw/char/pl011/src/memory_ops.rs
> index c4e8599ba43..8f66c8d492c 100644
> --- a/rust/hw/char/pl011/src/memory_ops.rs
> +++ b/rust/hw/char/pl011/src/memory_ops.rs
> @@ -26,7 +26,7 @@
>  unsafe extern "C" fn pl011_read(opaque: *mut c_void, addr: hwaddr, size: c_uint) -> u64 {
>      assert!(!opaque.is_null());
>      let mut state = unsafe { NonNull::new_unchecked(opaque.cast::<PL011State>()) };
> -    let val = unsafe { state.as_mut().read(addr, size) };
> +    let val = unsafe { state.as_mut() }.read(addr, size);

Nice cleanup.

>      match val {
>          std::ops::ControlFlow::Break(val) => val,
>          std::ops::ControlFlow::Continue(val) => {
> -- 

Nice transition! This is an important step. (Even my comments above
didn't affect the main work of the patch :-) )

So,

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>




  reply	other threads:[~2025-01-23  5:27 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-17  9:26 [PATCH 00/10] rust: pl011: correctly use interior mutability Paolo Bonzini
2025-01-17  9:26 ` [PATCH 01/10] rust: pl011: remove unnecessary "extern crate" Paolo Bonzini
2025-01-22 13:37   ` Zhao Liu
2025-01-17  9:26 ` [PATCH 02/10] rust: pl011: hide unnecessarily "pub" items from outside pl011::device Paolo Bonzini
2025-01-22 13:39   ` Zhao Liu
2025-01-17  9:26 ` [PATCH 03/10] rust: pl011: extract conversion to RegisterOffset Paolo Bonzini
2025-01-22 14:34   ` Zhao Liu
2025-01-22 15:00     ` Paolo Bonzini
2025-01-22 17:00       ` Zhao Liu
2025-01-17  9:26 ` [PATCH 04/10] rust: pl011: extract CharBackend receive logic into a separate function Paolo Bonzini
2025-01-22 14:59   ` Zhao Liu
2025-01-22 15:04     ` Paolo Bonzini
2025-01-17  9:26 ` [PATCH 05/10] rust: pl011: pull interrupt updates out of read/write ops Paolo Bonzini
2025-01-22 16:50   ` Zhao Liu
2025-01-22 16:49     ` Paolo Bonzini
2025-01-17  9:26 ` [PATCH 06/10] rust: pl011: extract PL011Registers Paolo Bonzini
2025-01-23  3:44   ` Zhao Liu
2025-01-23  8:07     ` Paolo Bonzini
2025-01-17  9:26 ` [PATCH 07/10] rust: pl011: wrap registers with BqlRefCell Paolo Bonzini
2025-01-23  5:47   ` Zhao Liu [this message]
2025-01-23  8:05     ` Paolo Bonzini
2025-01-23  9:24       ` Zhao Liu
2025-01-23 11:39         ` Paolo Bonzini
2025-01-17  9:26 ` [PATCH 08/10] rust: pl011: remove duplicate definitions Paolo Bonzini
2025-01-23  6:12   ` Zhao Liu
2025-01-17  9:26 ` [PATCH 09/10] rust: pl011: pull device-specific code out of MemoryRegionOps callbacks Paolo Bonzini
2025-01-23  6:18   ` Zhao Liu
2025-01-17  9:26 ` [PATCH 10/10] rust: qdev: make reset take a shared reference Paolo Bonzini
2025-01-23  6:19   ` Zhao Liu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Z5HX2G0+bt+3vzVB@intel.com \
    --to=zhao1.liu@intel.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-rust@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).