On Fri, 13 Jun 2026, Koushik Dutta wrote:
> + VMSTATE_UINT32(rx_coal_usecs, VirtIONet),
> + VMSTATE_UINT32(tx_coal_usecs, VirtIONet),
> + VMSTATE_UINT32(rx_coal_packets, VirtIONet),
> + VMSTATE_UINT32(tx_coal_packets, VirtIONet),
> VMSTATE_END_OF_LIST()
> },
These new fields are added directly to the main
vmstate_virtio_net_device fields list, which breaks both forward and
backward migration:
- Forward: old QEMU produces a shorter stream; new QEMU expects
more fields and fails to load.
- Backward: new QEMU emits extra fields that shift the stream
layout for older QEMU.
They should go in a subsection with a .needed predicate instead:
static bool has_notf_coal(void *opaque, int version_id)
{
return virtio_vdev_has_feature(VIRTIO_DEVICE(opaque),
VIRTIO_NET_F_NOTF_COAL);
}
static const VMStateDescription vmstate_virtio_net_coal = {
.name = "virtio-net/notf_coal",
.needed = has_notf_coal,
.fields = (const VMStateField[]) {
VMSTATE_UINT32(rx_coal_usecs, VirtIONet),
VMSTATE_UINT32(rx_coal_packets, VirtIONet),
VMSTATE_UINT32(tx_coal_usecs, VirtIONet),
VMSTATE_UINT32(tx_coal_packets, VirtIONet),
VMSTATE_END_OF_LIST()
}
};
and registered in the .subsections array of
vmstate_virtio_net_device.
Regards,
Bin Guo