diff mbox series

[RFC,v2,01/35] multi-process: memory: alloc RAM from file at offset

Message ID 20190617181459.29139-1-elena.ufimtseva@oracle.com (mailing list archive)
State New, archived
Headers show
Series Initial support of multi-process qemu | expand

Commit Message

Elena Ufimtseva June 17, 2019, 6:14 p.m. UTC
From: Jagannathan Raman <jag.raman@oracle.com>

Allow RAM MemoryRegion to be created from an offset in a file, instead
of allocating at offset of 0 by default. This is needed to synchronize
RAM between QEMU & remote process.
This will be needed for the following patches.

Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
---
 exec.c                    | 9 +++++----
 include/exec/ram_addr.h   | 2 +-
 include/qemu/mmap-alloc.h | 2 +-
 memory.c                  | 2 +-
 util/mmap-alloc.c         | 5 +++--
 util/oslib-posix.c        | 2 +-
 6 files changed, 12 insertions(+), 10 deletions(-)

Comments

Eric Blake June 17, 2019, 7:14 p.m. UTC | #1
On 6/17/19 1:14 PM, elena.ufimtseva@oracle.com wrote:
> From: Jagannathan Raman <jag.raman@oracle.com>
> 
> Allow RAM MemoryRegion to be created from an offset in a file, instead
> of allocating at offset of 0 by default. This is needed to synchronize
> RAM between QEMU & remote process.
> This will be needed for the following patches.

This message and the rest of the series was sent unthreaded (no
References: or In-Reply-To: headers), which makes it very difficult to
track. You'll want to fix your sending environment to ensure that
threading is preserved correctly.

> 
> Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
> Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
> Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
> ---
Elena Ufimtseva June 17, 2019, 7:46 p.m. UTC | #2
On Mon, Jun 17, 2019 at 02:14:49PM -0500, Eric Blake wrote:
> On 6/17/19 1:14 PM, elena.ufimtseva@oracle.com wrote:
> > From: Jagannathan Raman <jag.raman@oracle.com>
> > 
> > Allow RAM MemoryRegion to be created from an offset in a file, instead
> > of allocating at offset of 0 by default. This is needed to synchronize
> > RAM between QEMU & remote process.
> > This will be needed for the following patches.
> 
> This message and the rest of the series was sent unthreaded (no
> References: or In-Reply-To: headers), which makes it very difficult to
> track. You'll want to fix your sending environment to ensure that
> threading is preserved correctly.
>

Hi Eric

Yes, my bad. I have adjusted my scripts.

Elena
> > 
> > Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
> > Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
> > Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
> > ---
> 
> 
> -- 
> Eric Blake, Principal Software Engineer
> Red Hat, Inc.           +1-919-301-3226
> Virtualization:  qemu.org | libvirt.org
>
Gerd Hoffmann June 18, 2019, 5:12 a.m. UTC | #3
On Mon, Jun 17, 2019 at 11:14:59AM -0700, elena.ufimtseva@oracle.com wrote:
> From: Jagannathan Raman <jag.raman@oracle.com>
> 
> Allow RAM MemoryRegion to be created from an offset in a file, instead
> of allocating at offset of 0 by default. This is needed to synchronize
> RAM between QEMU & remote process.
> This will be needed for the following patches.

Details please.   vhost-user works fine without this ...

cheers,
  Gerd
Jag Raman Sept. 3, 2019, 9:16 p.m. UTC | #4
On 6/18/2019 1:12 AM, Gerd Hoffmann wrote:
> On Mon, Jun 17, 2019 at 11:14:59AM -0700, elena.ufimtseva@oracle.com wrote:
>> From: Jagannathan Raman <jag.raman@oracle.com>
>>
>> Allow RAM MemoryRegion to be created from an offset in a file, instead
>> of allocating at offset of 0 by default. This is needed to synchronize
>> RAM between QEMU & remote process.
>> This will be needed for the following patches.
> 
> Details please.   vhost-user works fine without this ...

Hi Gerd,

Sorry for the delayed response.

vhost-user doesn't use qemu_ram_alloc_from_fd(), it directly calls
mmap() to map the RAM onto the remote process.

Secondly, vhost-user uses its own functions (like vu_gpa_to_va()) for
address translation, whereas multi-process uses QEMU's existing
functions (address_space_rw()). Therefore, multi-process needs to use
qemu_ram_alloc_from_fd().

Lastly, updates to the system memory (received via MemoryListener) are
often in segments and not contiguous. Therefore, mapping these segments
in the remote process is possible only if we are able to allocate a
MemoryRegion at an offset in the memory backend.

