@@ -308,6 +308,10 @@ static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start,
while (page < end) {
unsigned long next = MIN(end, base + DIRTY_MEMORY_BLOCK_SIZE);
+ if (unlikely(mask & (1 << DIRTY_MEMORY_DIRTY_RATE))) {
+ bitmap_set_atomic(blocks[DIRTY_MEMORY_DIRTY_RATE]->blocks[idx],
+ offset, next - page);
+ }
if (likely(mask & (1 << DIRTY_MEMORY_MIGRATION))) {
bitmap_set_atomic(blocks[DIRTY_MEMORY_MIGRATION]->blocks[idx],
offset, next - page);
@@ -370,9 +374,17 @@ static inline void cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap,
qatomic_or(&blocks[DIRTY_MEMORY_VGA][idx][offset], temp);
if (global_dirty_tracking) {
- qatomic_or(
+ if (global_dirty_tracking & GLOBAL_DIRTY_MIGRATION) {
+ qatomic_or(
&blocks[DIRTY_MEMORY_MIGRATION][idx][offset],
temp);
+ }
+
+ if (global_dirty_tracking & GLOBAL_DIRTY_DIRTY_RATE) {
+ qatomic_or(
+ &blocks[DIRTY_MEMORY_DIRTY_RATE][idx][offset],
+ temp);
+ }
}
if (tcg_enabled()) {
@@ -394,6 +406,7 @@ static inline void cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap,
if (!global_dirty_tracking) {
clients &= ~(1 << DIRTY_MEMORY_MIGRATION);
+ clients &= ~(1 << DIRTY_MEMORY_DIRTY_RATE);
}
/*
@@ -8,10 +8,11 @@
typedef struct RAMBlockNotifier RAMBlockNotifier;
-#define DIRTY_MEMORY_VGA 0
-#define DIRTY_MEMORY_CODE 1
-#define DIRTY_MEMORY_MIGRATION 2
-#define DIRTY_MEMORY_NUM 3 /* num of dirty bits */
+#define DIRTY_MEMORY_VGA 0
+#define DIRTY_MEMORY_CODE 1
+#define DIRTY_MEMORY_MIGRATION 2
+#define DIRTY_MEMORY_DIRTY_RATE 3
+#define DIRTY_MEMORY_NUM 4 /* num of dirty bits */
/* The dirty memory bitmap is split into fixed-size blocks to allow growth
* under RCU. The bitmap for a block can be accessed as follows: