diff mbox series

[v26,12/17] vfio: Add function to start and stop dirty pages tracking

Message ID 1600817059-26721-13-git-send-email-kwankhede@nvidia.com
State New
Headers show
Series Add migration support for VFIO devices | expand

Commit Message

Kirti Wankhede Sept. 22, 2020, 11:24 p.m. UTC
Call VFIO_IOMMU_DIRTY_PAGES ioctl to start and stop dirty pages tracking
for VFIO devices.

Signed-off-by: Kirti Wankhede <kwankhede@nvidia.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
 hw/vfio/migration.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

Comments

Alex Williamson Sept. 25, 2020, 9:55 p.m. UTC | #1
On Wed, 23 Sep 2020 04:54:14 +0530
Kirti Wankhede <kwankhede@nvidia.com> wrote:

> Call VFIO_IOMMU_DIRTY_PAGES ioctl to start and stop dirty pages tracking

> for VFIO devices.

> 

> Signed-off-by: Kirti Wankhede <kwankhede@nvidia.com>

> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

> ---

>  hw/vfio/migration.c | 36 ++++++++++++++++++++++++++++++++++++

>  1 file changed, 36 insertions(+)

> 

> diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c

> index 4306f6316417..822b68b4e015 100644

> --- a/hw/vfio/migration.c

> +++ b/hw/vfio/migration.c

> @@ -11,6 +11,7 @@

>  #include "qemu/main-loop.h"

>  #include "qemu/cutils.h"

>  #include <linux/vfio.h>

> +#include <sys/ioctl.h>

>  

>  #include "sysemu/runstate.h"

>  #include "hw/vfio/vfio-common.h"

> @@ -355,6 +356,32 @@ static int vfio_load_device_config_state(QEMUFile *f, void *opaque)

>      return qemu_file_get_error(f);

>  }

>  

> +static int vfio_set_dirty_page_tracking(VFIODevice *vbasedev, bool start)

> +{

> +    int ret;

> +    VFIOContainer *container = vbasedev->group->container;

> +    struct vfio_iommu_type1_dirty_bitmap dirty = {

> +        .argsz = sizeof(dirty),

> +    };

> +

> +    if (start) {

> +        if (vbasedev->device_state & VFIO_DEVICE_STATE_SAVING) {

> +            dirty.flags = VFIO_IOMMU_DIRTY_PAGES_FLAG_START;

> +        } else {

> +            return -EINVAL;

> +        }

> +    } else {

> +            dirty.flags = VFIO_IOMMU_DIRTY_PAGES_FLAG_STOP;

> +    }

> +

> +    ret = ioctl(container->fd, VFIO_IOMMU_DIRTY_PAGES, &dirty);

> +    if (ret) {

> +        error_report("Failed to set dirty tracking flag 0x%x errno: %d",

> +                     dirty.flags, errno);

> +    }


Maybe doesn't matter in the long run, but do you want to use -errno for
the return rather than -1 from the ioctl on error?  Thanks,

Alex

> +    return ret;

> +}

> +

>  /* ---------------------------------------------------------------------- */

>  

>  static int vfio_save_setup(QEMUFile *f, void *opaque)

> @@ -386,6 +413,11 @@ static int vfio_save_setup(QEMUFile *f, void *opaque)

>          return ret;

>      }

>  

> +    ret = vfio_set_dirty_page_tracking(vbasedev, true);

> +    if (ret) {

> +        return ret;

> +    }

> +

>      qemu_put_be64(f, VFIO_MIG_FLAG_END_OF_STATE);

>  

>      ret = qemu_file_get_error(f);

> @@ -401,6 +433,8 @@ static void vfio_save_cleanup(void *opaque)

>      VFIODevice *vbasedev = opaque;

>      VFIOMigration *migration = vbasedev->migration;

>  

> +    vfio_set_dirty_page_tracking(vbasedev, false);

> +

>      if (migration->region.mmaps) {

>          vfio_region_unmap(&migration->region);

>      }

> @@ -734,6 +768,8 @@ static void vfio_migration_state_notifier(Notifier *notifier, void *data)

>          if (ret) {

>              error_report("%s: Failed to set state RUNNING", vbasedev->name);

>          }

> +

> +        vfio_set_dirty_page_tracking(vbasedev, false);

>      }

>  }

>
Kirti Wankhede Oct. 18, 2020, 8:52 p.m. UTC | #2
On 9/26/2020 3:25 AM, Alex Williamson wrote:
> On Wed, 23 Sep 2020 04:54:14 +0530

> Kirti Wankhede <kwankhede@nvidia.com> wrote:

> 

>> Call VFIO_IOMMU_DIRTY_PAGES ioctl to start and stop dirty pages tracking

>> for VFIO devices.

>>

>> Signed-off-by: Kirti Wankhede <kwankhede@nvidia.com>

>> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

>> ---

>>   hw/vfio/migration.c | 36 ++++++++++++++++++++++++++++++++++++

>>   1 file changed, 36 insertions(+)

>>

>> diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c

>> index 4306f6316417..822b68b4e015 100644

>> --- a/hw/vfio/migration.c

>> +++ b/hw/vfio/migration.c

>> @@ -11,6 +11,7 @@

>>   #include "qemu/main-loop.h"

>>   #include "qemu/cutils.h"

>>   #include <linux/vfio.h>

>> +#include <sys/ioctl.h>

>>   

>>   #include "sysemu/runstate.h"

>>   #include "hw/vfio/vfio-common.h"

