From 2a543bfdfadb432d82bab256a9a72b00c331b484 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Mon, 24 Jul 2017 12:51:59 +0200 Subject: migration: Teach it about G_SOURCE_REMOVE As this is defined on glib 2.32, add compatibility macros for older glibs. Signed-off-by: Juan Quintela Reviewed-by: Daniel P. Berrange Reviewed-by: Peter Xu --- include/glib-compat.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/glib-compat.h b/include/glib-compat.h index fcffcd3f07..e15aca2d40 100644 --- a/include/glib-compat.h +++ b/include/glib-compat.h @@ -223,6 +223,8 @@ static inline gboolean g_hash_table_contains(GHashTable *hash_table, { return g_hash_table_lookup_extended(hash_table, key, NULL, NULL); } +#define G_SOURCE_CONTINUE TRUE +#define G_SOURCE_REMOVE FALSE #endif #ifndef g_assert_true -- cgit v1.2.3-55-g7522 From fc7deeea26af3d08f45bad85b8bd3fc3d790a090 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Wed, 30 Aug 2017 16:31:59 +0800 Subject: bitmap: introduce bitmap_count_one() Count how many bits set in the bitmap. Reviewed-by: Dr. David Alan Gilbert Signed-off-by: Peter Xu Reviewed-by: Juan Quintela Signed-off-by: Juan Quintela --- include/qemu/bitmap.h | 10 ++++++++++ util/bitmap.c | 15 +++++++++++++++ 2 files changed, 25 insertions(+) (limited to 'include') diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h index c318da12d7..2718706edb 100644 --- a/include/qemu/bitmap.h +++ b/include/qemu/bitmap.h @@ -82,6 +82,7 @@ int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, long bits); int slow_bitmap_intersects(const unsigned long *bitmap1, const unsigned long *bitmap2, long bits); +long slow_bitmap_count_one(const unsigned long *bitmap, long nbits); static inline unsigned long *bitmap_try_new(long nbits) { @@ -216,6 +217,15 @@ static inline int bitmap_intersects(const unsigned long *src1, } } +static inline long bitmap_count_one(const unsigned long *bitmap, long nbits) +{ + if (small_nbits(nbits)) { + return ctpopl(*bitmap & BITMAP_LAST_WORD_MASK(nbits)); + } else { + return slow_bitmap_count_one(bitmap, nbits); + } +} + void bitmap_set(unsigned long *map, long i, long len); void bitmap_set_atomic(unsigned long *map, long i, long len); void bitmap_clear(unsigned long *map, long start, long nr); diff --git a/util/bitmap.c b/util/bitmap.c index efced9a7d8..90a42ff625 100644 --- a/util/bitmap.c +++ b/util/bitmap.c @@ -355,3 +355,18 @@ int slow_bitmap_intersects(const unsigned long *bitmap1, } return 0; } + +long slow_bitmap_count_one(const unsigned long *bitmap, long nbits) +{ + long k, lim = nbits / BITS_PER_LONG, result = 0; + + for (k = 0; k < lim; k++) { + result += ctpopl(bitmap[k]); + } + + if (nbits % BITS_PER_LONG) { + result += ctpopl(bitmap[k] & BITMAP_LAST_WORD_MASK(nbits)); + } + + return result; +} -- cgit v1.2.3-55-g7522 From d7788151a0807d5d2d410e3f8944d8c8a651f8d2 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Wed, 30 Aug 2017 16:32:00 +0800 Subject: bitmap: provide to_le/from_le helpers Provide helpers to convert bitmaps to little endian format. It can be used when we want to send one bitmap via network to some other hosts. One thing to mention is that, these helpers only solve the problem of endianess, but it does not solve the problem of different word size on machines (the bitmaps managing same count of bits may contains different size when malloced). So we need to take care of the size alignment issue on the callers for now. Signed-off-by: Peter Xu Reviewed-by: Juan Quintela Signed-off-by: Juan Quintela --- include/qemu/bitmap.h | 7 +++++++ util/bitmap.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) (limited to 'include') diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h index 2718706edb..509eeddece 100644 --- a/include/qemu/bitmap.h +++ b/include/qemu/bitmap.h @@ -39,6 +39,8 @@ * bitmap_clear(dst, pos, nbits) Clear specified bit area * bitmap_test_and_clear_atomic(dst, pos, nbits) Test and clear area * bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area + * bitmap_to_le(dst, src, nbits) Convert bitmap to little endian + * bitmap_from_le(dst, src, nbits) Convert bitmap from little endian */ /* @@ -247,4 +249,9 @@ static inline unsigned long *bitmap_zero_extend(unsigned long *old, return new; } +void bitmap_to_le(unsigned long *dst, const unsigned long *src, + long nbits); +void bitmap_from_le(unsigned long *dst, const unsigned long *src, + long nbits); + #endif /* BITMAP_H */ diff --git a/util/bitmap.c b/util/bitmap.c index 90a42ff625..cb618c65a5 100644 --- a/util/bitmap.c +++ b/util/bitmap.c @@ -370,3 +370,35 @@ long slow_bitmap_count_one(const unsigned long *bitmap, long nbits) return result; } + +static void bitmap_to_from_le(unsigned long *dst, + const unsigned long *src, long nbits) +{ + long len = BITS_TO_LONGS(nbits); + +#ifdef HOST_WORDS_BIGENDIAN + long index; + + for (index = 0; index < len; index++) { +# if HOST_LONG_BITS == 64 + dst[index] = bswap64(src[index]); +# else + dst[index] = bswap32(src[index]); +# endif + } +#else + memcpy(dst, src, len * sizeof(unsigned long)); +#endif +} + +void bitmap_from_le(unsigned long *dst, const unsigned long *src, + long nbits) +{ + bitmap_to_from_le(dst, src, nbits); +} + +void bitmap_to_le(unsigned long *dst, const unsigned long *src, + long nbits) +{ + bitmap_to_from_le(dst, src, nbits); +} -- cgit v1.2.3-55-g7522 From c6467627369b2518ea3cf466da6cd39da7e3a85a Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Mon, 10 Jul 2017 19:30:14 +0300 Subject: migration: add has_postcopy savevm handler Now postcopy-able states are recognized by not NULL save_live_complete_postcopy handler. But when we have several different postcopy-able states, it is not convenient. Ram postcopy may be disabled, while some other postcopy enabled, in this case Ram state should behave as it is not postcopy-able. This patch add separate has_postcopy handler to specify behaviour of savevm state. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Juan Quintela Signed-off-by: Juan Quintela --- include/migration/register.h | 1 + migration/ram.c | 6 ++++++ migration/savevm.c | 6 ++++-- 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/migration/register.h b/include/migration/register.h index a0f1edd8c7..f4f7bdc177 100644 --- a/include/migration/register.h +++ b/include/migration/register.h @@ -24,6 +24,7 @@ typedef struct SaveVMHandlers { /* This runs both outside and inside the iothread lock. */ bool (*is_active)(void *opaque); + bool (*has_postcopy)(void *opaque); /* This runs outside the iothread lock in the migration case, and * within the lock in the savevm case. The callback had better only diff --git a/migration/ram.c b/migration/ram.c index bb369e72d4..cedbeae48d 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -2849,11 +2849,17 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) return ret; } +static bool ram_has_postcopy(void *opaque) +{ + return migrate_postcopy_ram(); +} + static SaveVMHandlers savevm_ram_handlers = { .save_setup = ram_save_setup, .save_live_iterate = ram_save_iterate, .save_live_complete_postcopy = ram_save_complete, .save_live_complete_precopy = ram_save_complete, + .has_postcopy = ram_has_postcopy, .save_live_pending = ram_save_pending, .load_state = ram_load, .save_cleanup = ram_save_cleanup, diff --git a/migration/savevm.c b/migration/savevm.c index 7a55023d1a..9a48b7b4cb 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1008,7 +1008,8 @@ int qemu_savevm_state_iterate(QEMUFile *f, bool postcopy) * call that's already run, it might get confused if we call * iterate afterwards. */ - if (postcopy && !se->ops->save_live_complete_postcopy) { + if (postcopy && + !(se->ops->has_postcopy && se->ops->has_postcopy(se->opaque))) { continue; } if (qemu_file_rate_limit(f)) { @@ -1097,7 +1098,8 @@ int qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only, QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { if (!se->ops || - (in_postcopy && se->ops->save_live_complete_postcopy) || + (in_postcopy && se->ops->has_postcopy && + se->ops->has_postcopy(se->opaque)) || (in_postcopy && !iterable_only) || !se->ops->save_live_complete_precopy) { continue; -- cgit v1.2.3-55-g7522