From: Maciej S. Szmigiero Date: Fri, 16 May 2025 13:53:03 +0000 (+0200) Subject: migration/multifd: Don't send device state packets with zerocopy flag X-Git-Tag: v10.0.1~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7484d61bdbc88923969d8d0e2e26e8ba0935f53a;p=thirdparty%2Fqemu.git migration/multifd: Don't send device state packets with zerocopy flag If zerocopy is enabled for multifd then QIO_CHANNEL_WRITE_FLAG_ZERO_COPY flag is forced into all multifd channel write calls via p->write_flags that was setup in multifd_nocomp_send_setup(). However, device state packets aren't compatible with zerocopy - the data buffer isn't getting kept pinned until multifd channel flush. Make sure to mask that QIO_CHANNEL_WRITE_FLAG_ZERO_COPY flag in a multifd send thread if the data being sent is device state. Fixes: 0525b91a0b99 ("migration/multifd: Device state transfer support - send side") Signed-off-by: Maciej S. Szmigiero Reviewed-by: Fabiano Rosas Link: https://lore.kernel.org/r/3bd5f48578e29f3a78f41b1e4fbea3d4b2d9b136.1747403393.git.maciej.szmigiero@oracle.com Signed-off-by: Peter Xu (cherry picked from commit 6be7696129b302830a9cff7e30484e08c2d64b57) Signed-off-by: Michael Tokarev --- diff --git a/migration/multifd.c b/migration/multifd.c index dfb5189f0e..198763bada 100644 --- a/migration/multifd.c +++ b/migration/multifd.c @@ -695,6 +695,7 @@ static void *multifd_send_thread(void *opaque) if (qatomic_load_acquire(&p->pending_job)) { bool is_device_state = multifd_payload_device_state(p->data); size_t total_size; + int write_flags_masked = 0; p->flags = 0; p->iovs_num = 0; @@ -702,6 +703,9 @@ static void *multifd_send_thread(void *opaque) if (is_device_state) { multifd_device_state_send_prepare(p); + + /* Device state packets cannot be sent via zerocopy */ + write_flags_masked |= QIO_CHANNEL_WRITE_FLAG_ZERO_COPY; } else { ret = multifd_send_state->ops->send_prepare(p, &local_err); if (ret != 0) { @@ -723,7 +727,8 @@ static void *multifd_send_thread(void *opaque) &p->data->u.ram, &local_err); } else { ret = qio_channel_writev_full_all(p->c, p->iov, p->iovs_num, - NULL, 0, p->write_flags, + NULL, 0, + p->write_flags & ~write_flags_masked, &local_err); }