[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 11/62] memory: prepare for multiple bits in the dirty
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PULL 11/62] memory: prepare for multiple bits in the dirty log mask |
Date: |
Fri, 5 Jun 2015 17:15:12 +0200 |
When the dirty log mask will also cover other bits than DIRTY_MEMORY_VGA,
some listeners may be interested in the overall zero/non-zero value of
the dirty log mask; others may be interested in the value of single bits.
For this reason, always call log_start/log_stop if bits have respectively
appeared or disappeared, and pass the old and new values of the dirty log
mask so that listeners can distinguish the kinds of change.
For example, KVM checks if dirty logging used to be completely disabled
(in log_start) or is now completely disabled (in log_stop). On the
other hand, Xen has to check manually if DIRTY_MEMORY_VGA changed,
since that is the only bit it cares about.
Reviewed-by: Fam Zheng <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
hw/virtio/vhost.c | 6 ++++--
include/exec/memory.h | 6 ++++--
kvm-all.c | 14 ++++++++++++--
memory.c | 17 +++++++++++------
xen-hvm.c | 20 +++++++++++++-------
5 files changed, 44 insertions(+), 19 deletions(-)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 53d23d2..a7fe3c5 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -676,13 +676,15 @@ static void vhost_log_global_stop(MemoryListener
*listener)
}
static void vhost_log_start(MemoryListener *listener,
- MemoryRegionSection *section)
+ MemoryRegionSection *section,
+ int old, int new)
{
/* FIXME: implement */
}
static void vhost_log_stop(MemoryListener *listener,
- MemoryRegionSection *section)
+ MemoryRegionSection *section,
+ int old, int new)
{
/* FIXME: implement */
}
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 156d506..55dc11d 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -206,8 +206,10 @@ struct MemoryListener {
void (*region_add)(MemoryListener *listener, MemoryRegionSection *section);
void (*region_del)(MemoryListener *listener, MemoryRegionSection *section);
void (*region_nop)(MemoryListener *listener, MemoryRegionSection *section);
- void (*log_start)(MemoryListener *listener, MemoryRegionSection *section);
- void (*log_stop)(MemoryListener *listener, MemoryRegionSection *section);
+ void (*log_start)(MemoryListener *listener, MemoryRegionSection *section,
+ int old, int new);
+ void (*log_stop)(MemoryListener *listener, MemoryRegionSection *section,
+ int old, int new);
void (*log_sync)(MemoryListener *listener, MemoryRegionSection *section);
void (*log_global_start)(MemoryListener *listener);
void (*log_global_stop)(MemoryListener *listener);
diff --git a/kvm-all.c b/kvm-all.c
index d5416bb..c713b22 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -344,10 +344,15 @@ static int kvm_dirty_pages_log_change(hwaddr phys_addr,
}
static void kvm_log_start(MemoryListener *listener,
- MemoryRegionSection *section)
+ MemoryRegionSection *section,
+ int old, int new)
{
int r;
+ if (old != 0) {
+ return;
+ }
+
r = kvm_dirty_pages_log_change(section->offset_within_address_space,
int128_get64(section->size), true);
if (r < 0) {
@@ -356,10 +361,15 @@ static void kvm_log_start(MemoryListener *listener,
}
static void kvm_log_stop(MemoryListener *listener,
- MemoryRegionSection *section)
+ MemoryRegionSection *section,
+ int old, int new)
{
int r;
+ if (new != 0) {
+ return;
+ }
+
r = kvm_dirty_pages_log_change(section->offset_within_address_space,
int128_get64(section->size), false);
if (r < 0) {
diff --git a/memory.c b/memory.c
index 72e33e8..3e3d5b8 100644
--- a/memory.c
+++ b/memory.c
@@ -152,7 +152,7 @@ static bool memory_listener_match(MemoryListener *listener,
} while (0)
/* No need to ref/unref .mr, the FlatRange keeps it alive. */
-#define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback) \
+#define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback, _args...) \
MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) { \
.mr = (fr)->mr, \
.address_space = (as), \
@@ -160,7 +160,7 @@ static bool memory_listener_match(MemoryListener *listener,
.size = (fr)->addr.size, \
.offset_within_address_space = int128_get64((fr)->addr.start), \
.readonly = (fr)->readonly, \
- }))
+ }), ##_args)
struct CoalescedMemoryRange {
AddrRange addr;
@@ -774,10 +774,15 @@ static void
address_space_update_topology_pass(AddressSpace *as,
if (adding) {
MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_nop);
- if (frold->dirty_log_mask && !frnew->dirty_log_mask) {
- MEMORY_LISTENER_UPDATE_REGION(frnew, as, Reverse,
log_stop);
- } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) {
- MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward,
log_start);
+ if (frnew->dirty_log_mask & ~frold->dirty_log_mask) {
+ MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward,
log_start,
+ frold->dirty_log_mask,
+ frnew->dirty_log_mask);
+ }
+ if (frold->dirty_log_mask & ~frnew->dirty_log_mask) {
+ MEMORY_LISTENER_UPDATE_REGION(frnew, as, Reverse, log_stop,
+ frold->dirty_log_mask,
+ frnew->dirty_log_mask);
}
}
diff --git a/xen-hvm.c b/xen-hvm.c
index 338ab29..42356b8 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -646,21 +646,27 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
}
static void xen_log_start(MemoryListener *listener,
- MemoryRegionSection *section)
+ MemoryRegionSection *section,
+ int old, int new)
{
XenIOState *state = container_of(listener, XenIOState, memory_listener);
- xen_sync_dirty_bitmap(state, section->offset_within_address_space,
- int128_get64(section->size));
+ if (new & ~old & (1 << DIRTY_MEMORY_VGA)) {
+ xen_sync_dirty_bitmap(state, section->offset_within_address_space,
+ int128_get64(section->size));
+ }
}
-static void xen_log_stop(MemoryListener *listener, MemoryRegionSection
*section)
+static void xen_log_stop(MemoryListener *listener, MemoryRegionSection
*section,
+ int old, int new)
{
XenIOState *state = container_of(listener, XenIOState, memory_listener);
- state->log_for_dirtybit = NULL;
- /* Disable dirty bit tracking */
- xc_hvm_track_dirty_vram(xen_xc, xen_domid, 0, 0, NULL);
+ if (old & ~new & (1 << DIRTY_MEMORY_VGA)) {
+ state->log_for_dirtybit = NULL;
+ /* Disable dirty bit tracking */
+ xc_hvm_track_dirty_vram(xen_xc, xen_domid, 0, 0, NULL);
+ }
}
static void xen_log_sync(MemoryListener *listener, MemoryRegionSection
*section)
--
2.4.1
- [Qemu-devel] [PULL 01/62] Move parallel_hds_isa_init to hw/isa/isa-bus.c, (continued)
- [Qemu-devel] [PULL 01/62] Move parallel_hds_isa_init to hw/isa/isa-bus.c, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 02/62] ppc: add helpful message when KVM fails to start VCPU, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 04/62] exec: optimize phys_page_set_level, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 03/62] qemu-nbd: Switch to qemu_set_fd_handler, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 06/62] memory: the only dirty memory flag for users is DIRTY_MEMORY_VGA, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 05/62] Makefile.target: set master BUILD_DIR, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 07/62] g364fb: remove pointless call to memory_region_set_coalescing, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 08/62] display: enable DIRTY_MEMORY_VGA tracking explicitly, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 09/62] display: add memory_region_sync_dirty_bitmap calls, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 10/62] memory: differentiate memory_region_is_logging and memory_region_get_dirty_log_mask, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 11/62] memory: prepare for multiple bits in the dirty log mask,
Paolo Bonzini <=
- [Qemu-devel] [PULL 12/62] framebuffer: check memory_region_is_logging, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 14/62] memory: track DIRTY_MEMORY_CODE in mr->dirty_log_mask, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 13/62] ui/console: remove dpy_gfx_update_dirty, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 15/62] kvm: accept non-mapped memory in kvm_dirty_pages_log_change, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 16/62] memory: include DIRTY_MEMORY_MIGRATION in the dirty log mask, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 17/62] kvm: remove special handling of DIRTY_MEMORY_MIGRATION in the dirty log mask, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 19/62] exec: use memory_region_get_dirty_log_mask to optimize dirty tracking, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 20/62] exec: move functions to translate-all.h, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 18/62] ram_addr: tweaks to xen_modified_memory, Paolo Bonzini, 2015/06/05
- [Qemu-devel] [PULL 21/62] translate-all: remove unnecessary argument to tb_invalidate_phys_range, Paolo Bonzini, 2015/06/05