On Mon, Dec 16, 2013 at 8:32 AM, Edgar E. Iglesias <edgar.igles...@gmail.com
> wrote:

> On Fri, Dec 13, 2013 at 12:14:31PM +0100, Antonios Motakis wrote:
> > This option complements -mem-path. It implies -mem-prealloc. If
> specified,
> > the guest RAM is allocated as a shared memory object. If both -mem-path
> > and -mem-share are provided, the memory is allocated from the HugeTLBFS
> > supplied path, and then mmapped with MAP_SHARED.
>
> Hi,
>
> Interesting, I've got a similar use-case here where I've added a
> -mem-shared
> option. I've got a few comments/questions.
>
> Why do you imply -mem-prealloc? cant the user keep controlling that through
> -mem-prealloc?
>
> I'd prefer if -mem-share did not use shm_open but took a directory path as
> arg
> and created the backing files there. I'd also prefer if the files had
> deterministic names and where not unlinked after creation. I.e, let the
> user
> delete them when no longer needed.
>
> The reason for this is that it makes it easier to use apps that are not
> aware of shm or QEMU specifics to manipulate the memory backing. I
> understand
> that there might be issues (e.g filling up the disk, slow access over NFS
> etc)
> but these are at the choice of the user.
>
>
Currently -mem-path implies HugeTLBFS for the supplied path. Maybe we
should change
its behavior to do what you suggest:

-mem-path - specify a directory where to allocate the mmap-ed ram files
(and don't unlink them)
-mem-hugetlbfs - check mem-path directory for HugeTLBFS (do we need this
one?)
-mem-share - add MAP_SHARED to mmap
-mem-prealloc - preallocate the memory

How does this sound?



> Any thoughts around this?
>
> Best regards,
> Edgar
>
>
>
> >
> > Signed-off-by: Antonios Motakis <a.mota...@virtualopensystems.com>
> > Signed-off-by: Nikolay Nikolaev <n.nikol...@virtualopensystems.com>
> > ---
> >  exec.c                 | 72
> +++++++++++++++++++++++++++++++++++---------------
> >  include/exec/cpu-all.h |  1 +
> >  qemu-options.hx        |  9 +++++++
> >  vl.c                   |  5 ++++
> >  4 files changed, 66 insertions(+), 21 deletions(-)
> >
> > diff --git a/exec.c b/exec.c
> > index f4b9ef2..10720f1 100644
> > --- a/exec.c
> > +++ b/exec.c
> > @@ -883,6 +883,7 @@ void qemu_mutex_unlock_ramlist(void)
> >  #include <sys/vfs.h>
> >
> >  #define HUGETLBFS_MAGIC       0x958458f6
> > +#define MIN_HUGE_PAGE_SIZE    (2*1024*1024)
> >
> >  static long gethugepagesize(const char *path)
> >  {
> > @@ -920,15 +921,24 @@ static void *file_ram_alloc(RAMBlock *block,
> >      char *c;
> >      void *area;
> >      int fd;
> > +    int flags;
> >      unsigned long hpagesize;
> >
> > -    hpagesize = gethugepagesize(path);
> > -    if (!hpagesize) {
> > -        return NULL;
> > -    }
> > +    if (path) {
> > +        hpagesize = gethugepagesize(path);
> >
> > -    if (memory < hpagesize) {
> > -        return NULL;
> > +        if (!hpagesize) {
> > +            return NULL ;
> > +        }
> > +
> > +        if (memory < hpagesize) {
> > +            return NULL ;
> > +        }
> > +    } else {
> > +        if (memory < MIN_HUGE_PAGE_SIZE) {
> > +            return NULL ;
> > +        }
> > +        hpagesize = MIN_HUGE_PAGE_SIZE;
> >      }
> >
> >      if (kvm_enabled() && !kvm_has_sync_mmu()) {
> > @@ -943,20 +953,37 @@ static void *file_ram_alloc(RAMBlock *block,
> >              *c = '_';
> >      }
> >
> > -    filename = g_strdup_printf("%s/qemu_back_mem.%s.XXXXXX", path,
> > -                               sanitized_name);
> > -    g_free(sanitized_name);
> > +    if (path) {
> > +
> > +        filename = g_strdup_printf("%s/qemu_back_mem.%s.XXXXXX", path,
> > +                sanitized_name);
> > +        g_free(sanitized_name);
> >
> > -    fd = mkstemp(filename);
> > -    if (fd < 0) {
> > -        perror("unable to create backing store for hugepages");
> > +        fd = mkstemp(filename);
> > +        if (fd < 0) {
> > +            perror("unable to create backing store for huge");
> > +            g_free(filename);
> > +            return NULL ;
> > +        }
> > +        unlink(filename);
> >          g_free(filename);
> > +        memory = (memory + hpagesize - 1) & ~(hpagesize - 1);
> > +    } else if (mem_share) {
> > +        filename = g_strdup_printf("qemu_back_mem.%s.XXXXXX",
> sanitized_name);
> > +        g_free(sanitized_name);
> > +        fd = shm_open(filename, O_CREAT | O_RDWR | O_EXCL,
> > +                      S_IRWXU | S_IRWXG | S_IRWXO);
> > +        if (fd < 0) {
> > +            perror("unable to create backing store for shared memory");
> > +            g_free(filename);
> > +            return NULL ;
> > +        }
> > +        shm_unlink(filename);
> > +        g_free(filename);
> > +    } else {
> > +        fprintf(stderr, "-mem-path or -mem-share required\n");
> >          return NULL;
> >      }
> > -    unlink(filename);
> > -    g_free(filename);
> > -
> > -    memory = (memory+hpagesize-1) & ~(hpagesize-1);
> >
> >      /*
> >       * ftruncate is not supported by hugetlbfs in older
> > @@ -967,7 +994,8 @@ static void *file_ram_alloc(RAMBlock *block,
> >      if (ftruncate(fd, memory))
> >          perror("ftruncate");
> >
> > -    area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
> > +    flags = mem_share ? MAP_SHARED : MAP_PRIVATE;
> > +    area = mmap(0, memory, PROT_READ | PROT_WRITE, flags, fd, 0);
> >      if (area == MAP_FAILED) {
> >          perror("file_ram_alloc: can't mmap RAM pages");
> >          close(fd);
> > @@ -1150,13 +1178,14 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t
> size, void *host,
> >          new_block->host = host;
> >          new_block->flags |= RAM_PREALLOC_MASK;
> >      } else if (xen_enabled()) {
> > -        if (mem_path) {
> > -            fprintf(stderr, "-mem-path not supported with Xen\n");
> > +        if (mem_path || mem_share) {
> > +            fprintf(stderr,
> > +                    "-mem-path and -mem-share not supported with
> Xen\n");
> >              exit(1);
> >          }
> >          xen_ram_alloc(new_block->offset, size, mr);
> >      } else {
> > -        if (mem_path) {
> > +        if (mem_path || mem_share) {
> >              if (phys_mem_alloc != qemu_anon_ram_alloc) {
> >                  /*
> >                   * file_ram_alloc() needs to allocate just like
> > @@ -1164,7 +1193,8 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t
> size, void *host,
> >                   * a hook there.
> >                   */
> >                  fprintf(stderr,
> > -                        "-mem-path not supported with this
> accelerator\n");
> > +                        "-mem-path and -mem-share "
> > +                        "not supported with this accelerator\n");
> >                  exit(1);
> >              }
> >              new_block->host = file_ram_alloc(new_block, size, mem_path);
> > diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> > index b6998f0..05ad0ee 100644
> > --- a/include/exec/cpu-all.h
> > +++ b/include/exec/cpu-all.h
> > @@ -469,6 +469,7 @@ extern RAMList ram_list;
> >
> >  extern const char *mem_path;
> >  extern int mem_prealloc;
> > +extern int mem_share;
> >
> >  /* Flags stored in the low bits of the TLB virtual address.  These are
> >     defined so that fast path ram access is all zeros.  */
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index af34483..bd70777 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -237,6 +237,15 @@ STEXI
> >  Preallocate memory when using -mem-path.
> >  ETEXI
> >
> > +DEF("mem-share", 0, QEMU_OPTION_mem_share,
> > +    "-mem-share   share guest memory (implies -mem-prealloc)\n",
> > +    QEMU_ARCH_ALL)
> > +STEXI
> > +@item -mem-share
> > +@findex -mem-share
> > +Allocate guest RAM as a shared memory object.
> > +ETEXI
> > +
> >  DEF("k", HAS_ARG, QEMU_OPTION_k,
> >      "-k language     use keyboard layout (for example 'fr' for
> French)\n",
> >      QEMU_ARCH_ALL)
> > diff --git a/vl.c b/vl.c
> > index b0399de..d2f7403 100644
> > --- a/vl.c
> > +++ b/vl.c
> > @@ -189,6 +189,7 @@ const char* keyboard_layout = NULL;
> >  ram_addr_t ram_size;
> >  const char *mem_path = NULL;
> >  int mem_prealloc = 0; /* force preallocation of physical target memory
> */
> > +int mem_share = 0; /* allocate shared memory */
> >  int nb_nics;
> >  NICInfo nd_table[MAX_NICS];
> >  int autostart;
> > @@ -3212,6 +3213,10 @@ int main(int argc, char **argv, char **envp)
> >              case QEMU_OPTION_mem_prealloc:
> >                  mem_prealloc = 1;
> >                  break;
> > +            case QEMU_OPTION_mem_share:
> > +                mem_share = 1;
> > +                mem_prealloc = 1;
> > +                break;
> >              case QEMU_OPTION_d:
> >                  log_mask = optarg;
> >                  break;
> > --
> > 1.8.3.2
> >
> >
>

Reply via email to