>> @@ -355,6 +356,32 @@ static int vfio_load_device_config_state(QEMUFile *f, void *opaque)

>>       return qemu_file_get_error(f);

>>   }

>>   

>> +static int vfio_set_dirty_page_tracking(VFIODevice *vbasedev, bool start)

>> +{

>> +    int ret;

>> +    VFIOContainer *container = vbasedev->group->container;

>> +    struct vfio_iommu_type1_dirty_bitmap dirty = {

>> +        .argsz = sizeof(dirty),

>> +    };

>> +

>> +    if (start) {

>> +        if (vbasedev->device_state & VFIO_DEVICE_STATE_SAVING) {

>> +            dirty.flags = VFIO_IOMMU_DIRTY_PAGES_FLAG_START;

>> +        } else {

>> +            return -EINVAL;

>> +        }

>> +    } else {

>> +            dirty.flags = VFIO_IOMMU_DIRTY_PAGES_FLAG_STOP;

>> +    }

>> +

>> +    ret = ioctl(container->fd, VFIO_IOMMU_DIRTY_PAGES, &dirty);

>> +    if (ret) {

>> +        error_report("Failed to set dirty tracking flag 0x%x errno: %d",

>> +                     dirty.flags, errno);

>> +    }

> 

> Maybe doesn't matter in the long run, but do you want to use -errno for

> the return rather than -1 from the ioctl on error?  Thanks,

> 


Makes sense. Changing it.

Thanks,
Kirti

> Alex

> 

>> +    return ret;

>> +}

>> +

>>   /* ---------------------------------------------------------------------- */

>>   

>>   static int vfio_save_setup(QEMUFile *f, void *opaque)

>> @@ -386,6 +413,11 @@ static int vfio_save_setup(QEMUFile *f, void *opaque)

>>           return ret;

>>       }

>>   

>> +    ret = vfio_set_dirty_page_tracking(vbasedev, true);

>> +    if (ret) {

>> +        return ret;

>> +    }

>> +

>>       qemu_put_be64(f, VFIO_MIG_FLAG_END_OF_STATE);

>>   

>>       ret = qemu_file_get_error(f);

>> @@ -401,6 +433,8 @@ static void vfio_save_cleanup(void *opaque)

>>       VFIODevice *vbasedev = opaque;

>>       VFIOMigration *migration = vbasedev->migration;

>>   

>> +    vfio_set_dirty_page_tracking(vbasedev, false);

>> +

>>       if (migration->region.mmaps) {

>>           vfio_region_unmap(&migration->region);

>>       }

>> @@ -734,6 +768,8 @@ static void vfio_migration_state_notifier(Notifier *notifier, void *data)

>>           if (ret) {

>>               error_report("%s: Failed to set state RUNNING", vbasedev->name);

>>           }

>> +

>> +        vfio_set_dirty_page_tracking(vbasedev, false);

>>       }

>>   }

>>   

>
diff mbox series

Patch

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 4306f6316417..822b68b4e015 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -11,6 +11,7 @@ 
 #include "qemu/main-loop.h"
 #include "qemu/cutils.h"
 #include <linux/vfio.h>
+#include <sys/ioctl.h>
 
 #include "sysemu/runstate.h"
 #include "hw/vfio/vfio-common.h"
@@ -355,6 +356,32 @@  static int vfio_load_device_config_state(QEMUFile *f, void *opaque)
     return qemu_file_get_error(f);
 }
 
+static int vfio_set_dirty_page_tracking(VFIODevice *vbasedev, bool start)
+{
+    int ret;
+    VFIOContainer *container = vbasedev->group->container;
+    struct vfio_iommu_type1_dirty_bitmap dirty = {
+        .argsz = sizeof(dirty),
+    };
+
+    if (start) {
+        if (vbasedev->device_state & VFIO_DEVICE_STATE_SAVING) {
+            dirty.flags = VFIO_IOMMU_DIRTY_PAGES_FLAG_START;
+        } else {
+            return -EINVAL;
+        }
+    } else {
+            dirty.flags = VFIO_IOMMU_DIRTY_PAGES_FLAG_STOP;
+    }
+
+    ret = ioctl(container->fd, VFIO_IOMMU_DIRTY_PAGES, &dirty);
+    if (ret) {
+        error_report("Failed to set dirty tracking flag 0x%x errno: %d",
+                     dirty.flags, errno);
+    }
+    return ret;
+}
+
 /* ---------------------------------------------------------------------- */
 
 static int vfio_save_setup(QEMUFile *f, void *opaque)
@@ -386,6 +413,11 @@  static int vfio_save_setup(QEMUFile *f, void *opaque)
         return ret;
     }
 
+    ret = vfio_set_dirty_page_tracking(vbasedev, true);
+    if (ret) {
+        return ret;
+    }
+
     qemu_put_be64(f, VFIO_MIG_FLAG_END_OF_STATE);
 
     ret = qemu_file_get_error(f);
@@ -401,6 +433,8 @@  static void vfio_save_cleanup(void *opaque)
     VFIODevice *vbasedev = opaque;
     VFIOMigration *migration = vbasedev->migration;
 
+    vfio_set_dirty_page_tracking(vbasedev, false);
+
     if (migration->region.mmaps) {
         vfio_region_unmap(&migration->region);
     }
@@ -734,6 +768,8 @@  static void vfio_migration_state_notifier(Notifier *notifier, void *data)
         if (ret) {
             error_report("%s: Failed to set state RUNNING", vbasedev->name);
         }
+
+        vfio_set_dirty_page_tracking(vbasedev, false);
     }
 }