diff --git a/balloon.c b/balloon.c index 5d69e8a00b..0f45d1b5c4 100644 --- a/balloon.c +++ b/balloon.c @@ -36,6 +36,17 @@ static QEMUBalloonEvent *balloon_event_fn; static QEMUBalloonStatus *balloon_stat_fn; static void *balloon_opaque; +static bool balloon_inhibited; + +bool qemu_balloon_is_inhibited(void) +{ + return balloon_inhibited; +} + +void qemu_balloon_inhibit(bool state) +{ + balloon_inhibited = state; +} static bool have_balloon(Error **errp) { diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index c419b17143..9671635e63 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -37,9 +37,11 @@ static void balloon_page(void *addr, int deflate) { #if defined(__linux__) - if (!kvm_enabled() || kvm_has_sync_mmu()) + if (!qemu_balloon_is_inhibited() && (!kvm_enabled() || + kvm_has_sync_mmu())) { qemu_madvise(addr, TARGET_PAGE_SIZE, deflate ? QEMU_MADV_WILLNEED : QEMU_MADV_DONTNEED); + } #endif } diff --git a/include/sysemu/balloon.h b/include/sysemu/balloon.h index 17fe30070d..3f976b49e7 100644 --- a/include/sysemu/balloon.h +++ b/include/sysemu/balloon.h @@ -22,5 +22,7 @@ typedef void (QEMUBalloonStatus)(void *opaque, BalloonInfo *info); int qemu_add_balloon_handler(QEMUBalloonEvent *event_func, QEMUBalloonStatus *stat_func, void *opaque); void qemu_remove_balloon_handler(void *opaque); +bool qemu_balloon_is_inhibited(void); +void qemu_balloon_inhibit(bool state); #endif diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index 1a24b0937e..22d6b18e63 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c @@ -24,6 +24,7 @@ #include "migration/migration.h" #include "migration/postcopy-ram.h" #include "sysemu/sysemu.h" +#include "sysemu/balloon.h" #include "qemu/error-report.h" #include "trace.h" @@ -308,6 +309,8 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis) mis->have_fault_thread = false; } + qemu_balloon_inhibit(false); + if (enable_mlock) { if (os_mlock() < 0) { error_report("mlock: %s", strerror(errno)); @@ -533,6 +536,12 @@ int postcopy_ram_enable_notify(MigrationIncomingState *mis) return -1; } + /* + * Ballooning can mark pages as absent while we're postcopying + * that would cause false userfaults. + */ + qemu_balloon_inhibit(true); + trace_postcopy_ram_enable_notify(); return 0;