Message ID | 1609861330-129855-6-git-send-email-steven.sistare@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Live Update | expand |
On Tue, Jan 05, 2021 at 07:41:53AM -0800, Steve Sistare wrote: > Allocate anonymous memory using memfd_create if the memfd-alloc option is > set. > > Signed-off-by: Steve Sistare <steven.sistare@oracle.com> > --- > exec.c | 38 ++++++++++++++++++++++++++++++-------- > include/sysemu/sysemu.h | 1 + > qemu-options.hx | 11 +++++++++++ > softmmu/vl.c | 4 ++++ > trace-events | 1 + > 5 files changed, 47 insertions(+), 8 deletions(-) > diff --git a/qemu-options.hx b/qemu-options.hx > index 708583b..455b43b7 100644 > --- a/qemu-options.hx > +++ b/qemu-options.hx > @@ -4094,6 +4094,17 @@ SRST > an unmigratable state. > ERST > > +#ifdef __linux__ > +DEF("memfd-alloc", 0, QEMU_OPTION_memfd_alloc, \ > + "-memfd-alloc allocate anonymous memory using memfd_create\n", > + QEMU_ARCH_ALL) > +#endif > + > +SRST > +``-memfd-alloc`` > + Allocate anonymous memory using memfd_create (Linux only). > +ERST Do we really need a new arg for this ? It is already possible to request use of memfd for the guest RAM using -object memory-backend-memfd,id=ram-node0,size=NNNN this memory backend object framework was intended to remove the need to add new ad-hoc CLI args for controlling memory allocation. Regards, Daniel
On 1/5/2021 11:27 AM, Daniel P. Berrangé wrote: > On Tue, Jan 05, 2021 at 07:41:53AM -0800, Steve Sistare wrote: >> Allocate anonymous memory using memfd_create if the memfd-alloc option is >> set. >> >> Signed-off-by: Steve Sistare <steven.sistare@oracle.com> >> --- >> exec.c | 38 ++++++++++++++++++++++++++++++-------- >> include/sysemu/sysemu.h | 1 + >> qemu-options.hx | 11 +++++++++++ >> softmmu/vl.c | 4 ++++ >> trace-events | 1 + >> 5 files changed, 47 insertions(+), 8 deletions(-) > >> diff --git a/qemu-options.hx b/qemu-options.hx >> index 708583b..455b43b7 100644 >> --- a/qemu-options.hx >> +++ b/qemu-options.hx >> @@ -4094,6 +4094,17 @@ SRST >> an unmigratable state. >> ERST >> >> +#ifdef __linux__ >> +DEF("memfd-alloc", 0, QEMU_OPTION_memfd_alloc, \ >> + "-memfd-alloc allocate anonymous memory using memfd_create\n", >> + QEMU_ARCH_ALL) >> +#endif >> + >> +SRST >> +``-memfd-alloc`` >> + Allocate anonymous memory using memfd_create (Linux only). >> +ERST > > Do we really need a new arg for this ? It is already possible to request > use of memfd for the guest RAM using > > -object memory-backend-memfd,id=ram-node0,size=NNNN > > this memory backend object framework was intended to remove the need to > add new ad-hoc CLI args for controlling memory allocation. Yes, I considered that, but there are other memory regions that cannot be controlled by the command line but which must be preserved, such as vram, bios, and rom. If vram is not preserved, parts of the screen will be blank until the user performs some action which refreshes the display. bios and rom should be preserved rather than re-recreated with potentially different contents from the firmware images in the updated qemu package. However, your comment reminds me that I must add a few lines of code to preserve the memory-backend-memfd. - Steve
Il mer 6 gen 2021, 17:37 Steven Sistare <steven.sistare@oracle.com> ha scritto: > Yes, I considered that, but there are other memory regions that cannot be > controlled > by the command line but which must be preserved, such as vram, bios, and > rom. If vram > is not preserved, parts of the screen will be blank until the user > performs some action > which refreshes the display. bios and rom should be preserved rather than > re-recreated > with potentially different contents from the firmware images in the > updated qemu package. > > However, your comment reminds me that I must add a few lines of code to > preserve the > memory-backend-memfd. > A new option specific to memory is the wrong way to do this. If a special mode must be specified when starting QEMU, you can make it a -machine option and block the QMP commands unless it's specified. Otherwise you can use "normal" migration to marshal and unmarshal across the update those memory regions that aren't backed by shared memory or memfd. Also, because of the mess that vl.c had grown into, adding new "simple" options is going to be very very hard. In fact I am working on turning many options like -smp or -m into syntactic sugar for -machine; at some point I would like to (almost) forbid adding _any_ new option. Paolo > - Steve > >
On 1/6/2021 3:10 PM, Paolo Bonzini wrote: > Il mer 6 gen 2021, 17:37 Steven Sistare <steven.sistare@oracle.com <mailto:steven.sistare@oracle.com>> ha scritto: > > Yes, I considered that, but there are other memory regions that cannot be controlled > by the command line but which must be preserved, such as vram, bios, and rom. If vram > is not preserved, parts of the screen will be blank until the user performs some action > which refreshes the display. bios and rom should be preserved rather than re-recreated > with potentially different contents from the firmware images in the updated qemu package. > > However, your comment reminds me that I must add a few lines of code to preserve the > memory-backend-memfd. > > > A new option specific to memory is the wrong way to do this. If a special mode must be specified when starting QEMU, you can make it a -machine option and block the QMP commands unless it's specified. Otherwise you can use "normal" migration to marshal and unmarshal across the update those memory regions that aren't backed by shared memory or memfd. > > Also, because of the mess that vl.c had grown into, adding new "simple" options is going to be very very hard. In fact I am working on turning many options like -smp or -m into syntactic sugar for -machine; at some point I would like to (almost) forbid adding _any_ new option. Will do. Thanks for the heads up on the future of vl.c. I defined the option independently of cpr for generality. Do you think this could be useful? If yes, I will name and define the -machine option to use memfd; if no, I will name and define it to enable cpr, and implicitly enable memfd without saying so. - Steve
diff --git a/exec.c b/exec.c index d1f31b4..6da6590 100644 --- a/exec.c +++ b/exec.c @@ -67,6 +67,7 @@ #include "exec/log.h" #include "qemu/pmem.h" +#include "qemu/memfd.h" #include "migration/vmstate.h" @@ -2231,34 +2232,55 @@ static void ram_block_add(RAMBlock *new_block, Error **errp, bool shared) { RAMBlock *block; RAMBlock *last_block = NULL; + struct MemoryRegion *mr = new_block->mr; ram_addr_t old_ram_size, new_ram_size; Error *err = NULL; + const char *name; + void *addr = 0; + size_t maxlen; old_ram_size = last_ram_page(); qemu_mutex_lock_ramlist(); - new_block->offset = find_ram_offset(new_block->max_length); + maxlen = new_block->max_length; + new_block->offset = find_ram_offset(maxlen); if (!new_block->host) { if (xen_enabled()) { - xen_ram_alloc(new_block->offset, new_block->max_length, - new_block->mr, &err); + xen_ram_alloc(new_block->offset, maxlen, new_block->mr, &err); if (err) { error_propagate(errp, err); qemu_mutex_unlock_ramlist(); return; } } else { - new_block->host = phys_mem_alloc(new_block->max_length, - &new_block->mr->align, shared); - if (!new_block->host) { + name = memory_region_name(new_block->mr); + if (memfd_alloc) { + int mfd = -1; /* placeholder until next patch */ + mr->align = QEMU_VMALLOC_ALIGN; + if (mfd < 0) { + mfd = qemu_memfd_create(name, maxlen + mr->align, + 0, 0, 0, &err); + if (mfd < 0) { + return; + } + } + new_block->flags |= RAM_SHARED; + addr = file_ram_alloc(new_block, maxlen, mfd, false, errp); + trace_anon_memfd_alloc(name, maxlen, addr, mfd); + } else { + addr = phys_mem_alloc(maxlen, &mr->align, shared); + } + + if (!addr) { error_setg_errno(errp, errno, "cannot set up guest memory '%s'", - memory_region_name(new_block->mr)); + name); qemu_mutex_unlock_ramlist(); return; } - memory_try_enable_merging(new_block->host, new_block->max_length); + memory_try_enable_merging(addr, maxlen); + new_block->host = addr; } } diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 4b6a5c4..408eb56 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -13,6 +13,7 @@ extern int only_migratable; extern const char *qemu_name; extern QemuUUID qemu_uuid; extern bool qemu_uuid_set; +extern bool memfd_alloc; void qemu_add_data_dir(const char *path); diff --git a/qemu-options.hx b/qemu-options.hx index 708583b..455b43b7 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4094,6 +4094,17 @@ SRST an unmigratable state. ERST +#ifdef __linux__ +DEF("memfd-alloc", 0, QEMU_OPTION_memfd_alloc, \ + "-memfd-alloc allocate anonymous memory using memfd_create\n", + QEMU_ARCH_ALL) +#endif + +SRST +``-memfd-alloc`` + Allocate anonymous memory using memfd_create (Linux only). +ERST + DEF("nodefaults", 0, QEMU_OPTION_nodefaults, \ "-nodefaults don't create default devices\n", QEMU_ARCH_ALL) SRST diff --git a/softmmu/vl.c b/softmmu/vl.c index 4eb9d1f..5668e2b 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -164,6 +164,7 @@ bool boot_strict; uint8_t *boot_splash_filedata; int only_migratable; /* turn it off unless user states otherwise */ bool wakeup_suspend_enabled; +bool memfd_alloc; int icount_align_option; @@ -3635,6 +3636,9 @@ void qemu_init(int argc, char **argv, char **envp) case QEMU_OPTION_only_migratable: only_migratable = 1; break; + case QEMU_OPTION_memfd_alloc: + memfd_alloc = true; + break; case QEMU_OPTION_nodefaults: has_defaults = 0; break; diff --git a/trace-events b/trace-events index 42107eb..ed46c4d 100644 --- a/trace-events +++ b/trace-events @@ -54,6 +54,7 @@ find_ram_offset_loop(uint64_t size, uint64_t candidate, uint64_t offset, uint64_ ram_block_discard_range(const char *rbname, void *hva, size_t length, bool need_madvise, bool need_fallocate, int ret) "%s@%p + 0x%zx: madvise: %d fallocate: %d ret: %d" memory_notdirty_write_access(uint64_t vaddr, uint64_t ram_addr, unsigned size) "0x%" PRIx64 " ram_addr 0x%" PRIx64 " size %u" memory_notdirty_set_dirty(uint64_t vaddr) "0x%" PRIx64 +anon_memfd_alloc(const char *name, size_t size, void *ptr, int fd) "%s size %zu ptr %p fd %d" # memory.c memory_region_ops_read(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
Allocate anonymous memory using memfd_create if the memfd-alloc option is set. Signed-off-by: Steve Sistare <steven.sistare@oracle.com> --- exec.c | 38 ++++++++++++++++++++++++++++++-------- include/sysemu/sysemu.h | 1 + qemu-options.hx | 11 +++++++++++ softmmu/vl.c | 4 ++++ trace-events | 1 + 5 files changed, 47 insertions(+), 8 deletions(-)