diff mbox series

[v12,12/13] virtio-iommu: Support migration

Message ID 20200109144319.15912-13-eric.auger@redhat.com
State New
Headers show
Series VIRTIO-IOMMU device | expand

Commit Message

Eric Auger Jan. 9, 2020, 2:43 p.m. UTC
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(-)

Comments

Peter Xu Jan. 14, 2020, 7:07 p.m. UTC | #1
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>
Juan Quintela Feb. 10, 2020, 12:33 p.m. UTC | #2
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.
Eric Auger Feb. 10, 2020, 1:09 p.m. UTC | #3
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.
>
Eric Auger Feb. 10, 2020, 1:36 p.m. UTC | #4
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.
>>
> 
>
Juan Quintela Feb. 10, 2020, 4:44 p.m. UTC | #5
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 mbox series

Patch

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,