From: Juan Quintela <quintela@redhat.com>
To: qemu-devel@nongnu.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Umesh Deshpande <udeshpan@redhat.com>
Subject: [Qemu-devel] [PATCH 10/27] Separate migration bitmap
Date: Tue, 24 Jul 2012 20:36:35 +0200 [thread overview]
Message-ID: <1343155012-26316-11-git-send-email-quintela@redhat.com> (raw)
In-Reply-To: <1343155012-26316-1-git-send-email-quintela@redhat.com>
This patch creates a migration bitmap, which is periodically kept in
sync with the qemu bitmap. A separate copy of the dirty bitmap for the
migration limits the amount of concurrent access to the qemu bitmap
from iothread and migration thread (which requires taking the big
lock).
We use the qemu bitmap type. We have to "undo" the dirty_pages
counting optimization on the general dirty bitmap and do the counting
optimization with the migration local bitmap.
Signed-off-by: Umesh Deshpande <udeshpan@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
arch_init.c | 57 +++++++++++++++++++++++++++++++++++++++----------------
cpu-all.h | 1 -
exec-obsolete.h | 10 ----------
3 files changed, 41 insertions(+), 27 deletions(-)
diff --git a/arch_init.c b/arch_init.c
index d21b2a3..72345c3 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -31,6 +31,8 @@
#include "config.h"
#include "monitor.h"
#include "sysemu.h"
+#include "bitops.h"
+#include "bitmap.h"
#include "arch_init.h"
#include "audio/audio.h"
#include "hw/pc.h"
@@ -341,35 +343,54 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
static RAMBlock *last_block;
static ram_addr_t last_offset;
static uint32_t last_version;
+static unsigned long *migration_bitmap;
+static uint64_t migration_dirty_pages;
static inline bool migration_bitmap_test_and_reset_dirty(MemoryRegion *mr,
ram_addr_t offset)
{
- bool ret = memory_region_get_dirty(mr, offset, TARGET_PAGE_SIZE,
- DIRTY_MEMORY_MIGRATION);
+ bool ret;
+ int nr = (mr->ram_addr + offset) >> TARGET_PAGE_BITS;
+
+ ret = test_and_clear_bit(nr, migration_bitmap);
if (ret) {
- memory_region_reset_dirty(mr, offset, TARGET_PAGE_SIZE,
- DIRTY_MEMORY_MIGRATION);
+ migration_dirty_pages--;
}
return ret;
}
-static inline void migration_bitmap_set_dirty(MemoryRegion *mr, int length)
+static inline bool migration_bitmap_set_dirty(MemoryRegion *mr,
+ ram_addr_t offset)
{
- ram_addr_t addr;
+ bool ret;
+ int nr = (mr->ram_addr + offset) >> TARGET_PAGE_BITS;
- for (addr = 0; addr < length; addr += TARGET_PAGE_SIZE) {
- if (!memory_region_get_dirty(mr, addr, TARGET_PAGE_SIZE,
- DIRTY_MEMORY_MIGRATION)) {
- memory_region_set_dirty(mr, addr, TARGET_PAGE_SIZE);
- }
+ ret = test_and_set_bit(nr, migration_bitmap);
+
+ if (!ret) {
+ migration_dirty_pages++;
}
+ return ret;
}
static void migration_bitmap_sync(void)
{
+ RAMBlock *block;
+ ram_addr_t addr;
+
memory_global_sync_dirty_bitmap(get_system_memory());
+
+ QLIST_FOREACH(block, &ram_list.blocks, next) {
+ for (addr = 0; addr < block->length; addr += TARGET_PAGE_SIZE) {
+ if (memory_region_get_dirty(block->mr, addr, TARGET_PAGE_SIZE,
+ DIRTY_MEMORY_MIGRATION)) {
+ migration_bitmap_set_dirty(block->mr, addr);
+ }
+ }
+ memory_region_reset_dirty(block->mr, 0, block->length,
+ DIRTY_MEMORY_MIGRATION);
+ }
}
@@ -447,7 +468,7 @@ static uint64_t bytes_transferred;
static ram_addr_t ram_save_remaining(void)
{
- return ram_list.dirty_pages;
+ return migration_dirty_pages;
}
uint64_t ram_bytes_remaining(void)
@@ -532,6 +553,11 @@ static void reset_ram_globals(void)
static int ram_save_setup(QEMUFile *f, void *opaque)
{
RAMBlock *block;
+ int64_t ram_pages = last_ram_offset() >> TARGET_PAGE_BITS;
+
+ migration_bitmap = bitmap_new(ram_pages);
+ bitmap_set(migration_bitmap, 0, ram_pages);
+ migration_dirty_pages = ram_pages;
qemu_mutex_lock_ramlist();
@@ -551,10 +577,6 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
acct_clear();
}
- QLIST_FOREACH(block, &ram_list.blocks, next) {
- migration_bitmap_set_dirty(block->mr, block->length);
- }
-
memory_global_dirty_log_start();
qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
@@ -669,6 +691,9 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
qemu_mutex_unlock_ramlist();
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
+ g_free(migration_bitmap);
+ migration_bitmap = NULL;
+
return 0;
}
diff --git a/cpu-all.h b/cpu-all.h
index 45290b7..88ad1ba 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -495,7 +495,6 @@ typedef struct RAMList {
QLIST_HEAD(, RAMBlock) blocks_mru;
/* Protected by the ramlist lock. */
QLIST_HEAD(, RAMBlock) blocks;
- uint64_t dirty_pages;
} RAMList;
extern RAMList ram_list;
diff --git a/exec-obsolete.h b/exec-obsolete.h
index c099256..f8ffce6 100644
--- a/exec-obsolete.h
+++ b/exec-obsolete.h
@@ -74,11 +74,6 @@ static inline int cpu_physical_memory_get_dirty(ram_addr_t start,
static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr,
int dirty_flags)
{
- if ((dirty_flags & MIGRATION_DIRTY_FLAG) &&
- !cpu_physical_memory_get_dirty(addr, TARGET_PAGE_SIZE,
- MIGRATION_DIRTY_FLAG)) {
- ram_list.dirty_pages++;
- }
return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] |= dirty_flags;
}
@@ -92,11 +87,6 @@ static inline int cpu_physical_memory_clear_dirty_flags(ram_addr_t addr,
{
int mask = ~dirty_flags;
- if ((dirty_flags & MIGRATION_DIRTY_FLAG) &&
- cpu_physical_memory_get_dirty(addr, TARGET_PAGE_SIZE,
- MIGRATION_DIRTY_FLAG)) {
- ram_list.dirty_pages--;
- }
return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] &= mask;
}
--
1.7.10.4
next prev parent reply other threads:[~2012-07-24 18:37 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-24 18:36 [Qemu-devel] [RFC 00/27] Migration thread (WIP) Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 01/27] buffered_file: g_realloc() can't fail Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 02/27] split MRU ram list Juan Quintela
2012-07-25 20:20 ` Michael Roth
2012-07-26 13:19 ` Avi Kivity
2012-07-24 18:36 ` [Qemu-devel] [PATCH 03/27] savevm: Factorize ram globals reset in its own function Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 04/27] add a version number to ram_list Juan Quintela
2012-07-25 23:27 ` Michael Roth
2012-07-26 9:19 ` Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 05/27] protect the ramlist with a separate mutex Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 06/27] ram: introduce migration_bitmap_set_dirty() Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 07/27] ram: Introduce migration_bitmap_test_and_reset_dirty() Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 08/27] ram: Export last_ram_offset() Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 09/27] ram: introduce migration_bitmap_sync() Juan Quintela
2012-07-24 18:36 ` Juan Quintela [this message]
2012-07-25 9:16 ` [Qemu-devel] [PATCH 10/27] Separate migration bitmap Avi Kivity
2012-07-26 9:22 ` Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 11/27] BufferedFile: append, then flush Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 12/27] buffered_file: rename opaque to migration_state Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 13/27] buffered_file: opaque is MigrationState Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 14/27] buffered_file: unfold migrate_fd_put_buffer Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 15/27] buffered_file: unfold migrate_fd_put_ready Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 16/27] buffered_file: unfold migrate_fd_put_buffer Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 17/27] " Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 18/27] buffered_file: We can access directly to bandwidth_limit Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 19/27] buffered_file: Move from using a timer to use a thread Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 20/27] migration: make qemu_fopen_ops_buffered() return void Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 21/27] migration: stop all cpus correctly Juan Quintela
2012-07-26 12:54 ` Eric Blake
2012-07-24 18:36 ` [Qemu-devel] [PATCH 22/27] migration: make writes blocking Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 23/27] migration: remove unfreeze logic Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 24/27] migration: take finer locking Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 25/27] buffered_file: Unfold the trick to restart generating migration data Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 26/27] buffered_file: don't flush on put buffer Juan Quintela
2012-07-24 18:36 ` [Qemu-devel] [PATCH 27/27] buffered_file: unfold buffered_append in buffered_put_buffer Juan Quintela
2012-07-25 9:55 ` [Qemu-devel] [RFC 00/27] Migration thread (WIP) Orit Wasserman
2012-07-26 10:57 ` Jan Kiszka
2012-07-26 11:16 ` Juan Quintela
2012-07-26 11:56 ` Jan Kiszka
[not found] ` <500EF579.5040607@redhat.com>
2012-07-26 18:41 ` [Qemu-devel] Fwd: " Chegu Vinod
2012-07-26 21:26 ` Chegu Vinod
2012-07-27 11:05 ` Juan Quintela
[not found] ` <4168C988EBDF2141B4E0B6475B6A73D1165CDD@G6W2493.americas.hpqcorp.net>
2012-07-27 14:21 ` [Qemu-devel] FW: " Chegu Vinod
2012-07-26 21:36 ` [Qemu-devel] " Michael Roth
2012-08-02 12:01 ` Juan Quintela
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1343155012-26316-11-git-send-email-quintela@redhat.com \
--to=quintela@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=udeshpan@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).