All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zhao Liu <zhao1.liu@intel.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-rust@nondevel.org, qemu-devel <qemu-devel@nongnu.org>,
	Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Subject: Re: Rust high-level pre/post migration callbacks
Date: Thu, 11 Sep 2025 00:24:52 +0800	[thread overview]
Message-ID: <aMGmVNdIAyrN/W4J@intel.com> (raw)
In-Reply-To: <CABgObfaBOJs73XMCUS1tPnoSYYYoKSWmjRmWnjUOb2kFL6XPJg@mail.gmail.com>

On Wed, Sep 10, 2025 at 01:33:53PM +0200, Paolo Bonzini wrote:
> Date: Wed, 10 Sep 2025 13:33:53 +0200
> From: Paolo Bonzini <pbonzini@redhat.com>
> Subject: Re: Rust high-level pre/post migration callbacks
> 
> On Wed, Sep 10, 2025 at 9:58 AM Zhao Liu <zhao1.liu@intel.com> wrote:
> > > If a pure snapshot is possible, implementing the new trait
> > > is also simple:
> > >
> > > impl_vmstate_struct!(MyDeviceRegisters, ...);
> > >
> > > impl ToMigrationState for MyDeviceRegisters {
> > >     type Migrated = Self;
> > >     fn to_migration_state(&self) ->
> >
> > Just about the name:
> >
> > `to_migration_state` and `restore_migrated_state*` sound not a proper pair.
> > What about `snapshoot_migration_state` and `restore_migration_state`?
> 
> to_migration_state is the one that creates a new migration state, but
> perhaps it could be implemented in terms of
> 
>     fn snapshot_migration_state(&self, target: &mut Self::Migrated) ->
>        Result<(), migration::InvalidError>;

Thanks for this snapshot_migration_state() example. Then I think the
original to_migration_state() is better (returning migration state in the
`Result` looks better than passing `&mut` :). )

> > > trait ToMigrationState {
> > >     type Migrated: Default + VMState;
> > >     fn to_migration_state(&self) ->
> >
> > I think maybe here it's also necessary to accept a `&mut self` since
> > device would make some changes in pre_save.
> >
> > Then this trate can provide mutable methods and ToMigrationStateShare
> > provides immuatable ones.
> 
> That should not be necessary with this approach,

Indeed, I had misunderstood this point. Rethink the pre_save: Use HPET
as the example - changing something within `pre_save` is what HPETState's
`pre_save` does, and it's unrelated to the current Migratable<>'s
`pre_save`.

Here, Migratable<>'s `pre_save` is used to assist in retrieving the
corresponding migration state.

> since all changes can
> be done in the newly-allocated migration state.

EMM, I didn't your point here... could you please talk more about this
point?

> > > impl<T> ToMigrationState for Mutex<T: ToMigrationState> {
> > >     type Migrated = T::Migrated;
> > >     fn to_migration_state(&self) ->
> > >         Result<Box<Self::Migrated>, migration::InvalidError> {
> > >         self.lock().to_migration_state()
> >
> > I'm considerring maybe we could use get_mut() (and check bql by
> > assert!(bql_locked())) instead of locking this Mutex.
> >
> > In this context, C side should hold the BQL lock so that this is
> > already a stronger protection.
> 
> For non-BQL-protected device I think you cannot know that another
> thread isn't taking the lock. For BQL the assertion is only needed in
> Migratable and BqlRefCell's implementation of ToMigrationStateShared.

Yes, I see.

> > This omits the restore_migrated_state_mut, I guess it should be
> > filled with `unimplemented!()`.
> 
> restore_migrated_state_mut() however *can* use get_mut().

Yes!

> > > unsafe impl VMState for Migratable<T: ToMigrationStateShared> {
> > >     const BASE: bindings::VMStateField = {
> > >         static VMSD: &$crate::bindings::VMStateDescription =
> > >             VMStateDescriptionBuilder::<Self>::new()
> > >                 .version_id(T::VMSD.version_id)
> > >                 .minimum_version_id(T::VMSD.minimum_version_id)
> > >                 .priority(T::VMSD.priority)
> > >                 .pre_load(Self::pre_load)
> > >                 .post_load(Self::post_load)
> > >                 .pre_save(Self::pre_save)
> > >                 .post_save(Self::post_save)
> >
> > Maybe performance is a thing, and it might be worth comparing the
> > impact of these additional callbacks.
> 
> This is only done once per device so it should be okay.

Okay, I agree.

Thanks,
Zhao



      reply	other threads:[~2025-09-10 16:03 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-06  6:45 Rust high-level pre/post migration callbacks Paolo Bonzini
2025-09-07 14:35 ` Paolo Bonzini
2025-09-08 10:02 ` Manos Pitsidianakis
2025-09-08 10:19   ` Paolo Bonzini
2025-09-08 10:25     ` Manos Pitsidianakis
2025-09-10  8:19 ` Zhao Liu
2025-09-10 11:33   ` Paolo Bonzini
2025-09-10 16:24     ` Zhao Liu [this message]

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=aMGmVNdIAyrN/W4J@intel.com \
    --to=zhao1.liu@intel.com \
    --cc=manos.pitsidianakis@linaro.org \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-rust@nondevel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.