From: Peter Xu <peterx@redhat.com>
To: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name>
Cc: "Fabiano Rosas" <farosas@suse.de>,
"Alex Williamson" <alex@shazbot.org>,
"Cédric Le Goater" <clg@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Avihai Horon" <avihaih@nvidia.com>,
qemu-devel@nongnu.org
Subject: Re: [PATCH 2/2] vfio/migration: Parallelize device state transitions
Date: Thu, 16 Jul 2026 09:30:03 -0400 [thread overview]
Message-ID: <aljc2-4XfpSkX_ay@x1.local> (raw)
In-Reply-To: <5513c20b-0f5c-4bf2-93fc-d1619e3319c1@maciej.szmigiero.name>
On Thu, Jul 16, 2026 at 02:18:34PM +0200, Maciej S. Szmigiero wrote:
> On 15.07.2026 17:30, Peter Xu wrote:
> > On Tue, Jul 14, 2026 at 10:23:05PM +0200, Maciej S. Szmigiero wrote:
> > > The VFIO devices in {PRE_COPY,RUNNING}_P2P states can {still,already} accept
> > > DMA so in the master branch by the time prepare_cb() handlers exit and
> > > cb() ones start running the VFIO devices are {still,already} capable of
> > > accepting incoming DMA.
> > >
> > > On the other hand, if you meant the state transition into STOP_COPY on the
> > > migration source currently initiated from cb() handler then there can be an
> > > ordering issue in principle.
> > >
> > > It looks like the current master branch mostly avoids this by registering
> > > vhost-net vm_state_change handler from VirtIODevice and not from its parent
> > > PCI device, so with the usual PCI topology vhost-net cb() handler will run
> > > before the VFIO PCI device one (and so still hit DMA-capable VFIO device)
> > > due to the vhost-net VirtIODevice being one level deeper in the qdev tree.
> > > It could theoretically be problem with more complex PCI topology though.
> >
> > That's an interesting observation, but neither do I think it's intentional,
> > nor do I think it guarantees the depth ordering. Consider when a VFIO
> > device is put under a few layers of PCIe switches, or PCI bridges. In that
> > case the VFIO device notifier can have larger depth value v.s. the virtio
> > device when the virtio device is attached to the root complex.
>
> Yeah, that's why I wrote that it could be a problem with "more complex PCI topology".
Ah yes.
>
> Nevertheless, that's probably uncommon enough setup to not generate visible
> complaints about things being broken.
>
> >
> > >
> > > > It is also an issue then even before P2P_DMA state introduced, because
> > > > before that all cb()s can be run at random orders.
> > >
> > > Technically, the order is based on the device qdev tree depth and within
> > > the same qdev tree depth level it looks like the handler calling order will
> > > be dependent on the order the registering devices were instantiated.
> > >
> > > This means that even before these P2P states were introduced
> > > VM configurations that instantiated VFIO/virtio devices in the certain
> > > "right" order or topology weren't affected.
> > >
> > > So maybe adding these P2P states mostly fixed this issue too?
> >
> > I still think they're two different issues, and I still think with/without
> > P2P the issue is the same, now I tend to agree this issue exists,
> > especially if virtio-blk have similar behavior like virtio-net.
> >
> > For one example of virtio-blk DMA to VFIO MMIO regions:
> >
> > https://lore.kernel.org/r/20260616052552.389021-1-gshan@redhat.com
> >
> > Said that, I don't know it's 100% triggerable in this case with notifiers,
> > but sounds relevant.
>
> It does look like it could trigger this issue indeed since it's DMA done
> to VFIO device MMIO BAR.
> However, how easy would be to reproduce this is another question.
>
> > For virtio-net and others, I have less idea.
> >
> > In all cases, I still think there are two issues to fix, and I think we
> > don't need to fix this problem in one shot. I still don't think they're
> > directly relevant, at least on the goals.
>
> Sure, let's just not make the possible race situation worse.
>
> > So with what I suggested previously relying on prepare_cb() I believe we
> > can still do the concurrency issue you're looking for, making sure when
> > reaching VFIO's cb() it's still at least accepting DMAs (P2P is fine).
>
> But that's more or less the design of this (original) patch set -
> make the state change to RUNNING_P2P on the target finish already in the
> prepare_cb() time, make the state change to STOP_COPY on the source begin
> only in the cb() time?
I am not against the idea in general. I'm against patch 1 where it hijacks
"depth" into something even more complicated.
The "depth" itself makes sense to be recorded as a value, but I think it's
already a bit confusing to call it "priority" in VMChangeStateEntry,
because it isn't: when something has higher "priority", it should always be
executed before lower priority items. Here, the current code invert the
order for !RUN case, so it's in reality "depth", not "priority".
Now patch 1 added yet another extra "adj" concept on top of qdev hierachy's
"depth", which in fact the caller needs "priority" and callers need to
explicitly handle that by checking RUNNING and invert things.
That's the part I'm definitely against. Such code is IMHO not maintainable.
So my point is if we can implement your idea with existing prepare_cb() we
should just use it. Even if we want to enhance the priority support for
cb()s, we shouldn't use patch 1. I never thought further on that because I
still assumed relying on prepare_cb() works.
>
> > For the other issue you reported, even if existed, I am not yet sure VFIO
> > is the only special case that got affected. I think it's possible some
> > other emulated devices suffer the same even if it has no direct hardware
> > attached. Say, there can be device backends got stopped in cb() when VM
> > stopped, further DMA to it may cause assertions, then it's the same issue
> > that needs solving, where essentially we may require all such devices to
> > provide similar P2P states like VFIO to make sure they initiate DMAs and
> > flush them in a prepare_cb(), then if all devices' prepare_cb() will make
> > sure no DMA to be initiated anymore, cb()s will have no ordering constraint
> > on DMAs.
>
> Although the description above is about the migration source the situation
> on the migration target is essentially a mirror image of it so I will refer
> to both cases below.
>
> Specifically:
> * on the source no device should reach non DMA accepting state (like STOP_COPY
> for VFIO) before all devices reach non DMA generating state (PRE_COPY_P2P-equivalent).
>
> * on the target no device should reach DMA generating state (RUNNING-equivalent)
> before all devices reach DMA accepting state (RUNNING_P2P-like).
>
> That's why even in the case where non-VFIO devices introduce the equivalent of
> VFIO P2P states and implement a prepare_cb() callback we still need a (VM-wide)
> sync point between these callbacks for the benefit of async state changes/threads
> since no cb()-like async state change should start until all prepare_cb()-like
> changes finish (including these for other devices).
IIUC, prepare_cb() + cb() is already that "sync point". After all
prepare_cb() done, the VM should achieve "DMA quiesced" across the system?
What's missing is we should move all problematic device cb()s "let's flush
pending DMAs" logic into a prepare_cb(), leaving the real stop logic in
cb()s. That's the 2nd problem which I think we can skip until a reproducer
pops up at least.
VFIO is only special here when it wants to concurrent process of state
changes. If you create threads in prepare_cb(), then in cb() you have
chance to synchronize everything correctly satisfying the "sync point".
That's not a requirement for most of the rest devices.
Thanks,
--
Peter Xu
prev parent reply other threads:[~2026-07-16 13:30 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-20 14:41 [PATCH 0/2] VFIO device migration parallel state transitions Maciej S. Szmigiero
2026-05-20 14:41 ` [PATCH 1/2] system/runstate: Allow adjustment of priority for VM state change handlers Maciej S. Szmigiero
2026-06-01 13:26 ` Fabiano Rosas
2026-05-20 14:41 ` [PATCH 2/2] vfio/migration: Parallelize device state transitions Maciej S. Szmigiero
2026-06-01 13:39 ` Fabiano Rosas
2026-06-01 19:33 ` Peter Xu
2026-06-02 10:01 ` Maciej S. Szmigiero
2026-06-02 20:17 ` Peter Xu
2026-06-03 21:34 ` Maciej S. Szmigiero
2026-07-02 18:36 ` Maciej S. Szmigiero
2026-07-06 16:23 ` Peter Xu
2026-07-13 20:23 ` Maciej S. Szmigiero
2026-07-14 17:06 ` Peter Xu
2026-07-14 20:23 ` Maciej S. Szmigiero
2026-07-15 15:30 ` Peter Xu
2026-07-16 12:18 ` Maciej S. Szmigiero
2026-07-16 13:30 ` Peter Xu [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=aljc2-4XfpSkX_ay@x1.local \
--to=peterx@redhat.com \
--cc=alex@shazbot.org \
--cc=avihaih@nvidia.com \
--cc=clg@redhat.com \
--cc=farosas@suse.de \
--cc=mail@maciej.szmigiero.name \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@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 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.