[3/5] vfio/migration: tracking of dirty page in system memory

Submitted by Zhao, Yan Y on Feb. 19, 2019, 8:52 a.m.

Details

Message ID 1550566361-3697-1-git-send-email-yan.y.zhao@intel.com
State New
Headers show
Series "QEMU VFIO live migration" ( rev: 1 ) in Intel GVT devel

Not browsing as part of any series.

Commit Message

Zhao, Yan Y Feb. 19, 2019, 8:52 a.m.
register the log_sync interface to hook into ram's live migration
callbacks.

ram_save_pending
   |->migration_bitmap_sync
       |->memory_global_dirty_log_sync
           |->memory_region_sync_dirty_bitmap
               |->listener->log_sync(listener, &mrs);

So, the dirty page produced by vfio device in system memory will be
save/load by ram's live migration code iteratively.

Bitmap of device's dirty page in system memory is retrieved from Dirty Bitmap
Region

Signed-off-by: Yan Zhao <yan.y.zhao@intel.com>
Signed-off-by: Yulei Zhang <yulei.zhang@intel.com>
---
 hw/vfio/common.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

Patch hide | download patch | download mbox

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 7c185e5a..719e750 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -27,6 +27,7 @@ 
 
 #include "hw/vfio/vfio-common.h"
 #include "hw/vfio/vfio.h"
+#include "hw/vfio/pci.h"
 #include "exec/address-spaces.h"
 #include "exec/memory.h"
 #include "hw/hw.h"
@@ -698,9 +699,34 @@  static void vfio_listener_region_del(MemoryListener *listener,
     }
 }
 
+static void vfio_log_sync(MemoryListener *listener,
+                          MemoryRegionSection *section)
+{
+    VFIOContainer *container = container_of(listener, VFIOContainer, listener);
+    VFIOGroup *group = QLIST_FIRST(&container->group_list);
+    VFIODevice *vbasedev;
+    VFIOPCIDevice *vdev;
+
+    ram_addr_t size = int128_get64(section->size);
+    uint64_t page_nr = size >> TARGET_PAGE_BITS;
+    uint64_t start_addr = section->offset_within_address_space;
+
+    QLIST_FOREACH(vbasedev, &group->device_list, next) {
+        vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev);
+        if (!vdev->migration ||
+                !vfio_device_data_cap_system_memory(vdev) ||
+                !(vdev->migration->device_state & VFIO_DEVICE_STATE_LOGGING)) {
+            continue;
+        }
+
+        vfio_set_dirty_page_bitmap(vdev, start_addr, page_nr);
+    }
+}
+
 static const MemoryListener vfio_memory_listener = {
     .region_add = vfio_listener_region_add,
     .region_del = vfio_listener_region_del,
+    .log_sync = vfio_log_sync,
 };
 
 static void vfio_listener_release(VFIOContainer *container)