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

Reply via email to