@@ -38,6 +38,11 @@
#define MULTIFD_MAGIC 0x11223344U
#define MULTIFD_VERSION 1
+struct MultiFDSlots {
+ MultiFDSendData **free;
+ MultiFDSendData *active;
+};
+
typedef struct {
uint32_t magic;
uint32_t version;
@@ -737,7 +742,22 @@ static inline bool multifd_queue_full(MultiFDPages_t *pages)
static inline void multifd_enqueue(MultiFDPages_t *pages, ram_addr_t offset)
{
pages->offset[pages->num++] = offset;
- multifd_ram_send_slots->active->size += qemu_target_page_size();
+ multifd_set_slot_size(multifd_ram_send_slots, qemu_target_page_size());
+}
+
+void *multifd_get_active_slot(MultiFDSlots *multifd_ram_send_slots)
+{
+ return multifd_ram_send_slots->active->opaque;
+}
+
+void multifd_set_slot_size(MultiFDSlots *multifd_ram_send_slots, size_t size)
+{
+ multifd_ram_send_slots->active->size += size;
+}
+
+bool multifd_slot_has_data(MultiFDSlots *multifd_ram_send_slots)
+{
+ return !!multifd_ram_send_slots->active->size;
}
/* Returns true if enqueue successful, false otherwise */
@@ -746,7 +766,7 @@ bool multifd_queue_page(RAMBlock *block, ram_addr_t offset)
MultiFDPages_t *pages;
retry:
- pages = multifd_ram_send_slots->active->opaque;
+ pages = multifd_get_active_slot(multifd_ram_send_slots);
/* If the queue is empty, we can already enqueue now */
if (multifd_queue_empty(pages)) {
@@ -951,7 +971,7 @@ int multifd_send_sync_main(void)
return 0;
}
- if (multifd_ram_send_slots->active->size) {
+ if (multifd_slot_has_data(multifd_ram_send_slots)) {
if (!multifd_send(multifd_ram_send_slots)) {
error_report("%s: multifd_send_pages fail", __func__);
return -1;
@@ -102,15 +102,13 @@ struct MultiFDSendData {
void (*cleanup)(void *);
};
-struct MultiFDSlots {
- MultiFDSendData **free;
- MultiFDSendData *active;
-};
-
MultiFDSlots *multifd_allocate_slots(void *(*alloc_fn)(void),
void (*reset_fn)(void *),
void (*cleanup_fn)(void *));
void multifd_ram_save_setup(void);
+void *multifd_get_active_slot(MultiFDSlots *multifd_ram_send_slots);
+void multifd_set_slot_size(MultiFDSlots *multifd_ram_send_slots, size_t size);
+bool multifd_slot_has_data(MultiFDSlots *multifd_ram_send_slots);
typedef struct {
/* Fields are only written at creating/deletion time */
The only two things the multifd client needs to access are the active slot and the active slot size: The active slot itself is obviously needed because it's where the data is put. The slot size is needed only by the ram pages code, because it does not fill the data slot and sends it in one go, it instead fills the slot partially at each call of multifd_queue_page(), so the size is needed to differentiate an empty slot (free or recently consumed) from the slot that is partially full. Hide the MultiFDSlots implementation so the client is not tempted to make use of the free list. That field is there simply because we need the client to carry a handle to that memory, it's not supposed to be accessed directly. Signed-off-by: Fabiano Rosas <farosas@suse.de> --- migration/multifd.c | 26 +++++++++++++++++++++++--- migration/multifd.h | 8 +++----- 2 files changed, 26 insertions(+), 8 deletions(-)