aboutsummaryrefslogtreecommitdiff
path: root/lib/migration.c
diff options
context:
space:
mode:
authorThanos Makatos <thanos.makatos@nutanix.com>2021-01-26 14:38:08 +0000
committerGitHub <noreply@github.com>2021-01-26 14:38:08 +0000
commiteb7acbddfee4a51e20444807858421b6cbd54291 (patch)
treece4a59b5ad923784680a681d183c03d2d5446271 /lib/migration.c
parentae3aa60d6676f656f80dc293644f681bdbac5eb6 (diff)
downloadlibvfio-user-eb7acbddfee4a51e20444807858421b6cbd54291.zip
libvfio-user-eb7acbddfee4a51e20444807858421b6cbd54291.tar.gz
libvfio-user-eb7acbddfee4a51e20444807858421b6cbd54291.tar.bz2
cache pending_bytes (#246)
In VFIO, pending_bytes can be re-read and each time it's read the device can return a new value (even higher than the previous one). Rather than exposing the vfio-user device implementation to such complicated semantics, we cache pending_bytes and handle repeated calls to it ourselves. Even if pending_bytes does change in the device, the client will either way read it as a part of the current migration iteration. Signed-off-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib/migration.c')
-rw-r--r--lib/migration.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/lib/migration.c b/lib/migration.c
index f4e6931..3577cad 100644
--- a/lib/migration.c
+++ b/lib/migration.c
@@ -61,6 +61,7 @@ struct migration {
*/
struct {
enum migr_iter_state state;
+ __u64 pending_bytes;
__u64 offset;
__u64 size;
} iter;
@@ -251,8 +252,6 @@ handle_pending_bytes(vfu_ctx_t *vfu_ctx, struct migration *migr,
return 0;
}
- *pending_bytes = migr->callbacks.get_pending_bytes(vfu_ctx);
-
switch (migr->iter.state) {
case VFIO_USER_MIGR_ITER_STATE_INITIAL:
case VFIO_USER_MIGR_ITER_STATE_DATA_PREPARED:
@@ -260,6 +259,8 @@ handle_pending_bytes(vfu_ctx_t *vfu_ctx, struct migration *migr,
* FIXME what happens if data haven't been consumed in the previous
* iteration? Check https://www.spinics.net/lists/kvm/msg228608.html.
*/
+ *pending_bytes = migr->iter.pending_bytes = migr->callbacks.get_pending_bytes(vfu_ctx);
+
if (*pending_bytes == 0) {
migr_state_transition(migr, VFIO_USER_MIGR_ITER_STATE_FINISHED);
} else {
@@ -268,11 +269,11 @@ handle_pending_bytes(vfu_ctx_t *vfu_ctx, struct migration *migr,
break;
case VFIO_USER_MIGR_ITER_STATE_STARTED:
/*
- * Repeated reads of pending_bytes should not have any side effects.
- * FIXME does it have to be the same as the previous value? Can it
- * increase or even decrease? I suppose it can't be lower than
- * data_size? Ask on LKML.
+ * FIXME We might be wrong returning a cached value, check
+ * https://www.spinics.net/lists/kvm/msg228608.html
+ *
*/
+ *pending_bytes = migr->iter.pending_bytes;
break;
default:
return -EINVAL;