diff mbox series

[1/4] memory: introduce DIRTY_MEMORY_DIRTY_RATE dirty bits

Message ID b858f91a8df4233afa5cc93d27f0b1adee30fc52.1624771216.git.huangy81@chinatelecom.cn (mailing list archive)
State New, archived
Headers show
Series support dirtyrate measurement with dirty bitmap | expand

Commit Message

Hyman Huang June 27, 2021, 5:38 a.m. UTC
From: Hyman Huang(黄勇) <huangy81@chinatelecom.cn>

intrduce DIRTY_MEMORY_DIRTY_RATE dirty bits to tracking vm
dirty page for calculating dirty rate

since dirtyrate and migration may be trigger concurrently,
reusing the exsiting DIRTY_MEMORY_MIGRATION dirty bits seems
not a good choice. introduce a fresh new dirty bits for
dirtyrate to ensure both dirtyrate and migration work fine.

Signed-off-by: Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
---
 include/exec/ram_addr.h | 15 ++++++++++++++-
 include/exec/ramlist.h  |  9 +++++----
 2 files changed, 19 insertions(+), 5 deletions(-)

Comments

Peter Xu July 9, 2021, 6:37 p.m. UTC | #1
On Sun, Jun 27, 2021 at 01:38:14PM +0800, huangy81@chinatelecom.cn wrote:
> @@ -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);

So what I meant in the other thread is instead of operating on this bitmap we
just record the number of total dirty pages, just like we used to do with rings.

PS. IIUC maybe this can even work for dirty rings.. because either dirty ring
or dirty logging collect dirty bits into the slot bitmap, then it's further
aggregated here from the slot bitmaps.  However merging them won't help much
because dirty ring can provide finer-granule per-vcpu dirty info, which can be
further used for per-vcpu throttling in the future.  So just raise this up.

> +                        }
>                      }
diff mbox series

Patch

diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 45c9132..6070a52 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -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);
         }
 
         /*
diff --git a/include/exec/ramlist.h b/include/exec/ramlist.h
index ece6497..8585f00 100644
--- a/include/exec/ramlist.h
+++ b/include/exec/ramlist.h
@@ -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: