@@ -857,6 +857,36 @@ unsigned long colo_bitmap_find_dirty(RAMState *rs, RAMBlock *rb,
return first;
}
+/**
+ * colo_bitmap_clear_dirty:when we flush ram cache to ram, we will use
+ * continuous memory copy, so we can also clean up the bitmap of contiguous
+ * dirty memory.
+ */
+static inline bool colo_bitmap_clear_dirty(RAMState *rs,
+ RAMBlock *rb,
+ unsigned long start,
+ unsigned long num)
+{
+ bool ret;
+ unsigned long i = 0;
+
+ /*
+ * Since flush ram cache to ram can only happen on Secondary VM.
+ * and the clear bitmap always is NULL on destination side.
+ * Therefore, there is unnecessary to judge whether the
+ * clear_bitmap needs clear.
+ */
+ QEMU_LOCK_GUARD(&rs->bitmap_mutex);
+ for (i = 0; i < num; i++) {
+ ret = test_and_clear_bit(start + i, rb->bmap);
+ if (ret) {
+ rs->migration_dirty_pages--;
+ }
+ }
+
+ return ret;
+}
+
static inline bool migration_bitmap_clear_dirty(RAMState *rs,
RAMBlock *rb,
unsigned long page)
@@ -3723,11 +3753,7 @@ void colo_flush_ram_cache(void)
num = 0;
block = QLIST_NEXT_RCU(block, next);
} else {
- unsigned long i = 0;
-
- for (i = 0; i < num; i++) {
- migration_bitmap_clear_dirty(ram_state, block, offset + i);
- }
+ colo_bitmap_clear_dirty(ram_state, block, offset, num);
dst_host = block->host
+ (((ram_addr_t)offset) << TARGET_PAGE_BITS);
src_host = block->colo_cache