On Mon, May 18, 2020 at 11:43:09AM +0530, Kirti Wankhede wrote: <...> > + > +static int vfio_save_buffer(QEMUFile *f, VFIODevice *vbasedev) > +{ > + VFIOMigration *migration = vbasedev->migration; > + VFIORegion *region = &migration->region; > + uint64_t data_offset = 0, data_size = 0; > + int ret; > + > + ret = pread(vbasedev->fd, &data_offset, sizeof(data_offset), > + region->fd_offset + offsetof(struct > vfio_device_migration_info, > + data_offset)); > + if (ret != sizeof(data_offset)) { > + error_report("%s: Failed to get migration buffer data offset %d", > + vbasedev->name, ret); > + return -EINVAL; > + } > + > + ret = pread(vbasedev->fd, &data_size, sizeof(data_size), > + region->fd_offset + offsetof(struct > vfio_device_migration_info, > + data_size)); > + if (ret != sizeof(data_size)) { > + error_report("%s: Failed to get migration buffer data size %d", > + vbasedev->name, ret); > + return -EINVAL; > + } > + > + if (data_size > 0) { > + void *buf = NULL; > + bool buffer_mmaped; > + > + if (region->mmaps) { > + buf = find_data_region(region, data_offset, data_size); > + } > + > + buffer_mmaped = (buf != NULL); > + > + if (!buffer_mmaped) { > + buf = g_try_malloc(data_size); > + if (!buf) { > + error_report("%s: Error allocating buffer ", __func__); > + return -ENOMEM; > + } > + > + ret = pread(vbasedev->fd, buf, data_size, > + region->fd_offset + data_offset); > + if (ret != data_size) { > + error_report("%s: Failed to get migration data %d", > + vbasedev->name, ret); > + g_free(buf); > + return -EINVAL; > + } > + } > + > + qemu_put_be64(f, data_size); > + qemu_put_buffer(f, buf, data_size); > + > + if (!buffer_mmaped) { > + g_free(buf); > + } > + } else { > + qemu_put_be64(f, data_size); > + } > + > + trace_vfio_save_buffer(vbasedev->name, data_offset, data_size, > + migration->pending_bytes); > + > + ret = qemu_file_get_error(f); > + if (ret) { > + return ret; > + } > + > + return data_size; > +} > + > +static int vfio_update_pending(VFIODevice *vbasedev) > +{ > + VFIOMigration *migration = vbasedev->migration; > + VFIORegion *region = &migration->region; > + uint64_t pending_bytes = 0; > + int ret; > + > + ret = pread(vbasedev->fd, &pending_bytes, sizeof(pending_bytes), > + region->fd_offset + offsetof(struct > vfio_device_migration_info, > + pending_bytes)); > + if ((ret < 0) || (ret != sizeof(pending_bytes))) { > + error_report("%s: Failed to get pending bytes %d", > + vbasedev->name, ret); > + migration->pending_bytes = 0; > + return (ret < 0) ? ret : -EINVAL; > + } > + > + migration->pending_bytes = pending_bytes; > + trace_vfio_update_pending(vbasedev->name, pending_bytes); > + return 0; > +} > + <...> > > +static void vfio_save_pending(QEMUFile *f, void *opaque, > + uint64_t threshold_size, > + uint64_t *res_precopy_only, > + uint64_t *res_compatible, > + uint64_t *res_postcopy_only) > +{ > + VFIODevice *vbasedev = opaque; > + VFIOMigration *migration = vbasedev->migration; > + int ret; > + > + ret = vfio_update_pending(vbasedev); > + if (ret) { > + return; > + } > + > + *res_precopy_only += migration->pending_bytes; > + > + trace_vfio_save_pending(vbasedev->name, *res_precopy_only, > + *res_postcopy_only, *res_compatible); > +} > + > +static int vfio_save_iterate(QEMUFile *f, void *opaque) > +{ > + VFIODevice *vbasedev = opaque; > + VFIOMigration *migration = vbasedev->migration; > + int ret, data_size; > + > + qemu_put_be64(f, VFIO_MIG_FLAG_DEV_DATA_STATE); > + hi Kirti seems you also didn't address my previous comments. https://lists.gnu.org/archive/html/qemu-devel/2020-05/msg02795.html. https://lists.gnu.org/archive/html/qemu-devel/2020-05/msg02796.html
> + if (migration->pending_bytes == 0) { > + ret = vfio_update_pending(vbasedev); repeated get pending_bytes here would cause vmstats following vfio-pci have no chance to get called. Thanks Yan > + if (ret) { > + return ret; > + } > + > + if (migration->pending_bytes == 0) { > + /* indicates data finished, goto complete phase */ > + return 1; > + } > + } > + > + data_size = vfio_save_buffer(f, vbasedev); > + > + if (data_size < 0) { > + error_report("%s: vfio_save_buffer failed %s", vbasedev->name, > + strerror(errno)); > + return data_size; > + } > + > + qemu_put_be64(f, VFIO_MIG_FLAG_END_OF_STATE); > + > + ret = qemu_file_get_error(f); > + if (ret) { > + return ret; > + } > + > + trace_vfio_save_iterate(vbasedev->name, data_size); > + > + return 0; > +} > + <...>