Message ID | 20200109144319.15912-13-eric.auger@redhat.com |
---|---|
State | New |
Headers | show |
Series | VIRTIO-IOMMU device | expand |
On Thu, Jan 09, 2020 at 03:43:18PM +0100, Eric Auger wrote: > Add Migration support. We rely on recently added gtree and qlist > migration. We only migrate the domain gtree. The endpoint gtree > is re-constructed in a post-load operation. > > Signed-off-by: Eric Auger <eric.auger@redhat.com> Acked-by: Peter Xu <peterx@redhat.com>
Eric Auger <eric.auger@redhat.com> wrote: > Add Migration support. We rely on recently added gtree and qlist > migration. We only migrate the domain gtree. The endpoint gtree > is re-constructed in a post-load operation. > > Signed-off-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> And yes, this is as confusing as it can be: a tree of mappings (i.e. key,value) a list of endpoints I will propose this as most complex structure migrated ever. Later, Juan.
Hi Juan, On 2/10/20 1:33 PM, Juan Quintela wrote: > Eric Auger <eric.auger@redhat.com> wrote: >> Add Migration support. We rely on recently added gtree and qlist >> migration. We only migrate the domain gtree. The endpoint gtree >> is re-constructed in a post-load operation. >> >> Signed-off-by: Eric Auger <eric.auger@redhat.com> > > Reviewed-by: Juan Quintela <quintela@redhat.com> > > And yes, this is as confusing as it can be: > a tree of mappings (i.e. key,value) > a list of endpoints > > I will propose this as most complex structure migrated ever. :-) Thank you Juan, Dave, and Peter for your support Best Regards Eric > > Later, Juan. >
Hi Juan, On 2/10/20 2:09 PM, Auger Eric wrote: > Hi Juan, > > On 2/10/20 1:33 PM, Juan Quintela wrote: >> Eric Auger <eric.auger@redhat.com> wrote: >>> Add Migration support. We rely on recently added gtree and qlist >>> migration. We only migrate the domain gtree. The endpoint gtree >>> is re-constructed in a post-load operation. >>> >>> Signed-off-by: Eric Auger <eric.auger@redhat.com> >> >> Reviewed-by: Juan Quintela <quintela@redhat.com> >> >> And yes, this is as confusing as it can be: >> a tree of mappings (i.e. key,value) >> a list of endpoints >> >> I will propose this as most complex structure migrated ever. > :-) Thank you Juan, Dave, and Peter for your support I did not notice this at the first glimpse but could you send the R-b on the v15. I have been running like a hamster on my wheel during last week. Code has not changed though :-). Thanks Eric > > Best Regards > > Eric >> >> Later, Juan. >> > >
Auger Eric <eric.auger@redhat.com> wrote: > Hi Juan, > > On 2/10/20 2:09 PM, Auger Eric wrote: >> Hi Juan, >> >> On 2/10/20 1:33 PM, Juan Quintela wrote: >>> Eric Auger <eric.auger@redhat.com> wrote: >>>> Add Migration support. We rely on recently added gtree and qlist >>>> migration. We only migrate the domain gtree. The endpoint gtree >>>> is re-constructed in a post-load operation. >>>> >>>> Signed-off-by: Eric Auger <eric.auger@redhat.com> >>> >>> Reviewed-by: Juan Quintela <quintela@redhat.com> >>> >>> And yes, this is as confusing as it can be: >>> a tree of mappings (i.e. key,value) >>> a list of endpoints >>> >>> I will propose this as most complex structure migrated ever. >> :-) Thank you Juan, Dave, and Peter for your support > > I did not notice this at the first glimpse but could you send the R-b on > the v15. I have been running like a hamster on my wheel during last week. > > Code has not changed though :-). Sure. Later, Juan.
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 09193970ee..b0fde3af6f 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -655,16 +655,6 @@ static uint64_t virtio_iommu_get_features(VirtIODevice *vdev, uint64_t f, return f; } -/* - * Migration is not yet supported: most of the state consists - * of balanced binary trees which are not yet ready for getting - * migrated - */ -static const VMStateDescription vmstate_virtio_iommu_device = { - .name = "virtio-iommu-device", - .unmigratable = 1, -}; - static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data) { guint ua = GPOINTER_TO_UINT(a); @@ -748,9 +738,108 @@ static void virtio_iommu_instance_init(Object *obj) { } +#define VMSTATE_INTERVAL \ +{ \ + .name = "interval", \ + .version_id = 1, \ + .minimum_version_id = 1, \ + .fields = (VMStateField[]) { \ + VMSTATE_UINT64(low, VirtIOIOMMUInterval), \ + VMSTATE_UINT64(high, VirtIOIOMMUInterval), \ + VMSTATE_END_OF_LIST() \ + } \ +} + +#define VMSTATE_MAPPING \ +{ \ + .name = "mapping", \ + .version_id = 1, \ + .minimum_version_id = 1, \ + .fields = (VMStateField[]) { \ + VMSTATE_UINT64(phys_addr, VirtIOIOMMUMapping),\ + VMSTATE_UINT32(flags, VirtIOIOMMUMapping), \ + VMSTATE_END_OF_LIST() \ + }, \ +} + +static const VMStateDescription vmstate_interval_mapping[2] = { + VMSTATE_MAPPING, /* value */ + VMSTATE_INTERVAL /* key */ +}; + +static int domain_preload(void *opaque) +{ + VirtIOIOMMUDomain *domain = opaque; + + domain->mappings = g_tree_new_full((GCompareDataFunc)interval_cmp, + NULL, g_free, g_free); + return 0; +} + +static const VMStateDescription vmstate_endpoint = { + .name = "endpoint", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(id, VirtIOIOMMUEndpoint), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_domain = { + .name = "domain", + .version_id = 1, + .minimum_version_id = 1, + .pre_load = domain_preload, + .fields = (VMStateField[]) { + VMSTATE_UINT32(id, VirtIOIOMMUDomain), + VMSTATE_GTREE_V(mappings, VirtIOIOMMUDomain, 1, + vmstate_interval_mapping, + VirtIOIOMMUInterval, VirtIOIOMMUMapping), + VMSTATE_QLIST_V(endpoint_list, VirtIOIOMMUDomain, 1, + vmstate_endpoint, VirtIOIOMMUEndpoint, next), + VMSTATE_END_OF_LIST() + } +}; + +static gboolean reconstruct_endpoints(gpointer key, gpointer value, + gpointer data) +{ + VirtIOIOMMU *s = (VirtIOIOMMU *)data; + VirtIOIOMMUDomain *d = (VirtIOIOMMUDomain *)value; + VirtIOIOMMUEndpoint *iter; + + QLIST_FOREACH(iter, &d->endpoint_list, next) { + iter->domain = d; + g_tree_insert(s->endpoints, GUINT_TO_POINTER(iter->id), iter); + } + return false; /* continue the domain traversal */ +} + +static int iommu_post_load(void *opaque, int version_id) +{ + VirtIOIOMMU *s = opaque; + + g_tree_foreach(s->domains, reconstruct_endpoints, s); + return 0; +} + +static const VMStateDescription vmstate_virtio_iommu_device = { + .name = "virtio-iommu-device", + .minimum_version_id = 1, + .version_id = 1, + .post_load = iommu_post_load, + .fields = (VMStateField[]) { + VMSTATE_GTREE_DIRECT_KEY_V(domains, VirtIOIOMMU, 1, + &vmstate_domain, VirtIOIOMMUDomain), + VMSTATE_END_OF_LIST() + }, +}; + static const VMStateDescription vmstate_virtio_iommu = { .name = "virtio-iommu", .minimum_version_id = 1, + .priority = MIG_PRI_IOMMU, .version_id = 1, .fields = (VMStateField[]) { VMSTATE_VIRTIO_DEVICE,
Add Migration support. We rely on recently added gtree and qlist migration. We only migrate the domain gtree. The endpoint gtree is re-constructed in a post-load operation. Signed-off-by: Eric Auger <eric.auger@redhat.com> --- v11 -> v12: - do not migrate the endpoint gtree but reconstruct it from the domain gtree (Peter's suggestion) - add MIG_PRI_IOMMU --- hw/virtio/virtio-iommu.c | 109 +++++++++++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 10 deletions(-)