From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51114) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W1bG3-00081n-Au for qemu-devel@nongnu.org; Fri, 10 Jan 2014 07:32:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W1bFw-0006Gc-Ro for qemu-devel@nongnu.org; Fri, 10 Jan 2014 07:32:15 -0500 Received: from mx1.redhat.com ([209.132.183.28]:17763) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W1bFw-0006GU-HM for qemu-devel@nongnu.org; Fri, 10 Jan 2014 07:32:08 -0500 Date: Fri, 10 Jan 2014 14:31:58 +0200 From: "Michael S. Tsirkin" Message-ID: <20140110123158.GC10700@redhat.com> References: <1389279601-1924-1-git-send-email-a.motakis@virtualopensystems.com> <1389279601-1924-2-git-send-email-a.motakis@virtualopensystems.com> <20140109160117.GC3485@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline In-Reply-To: Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH v5 1/7] Convert -mem-path to QemuOpts and add prealloc, share and unlink properties List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Antonios Motakis Cc: Peter Maydell , snabb-devel@googlegroups.com, Anthony Liguori , Jan Kiszka , Michael Tokarev , qemu-devel qemu-devel , Nikolay Nikolaev , Alexander Graf , Stefan Hajnoczi , Luke Gorrie , Paolo Bonzini , VirtualOpenSystems Technical Team , Andreas =?iso-8859-1?Q?F=E4rber?= , Markus Armbruster , Richard Henderson On Fri, Jan 10, 2014 at 12:05:57PM +0100, Antonios Motakis wrote: >=20 >=20 >=20 > On Thu, Jan 9, 2014 at 5:01 PM, Michael S. Tsirkin wro= te: >=20 > On Thu, Jan 09, 2014 at 03:59:55PM +0100, Antonios Motakis wrote: > > Extend -mem-path with additional properties: > > > > =A0- prealloc=3Don|off - default off, same as -mem-prealloc > > =A0- share=3Don|off - default off, memory is mmapped with MAP_SHA= RED flag > > =A0- unlink=3Don|off - default on, inlink the file after openinng= it >=20 > typos >=20 >=20 > Ack. > =A0 >=20 >=20 > > > > Signed-off-by: Antonios Motakis > > Signed-off-by: Nikolay Nikolaev > > --- > > =A0exec.c =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 | 57 > +++++++++++++++++++++++++++++++++++++++++--------- > > =A0include/exec/cpu-all.h | =A03 --- > > =A0qemu-options.hx =A0 =A0 =A0 =A0| 10 +++++++-- > > =A0vl.c =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 | 41 ++++++++++++++++= +++++++++++++++----- > > =A04 files changed, 91 insertions(+), 20 deletions(-) > > > > diff --git a/exec.c b/exec.c > > index 7e49e8e..30f4019 100644 > > --- a/exec.c > > +++ b/exec.c > > @@ -957,6 +957,7 @@ void qemu_mutex_unlock_ramlist(void) > > =A0#include > > > > =A0#define HUGETLBFS_MAGIC =A0 =A0 =A0 0x958458f6 > > +#define MIN_HUGE_PAGE_SIZE =A0 =A0(2*1024*1024) > > > > =A0static long gethugepagesize(const char *path) > > =A0{ > > @@ -972,8 +973,9 @@ static long gethugepagesize(const char *path) > > =A0 =A0 =A0 =A0 =A0return 0; > > =A0 =A0 =A0} > > > > - =A0 =A0if (fs.f_type !=3D HUGETLBFS_MAGIC) > > - =A0 =A0 =A0 =A0fprintf(stderr, "Warning: path not on HugeTLBFS:= %s\n", path); > > + =A0 =A0if (fs.f_type !=3D HUGETLBFS_MAGIC) { > > + =A0 =A0 =A0 =A0return 0; > > + =A0 =A0} > > > > =A0 =A0 =A0return fs.f_bsize; > > =A0} > > @@ -994,11 +996,14 @@ static void *file_ram_alloc(RAMBlock *block= , > > =A0 =A0 =A0char *c; > > =A0 =A0 =A0void *area; > > =A0 =A0 =A0int fd; > > + =A0 =A0int flags; > > =A0 =A0 =A0unsigned long hpagesize; > > + =A0 =A0QemuOpts *opts; > > + =A0 =A0unsigned int mem_prealloc =3D 0, mem_share =3D 0, mem_un= link =3D 1; > > > > =A0 =A0 =A0hpagesize =3D gethugepagesize(path); > > =A0 =A0 =A0if (!hpagesize) { > > - =A0 =A0 =A0 =A0return NULL; > > + =A0 =A0 =A0 =A0hpagesize =3D MIN_HUGE_PAGE_SIZE; > > =A0 =A0 =A0} > > > > =A0 =A0 =A0if (memory < hpagesize) { > > @@ -1010,6 +1015,14 @@ static void *file_ram_alloc(RAMBlock *bloc= k, > > =A0 =A0 =A0 =A0 =A0return NULL; > > =A0 =A0 =A0} > > > > + =A0 =A0/* Fill config options */ > > + =A0 =A0opts =3D qemu_opts_find(qemu_find_opts("mem-path"), NULL= ); > > + =A0 =A0if (opts) { > > + =A0 =A0 =A0 =A0mem_prealloc =3D qemu_opt_get_bool(opts, "preall= oc", 0); > > + =A0 =A0 =A0 =A0mem_share =3D qemu_opt_get_bool(opts, "share", 0= ); > > + =A0 =A0 =A0 =A0mem_unlink =3D qemu_opt_get_bool(opts, "unlink",= 1); > > + =A0 =A0} > > + > > =A0 =A0 =A0/* Make name safe to use with mkstemp by replacing '/'= with '_'. */ > > =A0 =A0 =A0sanitized_name =3D g_strdup(block->mr->name); > > =A0 =A0 =A0for (c =3D sanitized_name; *c !=3D '\0'; c++) { > > @@ -1017,20 +1030,28 @@ static void *file_ram_alloc(RAMBlock *blo= ck, > > =A0 =A0 =A0 =A0 =A0 =A0 =A0*c =3D '_'; > > =A0 =A0 =A0} > > > > - =A0 =A0filename =3D g_strdup_printf("%s/qemu_back_mem.%s.XXXXXX= ", path, > > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 san= itized_name); > > + =A0 =A0filename =3D g_strdup_printf("%s/qemu_back_mem.%s%s", pa= th, > sanitized_name, > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (me= m_unlink) ? ".XXXXXX" : ""); > > =A0 =A0 =A0g_free(sanitized_name); > > > > - =A0 =A0fd =3D mkstemp(filename); > > + =A0 =A0if (mem_unlink) { > > + =A0 =A0 =A0 =A0fd =3D mkstemp(filename); > > + =A0 =A0} else { > > + =A0 =A0 =A0 =A0fd =3D open(filename, O_CREAT | O_RDWR | O_EXCL, > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0S_IRWXU | S_IRWXG | S_IRWXO); > > + =A0 =A0} > > =A0 =A0 =A0if (fd < 0) { > > - =A0 =A0 =A0 =A0perror("unable to create backing store for hugep= ages"); > > + =A0 =A0 =A0 =A0perror("unable to create guest RAM backing store= "); > > =A0 =A0 =A0 =A0 =A0g_free(filename); > > =A0 =A0 =A0 =A0 =A0return NULL; > > =A0 =A0 =A0} > > - =A0 =A0unlink(filename); > > + > > + =A0 =A0if (mem_unlink) { > > + =A0 =A0 =A0 =A0unlink(filename); > > + =A0 =A0} >=20 > If we don't unlink, what will? >=20 >=20 > The option to not unlink the file was added based on feedback on these = mailing > lists: http://lists.nongnu.org/archive/html/qemu-devel/2013-12/msg02769= .html >=20 > From our side we don't strictly need it, and we can remove it if it is > preferred that way. Maybe split this out as a separate patch. >=20 >=20 > > =A0 =A0 =A0g_free(filename); > > > > - =A0 =A0memory =3D (memory+hpagesize-1) & ~(hpagesize-1); > > + =A0 =A0memory =3D (memory + hpagesize - 1) & ~(hpagesize - 1); > > > > =A0 =A0 =A0/* > > =A0 =A0 =A0 * ftruncate is not supported by hugetlbfs in older > > @@ -1041,7 +1062,8 @@ static void *file_ram_alloc(RAMBlock *block= , > > =A0 =A0 =A0if (ftruncate(fd, memory)) > > =A0 =A0 =A0 =A0 =A0perror("ftruncate"); > > > > - =A0 =A0area =3D mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRI= VATE, fd, 0); > > + =A0 =A0flags =3D mem_share ? MAP_SHARED : MAP_PRIVATE; > > + =A0 =A0area =3D mmap(0, memory, PROT_READ | PROT_WRITE, flags, = fd, 0); > > =A0 =A0 =A0if (area =3D=3D MAP_FAILED) { > > =A0 =A0 =A0 =A0 =A0perror("file_ram_alloc: can't mmap RAM pages")= ; > > =A0 =A0 =A0 =A0 =A0close(fd); > > @@ -1211,11 +1233,18 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_ad= dr_t > size, void *host, > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 MemoryRegion *mr) > > =A0{ > > =A0 =A0 =A0RAMBlock *block, *new_block; > > + =A0 =A0QemuOpts *opts; > > + =A0 =A0const char *mem_path =3D 0; > > > > =A0 =A0 =A0size =3D TARGET_PAGE_ALIGN(size); > > =A0 =A0 =A0new_block =3D g_malloc0(sizeof(*new_block)); > > =A0 =A0 =A0new_block->fd =3D -1; > > > > + =A0 =A0opts =3D qemu_opts_find(qemu_find_opts("mem-path"), NULL= ); > > + =A0 =A0if (opts) { > > + =A0 =A0 =A0 =A0mem_path =3D qemu_opt_get(opts, "path"); > > + =A0 =A0} > > + > > =A0 =A0 =A0/* This assumes the iothread lock is taken here too. =A0= */ > > =A0 =A0 =A0qemu_mutex_lock_ramlist(); > > =A0 =A0 =A0new_block->mr =3D mr; > > @@ -1348,6 +1377,14 @@ void qemu_ram_remap(ram_addr_t addr, ram_a= ddr_t > length) > > =A0 =A0 =A0ram_addr_t offset; > > =A0 =A0 =A0int flags; > > =A0 =A0 =A0void *area, *vaddr; > > + =A0 =A0QemuOpts *opts; > > + =A0 =A0unsigned int mem_prealloc =3D 0; > > + > > + =A0 =A0/* Fill config options */ > > + =A0 =A0opts =3D qemu_opts_find(qemu_find_opts("mem-path"), NULL= ); > > + =A0 =A0if (opts) { > > + =A0 =A0 =A0 =A0mem_prealloc =3D qemu_opt_get_bool(opts, "preall= oc", 0); > > + =A0 =A0} > > > > =A0 =A0 =A0QTAILQ_FOREACH(block, &ram_list.blocks, next) { > > =A0 =A0 =A0 =A0 =A0offset =3D addr - block->offset; > > diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h > > index b6998f0..4f8e989 100644 > > --- a/include/exec/cpu-all.h > > +++ b/include/exec/cpu-all.h > > @@ -467,9 +467,6 @@ typedef struct RAMList { > > =A0} RAMList; > > =A0extern RAMList ram_list; > > > > -extern const char *mem_path; > > -extern int mem_prealloc; > > - > > =A0/* Flags stored in the low bits of the TLB virtual address. =A0= These are > > =A0 =A0 defined so that fast path ram access is all zeros. =A0*/ > > =A0/* Zero if TLB entry is valid. =A0*/ > > diff --git a/qemu-options.hx b/qemu-options.hx > > index bcfe9ea..0d35c9c 100644 > > --- a/qemu-options.hx > > +++ b/qemu-options.hx > > @@ -221,9 +221,15 @@ gigabytes respectively. > > =A0ETEXI > > > > =A0DEF("mem-path", HAS_ARG, QEMU_OPTION_mempath, > > - =A0 =A0"-mem-path FILE =A0provide backing storage for guest RAM= \n", > QEMU_ARCH_ALL) > > + =A0 =A0"-mem-path [path=3D]path[,prealloc=3Don|off][,share=3Don= |off][,unlink=3Don| > off]\n" > > + =A0 =A0" =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0provide backing storage= for guest RAM\n" > > + =A0 =A0" =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0path=3D a directory pat= h for the backing store\n" > > + =A0 =A0" =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0prealloc=3D preallocate= guest memory [default > disabled]\n" > > + =A0 =A0" =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0share=3D enable mmap sh= are flag [default disabled]\n" > > + =A0 =A0" =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0unlink=3D enable unlink= ing the guest RAM files > [default enabled]\n", > > + =A0 =A0 =A0 =A0QEMU_ARCH_ALL) > > =A0STEXI > > -@item -mem-path @var{path} > > +@item -mem-path [path=3D]@var{path}[,prealloc=3Don|off][,share=3D= on|off] > [,unlink=3Don|off] > > =A0@findex -mem-path > > =A0Allocate guest RAM from a temporarily created file in @var{pat= h}. > > =A0ETEXI > > diff --git a/vl.c b/vl.c > > index 7511e70..4a52e0d 100644 > > --- a/vl.c > > +++ b/vl.c > > @@ -187,8 +187,6 @@ DisplayType display_type =3D DT_DEFAULT; > > =A0static int display_remote; > > =A0const char* keyboard_layout =3D NULL; > > =A0ram_addr_t ram_size; > > -const char *mem_path =3D NULL; > > -int mem_prealloc =3D 0; /* force preallocation of physical targe= t memory * > / > > =A0int nb_nics; > > =A0NICInfo nd_table[MAX_NICS]; > > =A0int autostart; > > @@ -531,6 +529,31 @@ static QemuOptsList qemu_msg_opts =3D { > > =A0 =A0 =A0}, > > =A0}; > > > > +static QemuOptsList qemu_mem_path_opts =3D { > > + =A0 =A0.name =3D "mem-path", > > + =A0 =A0.implied_opt_name =3D "path", > > + =A0 =A0.head =3D QTAILQ_HEAD_INITIALIZER(qemu_mem_path_opts.hea= d), > > + =A0 =A0.desc =3D { > > + =A0 =A0 =A0 =A0{ > > + =A0 =A0 =A0 =A0 =A0 =A0.name =3D "path", > > + =A0 =A0 =A0 =A0 =A0 =A0.type =3D QEMU_OPT_STRING, > > + =A0 =A0 =A0 =A0}, > > + =A0 =A0 =A0 =A0{ > > + =A0 =A0 =A0 =A0 =A0 =A0.name =3D "prealloc", > > + =A0 =A0 =A0 =A0 =A0 =A0.type =3D QEMU_OPT_BOOL, > > + =A0 =A0 =A0 =A0}, > > + =A0 =A0 =A0 =A0{ > > + =A0 =A0 =A0 =A0 =A0 =A0.name =3D "share", > > + =A0 =A0 =A0 =A0 =A0 =A0.type =3D QEMU_OPT_BOOL, > > + =A0 =A0 =A0 =A0}, > > + =A0 =A0 =A0 =A0{ > > + =A0 =A0 =A0 =A0 =A0 =A0.name =3D "unlink", > > + =A0 =A0 =A0 =A0 =A0 =A0.type =3D QEMU_OPT_BOOL, > > + =A0 =A0 =A0 =A0}, > > + =A0 =A0 =A0 =A0{ /* end of list */ } > > + =A0 =A0}, > > +}; > > + > > =A0/** > > =A0 * Get machine options > > =A0 * > > @@ -2892,6 +2915,7 @@ int main(int argc, char **argv, char **envp= ) > > =A0 =A0 =A0qemu_add_opts(&qemu_tpmdev_opts); > > =A0 =A0 =A0qemu_add_opts(&qemu_realtime_opts); > > =A0 =A0 =A0qemu_add_opts(&qemu_msg_opts); > > + =A0 =A0qemu_add_opts(&qemu_mem_path_opts); > > > > =A0 =A0 =A0runstate_init(); > > > > @@ -3209,11 +3233,18 @@ int main(int argc, char **argv, char **en= vp) > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > > =A0#endif > > =A0 =A0 =A0 =A0 =A0 =A0 =A0case QEMU_OPTION_mempath: > > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mem_path =3D optarg; > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (!qemu_opts_parse(qemu_find_o= pts("mem-path"), optarg, > 1)) { > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0exit(1); > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > > - =A0 =A0 =A0 =A0 =A0 =A0case QEMU_OPTION_mem_prealloc: > > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mem_prealloc =3D 1; > > + =A0 =A0 =A0 =A0 =A0 =A0case QEMU_OPTION_mem_prealloc: { > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0QemuOpts *mem_opts =3D qemu_opts= _find(qemu_find_opts > ("mem-path"), > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0NULL); > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (mem_opts) { > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0qemu_opt_set(mem_opts, "= prealloc", "on"); > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > > + =A0 =A0 =A0 =A0 =A0 =A0} > > =A0 =A0 =A0 =A0 =A0 =A0 =A0case QEMU_OPTION_d: > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0log_mask =3D optarg; > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > > -- > > 1.8.3.2 > > >=20 >=20