Thanks!
--
Jag

> 
> cheers,
>    Gerd
> 
>
diff mbox series

Patch

diff --git a/exec.c b/exec.c
index 2646207661..ffe25169a8 100644
--- a/exec.c
+++ b/exec.c
@@ -1829,6 +1829,7 @@  static void *file_ram_alloc(RAMBlock *block,
                             ram_addr_t memory,
                             int fd,
                             bool truncate,
+                            off_t offset,
                             Error **errp)
 {
     void *area;
@@ -1879,7 +1880,7 @@  static void *file_ram_alloc(RAMBlock *block,
     }
 
     area = qemu_ram_mmap(fd, memory, block->mr->align,
-                         block->flags & RAM_SHARED);
+                         block->flags & RAM_SHARED, offset);
     if (area == MAP_FAILED) {
         error_setg_errno(errp, errno,
                          "unable to map backing store for guest RAM");
@@ -2268,7 +2269,7 @@  static void ram_block_add(RAMBlock *new_block, Error **errp, bool shared)
 #ifdef CONFIG_POSIX
 RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
                                  uint32_t ram_flags, int fd,
-                                 Error **errp)
+                                 off_t offset, Error **errp)
 {
     RAMBlock *new_block;
     Error *local_err = NULL;
@@ -2313,7 +2314,7 @@  RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
     new_block->used_length = size;
     new_block->max_length = size;
     new_block->flags = ram_flags;
-    new_block->host = file_ram_alloc(new_block, size, fd, !file_size, errp);
+    new_block->host = file_ram_alloc(new_block, size, fd, !file_size, offset, errp);
     if (!new_block->host) {
         g_free(new_block);
         return NULL;
@@ -2343,7 +2344,7 @@  RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
         return NULL;
     }
 
-    block = qemu_ram_alloc_from_fd(size, mr, ram_flags, fd, errp);
+    block = qemu_ram_alloc_from_fd(size, mr, ram_flags, fd, 0, errp);
     if (!block) {
         if (created) {
             unlink(mem_path);
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 9ecd911c3e..2ed457905c 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -100,7 +100,7 @@  RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
                                    Error **errp);
 RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
                                  uint32_t ram_flags, int fd,
-                                 Error **errp);
+                                 off_t offset, Error **errp);
 
 RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
                                   MemoryRegion *mr, Error **errp);
diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h
index ef04f0ed5b..25c4b12224 100644
--- a/include/qemu/mmap-alloc.h
+++ b/include/qemu/mmap-alloc.h
@@ -7,7 +7,7 @@  size_t qemu_fd_getpagesize(int fd);
 
 size_t qemu_mempath_getpagesize(const char *mem_path);
 
-void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared);
+void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared, off_t start);
 
 void qemu_ram_munmap(int fd, void *ptr, size_t size);
 
diff --git a/memory.c b/memory.c
index bb2b71ee38..858271b08b 100644
--- a/memory.c
+++ b/memory.c
@@ -1617,7 +1617,7 @@  void memory_region_init_ram_from_fd(MemoryRegion *mr,
     mr->destructor = memory_region_destructor_ram;
     mr->ram_block = qemu_ram_alloc_from_fd(size, mr,
                                            share ? RAM_SHARED : 0,
-                                           fd, &err);
+                                           fd, 0, &err);
     mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
     if (err) {
         mr->size = int128_zero();
diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
index 8565885420..58cb4cc267 100644
--- a/util/mmap-alloc.c
+++ b/util/mmap-alloc.c
@@ -75,7 +75,7 @@  size_t qemu_mempath_getpagesize(const char *mem_path)
     return getpagesize();
 }
 
-void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared)
+void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared, off_t start)
 {
     int flags;
     int guardfd;
@@ -130,7 +130,8 @@  void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared)
     flags |= shared ? MAP_SHARED : MAP_PRIVATE;
     offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guardptr;
 
-    ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, flags, fd, 0);
+    ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, flags, fd,
+               start);
 
     if (ptr == MAP_FAILED) {
         munmap(guardptr, total);
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 88dda9cd39..2d4907dc59 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -203,7 +203,7 @@  void *qemu_memalign(size_t alignment, size_t size)
 void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment, bool shared)
 {
     size_t align = QEMU_VMALLOC_ALIGN;
-    void *ptr = qemu_ram_mmap(-1, size, align, shared);
+    void *ptr = qemu_ram_mmap(-1, size, align, shared, 0);
 
     if (ptr == MAP_FAILED) {
         return NULL;