ram compress: Assert that the file buffer matches the result
authorLukas Straub <lukasstraub2@web.de>
Thu, 20 Apr 2023 09:48:31 +0000 (11:48 +0200)
committerJuan Quintela <quintela@redhat.com>
Mon, 8 May 2023 13:25:26 +0000 (15:25 +0200)
Before this series, "nothing to send" was handled by the file buffer
being empty. Now it is tracked via param->result.

Assert that the file buffer state matches the result.

Signed-off-by: Lukas Straub <lukasstraub2@web.de>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
migration/qemu-file.c
migration/qemu-file.h
migration/ram-compress.c
migration/ram.c

index f4cfd05c67b49861ae5980f31a0a30f06140c2a1..61fb580342234d72f52014f7491f4d8bd0757615 100644 (file)
@@ -870,6 +870,17 @@ int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src)
     return len;
 }
 
+/*
+ * Check if the writable buffer is empty
+ */
+
+bool qemu_file_buffer_empty(QEMUFile *file)
+{
+    assert(qemu_file_is_writable(file));
+
+    return !file->iovcnt;
+}
+
 /*
  * Get a string whose length is determined by a single preceding byte
  * A preallocated 256 byte buffer must be passed in.
index 4f26bf696119aad341a3cb25a39b86ea9a4061fc..4ee58a87ddadce6eabb6dab0736e69d380ff103d 100644 (file)
@@ -113,6 +113,7 @@ size_t coroutine_mixed_fn qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, s
 ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream,
                                   const uint8_t *p, size_t size);
 int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src);
+bool qemu_file_buffer_empty(QEMUFile *file);
 
 /*
  * Note that you can only peek continuous bytes from where the current pointer
index c25562f12d204618d3a6415514e312c4f704a24a..3d2a4a6329a673bcb3a810ee6e947f71171a90b6 100644 (file)
@@ -194,6 +194,8 @@ static CompressResult do_compress_ram_page(QEMUFile *f, z_stream *stream,
     uint8_t *p = block->host + offset;
     int ret;
 
+    assert(qemu_file_buffer_empty(f));
+
     if (buffer_is_zero(p, TARGET_PAGE_SIZE)) {
         return RES_ZEROPAGE;
     }
@@ -208,6 +210,7 @@ static CompressResult do_compress_ram_page(QEMUFile *f, z_stream *stream,
     if (ret < 0) {
         qemu_file_set_error(migrate_get_current()->to_dst_file, ret);
         error_report("compressed data failed!");
+        qemu_fflush(f);
         return RES_NONE;
     }
     return RES_COMPRESS;
@@ -239,6 +242,7 @@ void flush_compressed_data(int (send_queued_data(CompressParam *)))
         if (!comp_param[idx].quit) {
             CompressParam *param = &comp_param[idx];
             send_queued_data(param);
+            assert(qemu_file_buffer_empty(param->file));
             compress_reset_result(param);
         }
         qemu_mutex_unlock(&comp_param[idx].mutex);
@@ -268,6 +272,7 @@ retry:
             qemu_mutex_lock(&param->mutex);
             param->done = false;
             send_queued_data(param);
+            assert(qemu_file_buffer_empty(param->file));
             compress_reset_result(param);
             set_compress_params(param, block, offset);
 
index 009681d2138a9ee395df70d7c57e171eff22d7d4..ee4ab31f2535c0b0494db406f2e66bc68015cffb 100644 (file)
@@ -1321,11 +1321,13 @@ static int send_queued_data(CompressParam *param)
     assert(block == pss->last_sent_block);
 
     if (param->result == RES_ZEROPAGE) {
+        assert(qemu_file_buffer_empty(param->file));
         len += save_page_header(pss, file, block, offset | RAM_SAVE_FLAG_ZERO);
         qemu_put_byte(file, 0);
         len += 1;
         ram_release_page(block->idstr, offset);
     } else if (param->result == RES_COMPRESS) {
+        assert(!qemu_file_buffer_empty(param->file));
         len += save_page_header(pss, file, block,
                                 offset | RAM_SAVE_FLAG_COMPRESS_PAGE);
         len += qemu_put_qemu_file(file, param->file);