[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH V8 22/39] cpr: ram block blockers
From: |
Steve Sistare |
Subject: |
[PATCH V8 22/39] cpr: ram block blockers |
Date: |
Wed, 15 Jun 2022 07:52:09 -0700 |
Unlike reboot mode, restart mode cannot save volatile ram blocks in the
vmstate file and recreate them later, because the physical memory for the
blocks is pinned and registered for vfio. Add a restart-mode blocker for
volatile ram blocks.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
include/exec/memory.h | 2 ++
include/exec/ramblock.h | 1 +
softmmu/physmem.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
softmmu/vl.c | 2 ++
4 files changed, 53 insertions(+)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 6a257a4..812226f 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -3039,6 +3039,8 @@ bool ram_block_discard_is_required(void);
void ram_block_register(RAMBlock *rb);
void ram_block_unregister(RAMBlock *rb);
+void ram_block_add_cpr_blockers(Error **errp);
+
#endif
#endif
diff --git a/include/exec/ramblock.h b/include/exec/ramblock.h
index 6cbedf9..a5cbd9e 100644
--- a/include/exec/ramblock.h
+++ b/include/exec/ramblock.h
@@ -39,6 +39,7 @@ struct RAMBlock {
/* RCU-enabled, writes protected by the ramlist lock */
QLIST_ENTRY(RAMBlock) next;
QLIST_HEAD(, RAMBlockNotifier) ramblock_notifiers;
+ Error *cpr_blocker;
int fd;
size_t page_size;
/* dirty bitmap used during migration */
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 412cc80..b90ab4e 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -1968,6 +1968,53 @@ static bool memory_region_is_backend(MemoryRegion *mr)
return !!object_dynamic_cast(mr->parent_obj.parent, TYPE_MEMORY_BACKEND);
}
+/*
+ * Return true if ram contents would be lost during cpr for CPR_MODE_RESTART.
+ * Return false for ram_device because it is remapped after restart. Do not
+ * exclude rom, even though it is readonly, because the rom file could change
+ * in the new qemu. Return false for non-migratable blocks. They are either
+ * re-created after restart, or are handled specially, or are covered by a
+ * device-level cpr blocker. Return false for an fd, because it is visible and
+ * can be remapped in the new process.
+ */
+static bool ram_is_volatile(RAMBlock *rb)
+{
+ MemoryRegion *mr = rb->mr;
+
+ return mr &&
+ memory_region_is_ram(mr) &&
+ !memory_region_is_ram_device(mr) &&
+ (!qemu_ram_is_shared(rb) || ramblock_is_anon(rb)) &&
+ qemu_ram_is_migratable(rb) &&
+ rb->fd < 0;
+}
+
+/*
+ * Add a CPR_MODE_RESTART blocker for each volatile ram block. This cannot be
+ * performed in ram_block_add because the migratable flag has not been set yet.
+ */
+void ram_block_add_cpr_blockers(Error **errp)
+{
+ RAMBlock *rb;
+
+ RAMBLOCK_FOREACH(rb) {
+ if (ram_is_volatile(rb)) {
+ const char *name = memory_region_name(rb->mr);
+ rb->cpr_blocker = NULL;
+ if (memory_region_is_backend(rb->mr)) {
+ error_setg(&rb->cpr_blocker,
+ "Memory region %s is volatile. A memory-backend-memfd or"
+ " memory-backend-file with share=on is required.", name);
+ } else {
+ error_setg(&rb->cpr_blocker,
+ "Memory region %s is volatile. "
+ "-cpr-enable restart is required.", name);
+ }
+ cpr_add_blocker(&rb->cpr_blocker, errp, CPR_MODE_RESTART, 0);
+ }
+ }
+}
+
static void *qemu_anon_memfd_alloc(RAMBlock *rb, size_t maxlen, Error **errp)
{
size_t len, align;
@@ -2275,6 +2322,7 @@ void qemu_ram_free(RAMBlock *block)
qemu_mutex_lock_ramlist();
cpr_delete_memfd(memory_region_name(block->mr));
+ cpr_del_blocker(&block->cpr_blocker);
QLIST_REMOVE_RCU(block, next);
ram_list.mru_block = NULL;
/* Write list before version */
diff --git a/softmmu/vl.c b/softmmu/vl.c
index ce779cf..3e19c74 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -28,6 +28,7 @@
#include "qemu/units.h"
#include "exec/cpu-common.h"
#include "exec/page-vary.h"
+#include "exec/memory.h"
#include "hw/qdev-properties.h"
#include "qapi/compat-policy.h"
#include "qapi/error.h"
@@ -2569,6 +2570,7 @@ void qmp_x_exit_preconfig(Error **errp)
qemu_init_board();
qemu_create_cli_devices();
qemu_machine_creation_done();
+ ram_block_add_cpr_blockers(&error_fatal);
if (loadvm) {
load_snapshot(loadvm, NULL, false, NULL, &error_fatal);
--
1.8.3.1
- Re: [PATCH V8 13/39] oslib: qemu_clear_cloexec, (continued)
- [PATCH V8 25/39] cpr: notifiers, Steve Sistare, 2022/06/15
- [PATCH V8 20/39] cpr: restart mode, Steve Sistare, 2022/06/15
- [PATCH V8 29/39] vfio-pci: cpr part 3 (intx), Steve Sistare, 2022/06/15
- [PATCH V8 17/39] qapi: strList unit tests, Steve Sistare, 2022/06/15
- [PATCH V8 14/39] qapi: strList_from_string, Steve Sistare, 2022/06/15
- [PATCH V8 18/39] vl: helper to request re-exec, Steve Sistare, 2022/06/15
- [PATCH V8 22/39] cpr: ram block blockers,
Steve Sistare <=
- [PATCH V8 23/39] hostmem-memfd: cpr for memory-backend-memfd, Steve Sistare, 2022/06/15
- [PATCH V8 19/39] cpr: preserve extra state, Steve Sistare, 2022/06/15
- [PATCH V8 21/39] cpr: restart HMP interfaces, Steve Sistare, 2022/06/15
- [PATCH V8 24/39] pci: export export msix_is_pending, Steve Sistare, 2022/06/15
- [PATCH V8 31/39] vhost: reset vhost devices for cpr, Steve Sistare, 2022/06/15
- [PATCH V8 26/39] vfio-pci: refactor for cpr, Steve Sistare, 2022/06/15
- [PATCH V8 36/39] chardev: cpr for sockets, Steve Sistare, 2022/06/15
- [PATCH V8 28/39] vfio-pci: cpr part 2 (msi), Steve Sistare, 2022/06/15