From patchwork Thu Jan 9 14:59:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonios Motakis X-Patchwork-Id: 308847 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 70D3F2C0344 for ; Fri, 10 Jan 2014 02:01:44 +1100 (EST) Received: from localhost ([::1]:52438 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W1H78-0000EO-69 for incoming@patchwork.ozlabs.org; Thu, 09 Jan 2014 10:01:42 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53786) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W1H6c-0000DG-9M for qemu-devel@nongnu.org; Thu, 09 Jan 2014 10:01:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W1H6W-0000LN-8E for qemu-devel@nongnu.org; Thu, 09 Jan 2014 10:01:10 -0500 Received: from mail-wg0-f49.google.com ([74.125.82.49]:44953) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W1H6V-0000LC-VV for qemu-devel@nongnu.org; Thu, 09 Jan 2014 10:01:04 -0500 Received: by mail-wg0-f49.google.com with SMTP id a1so614037wgh.16 for ; Thu, 09 Jan 2014 07:01:03 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=fbkDnyYahOB1RFNSW5PZVsAAvoRH8TCMA9S7H5yGp/E=; b=EWqVSyQSVoGH6M6LWe+IlOjyFlyzFjhP02SaRW+RheT3g6GgiFFD4MwPLHXW60GgNv 5Y10id2gSKhv5FaGCtAWuI0IjKH3m81NamUpamOE/PY8PTe81jM4kqebJwCcl92IyUBU exF8sGMgGrXlFF3L1TyLC7KjjvfN/6gZ0YrWsNFeSOkZAZANQW0wJopRzSUMddnkKHmy NQg1WYYToLv275EB6V3wV8Bu3vIZf/3z1KuXNmukSB7Mui69cCb4Z8Q1HEUoTAPrqZB8 8DZ+f/gX+SkfbdsRR5rcOiW5habJ0MagLk4nx/rriLeepFv6xHDgMxnYQerhReVwN0br ICag== X-Gm-Message-State: ALoCoQkYGl4OraSOXcarW9/nyoZsftD13Q3ukdGQySvoaiTAtqJHikeYv2cFEW0A2BcF6elM+ARC X-Received: by 10.194.202.230 with SMTP id kl6mr3451221wjc.9.1389279662843; Thu, 09 Jan 2014 07:01:02 -0800 (PST) Received: from localhost.localdomain (home.tvelocity.eu. [82.67.68.96]) by mx.google.com with ESMTPSA id k10sm1765683wjf.11.2014.01.09.07.01.00 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 09 Jan 2014 07:01:01 -0800 (PST) From: Antonios Motakis To: qemu-devel@nongnu.org, snabb-devel@googlegroups.com Date: Thu, 9 Jan 2014 15:59:55 +0100 Message-Id: <1389279601-1924-2-git-send-email-a.motakis@virtualopensystems.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1389279601-1924-1-git-send-email-a.motakis@virtualopensystems.com> References: <1389279601-1924-1-git-send-email-a.motakis@virtualopensystems.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 74.125.82.49 Cc: Peter Maydell , Stefan Hajnoczi , Jan Kiszka , Michael Tokarev , Alexander Graf , n.nikolaev@virtualopensystems.com, Markus Armbruster , Anthony Liguori , Paolo Bonzini , lukego@gmail.com, Antonios Motakis , tech@virtualopensystems.com, =?UTF-8?q?Andreas=20F=C3=A4rber?= , Richard Henderson Subject: [Qemu-devel] [PATCH v5 1/7] Convert -mem-path to QemuOpts and add prealloc, share and unlink properties X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Extend -mem-path with additional properties: - prealloc=on|off - default off, same as -mem-prealloc - share=on|off - default off, memory is mmapped with MAP_SHARED flag - unlink=on|off - default on, inlink the file after openinng it Signed-off-by: Antonios Motakis Signed-off-by: Nikolay Nikolaev Reviewed-by: Edgar E. Iglesias --- exec.c | 57 +++++++++++++++++++++++++++++++++++++++++--------- include/exec/cpu-all.h | 3 --- qemu-options.hx | 10 +++++++-- vl.c | 41 +++++++++++++++++++++++++++++++----- 4 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) #include #define HUGETLBFS_MAGIC 0x958458f6 +#define MIN_HUGE_PAGE_SIZE (2*1024*1024) static long gethugepagesize(const char *path) { @@ -972,8 +973,9 @@ static long gethugepagesize(const char *path) return 0; } - if (fs.f_type != HUGETLBFS_MAGIC) - fprintf(stderr, "Warning: path not on HugeTLBFS: %s\n", path); + if (fs.f_type != HUGETLBFS_MAGIC) { + return 0; + } return fs.f_bsize; } @@ -994,11 +996,14 @@ static void *file_ram_alloc(RAMBlock *block, char *c; void *area; int fd; + int flags; unsigned long hpagesize; + QemuOpts *opts; + unsigned int mem_prealloc = 0, mem_share = 0, mem_unlink = 1; hpagesize = gethugepagesize(path); if (!hpagesize) { - return NULL; + hpagesize = MIN_HUGE_PAGE_SIZE; } if (memory < hpagesize) { @@ -1010,6 +1015,14 @@ static void *file_ram_alloc(RAMBlock *block, return NULL; } + /* Fill config options */ + opts = qemu_opts_find(qemu_find_opts("mem-path"), NULL); + if (opts) { + mem_prealloc = qemu_opt_get_bool(opts, "prealloc", 0); + mem_share = qemu_opt_get_bool(opts, "share", 0); + mem_unlink = qemu_opt_get_bool(opts, "unlink", 1); + } + /* Make name safe to use with mkstemp by replacing '/' with '_'. */ sanitized_name = g_strdup(block->mr->name); for (c = sanitized_name; *c != '\0'; c++) { @@ -1017,20 +1030,28 @@ static void *file_ram_alloc(RAMBlock *block, *c = '_'; } - filename = g_strdup_printf("%s/qemu_back_mem.%s.XXXXXX", path, - sanitized_name); + filename = g_strdup_printf("%s/qemu_back_mem.%s%s", path, sanitized_name, + (mem_unlink) ? ".XXXXXX" : ""); g_free(sanitized_name); - fd = mkstemp(filename); + if (mem_unlink) { + fd = mkstemp(filename); + } else { + fd = open(filename, O_CREAT | O_RDWR | O_EXCL, + S_IRWXU | S_IRWXG | S_IRWXO); + } if (fd < 0) { - perror("unable to create backing store for hugepages"); + perror("unable to create guest RAM backing store"); g_free(filename); return NULL; } - unlink(filename); + + if (mem_unlink) { + unlink(filename); + } g_free(filename); - memory = (memory+hpagesize-1) & ~(hpagesize-1); + memory = (memory + hpagesize - 1) & ~(hpagesize - 1); /* * ftruncate is not supported by hugetlbfs in older @@ -1041,7 +1062,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); @@ -1211,11 +1233,18 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, MemoryRegion *mr) { RAMBlock *block, *new_block; + QemuOpts *opts; + const char *mem_path = 0; size = TARGET_PAGE_ALIGN(size); new_block = g_malloc0(sizeof(*new_block)); new_block->fd = -1; + opts = qemu_opts_find(qemu_find_opts("mem-path"), NULL); + if (opts) { + mem_path = qemu_opt_get(opts, "path"); + } + /* This assumes the iothread lock is taken here too. */ qemu_mutex_lock_ramlist(); new_block->mr = mr; @@ -1348,6 +1377,14 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length) ram_addr_t offset; int flags; void *area, *vaddr; + QemuOpts *opts; + unsigned int mem_prealloc = 0; + + /* Fill config options */ + opts = qemu_opts_find(qemu_find_opts("mem-path"), NULL); + if (opts) { + mem_prealloc = qemu_opt_get_bool(opts, "prealloc", 0); + } QTAILQ_FOREACH(block, &ram_list.blocks, next) { offset = 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 { } RAMList; extern RAMList ram_list; -extern const char *mem_path; -extern int mem_prealloc; - /* Flags stored in the low bits of the TLB virtual address. These are defined so that fast path ram access is all zeros. */ /* Zero if TLB entry is valid. */ 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. ETEXI DEF("mem-path", HAS_ARG, QEMU_OPTION_mempath, - "-mem-path FILE provide backing storage for guest RAM\n", QEMU_ARCH_ALL) + "-mem-path [path=]path[,prealloc=on|off][,share=on|off][,unlink=on|off]\n" + " provide backing storage for guest RAM\n" + " path= a directory path for the backing store\n" + " prealloc= preallocate guest memory [default disabled]\n" + " share= enable mmap share flag [default disabled]\n" + " unlink= enable unlinking the guest RAM files [default enabled]\n", + QEMU_ARCH_ALL) STEXI -@item -mem-path @var{path} +@item -mem-path [path=]@var{path}[,prealloc=on|off][,share=on|off][,unlink=on|off] @findex -mem-path Allocate guest RAM from a temporarily created file in @var{path}. ETEXI 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 = DT_DEFAULT; static int display_remote; 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 nb_nics; NICInfo nd_table[MAX_NICS]; int autostart; @@ -531,6 +529,31 @@ static QemuOptsList qemu_msg_opts = { }, }; +static QemuOptsList qemu_mem_path_opts = { + .name = "mem-path", + .implied_opt_name = "path", + .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_path_opts.head), + .desc = { + { + .name = "path", + .type = QEMU_OPT_STRING, + }, + { + .name = "prealloc", + .type = QEMU_OPT_BOOL, + }, + { + .name = "share", + .type = QEMU_OPT_BOOL, + }, + { + .name = "unlink", + .type = QEMU_OPT_BOOL, + }, + { /* end of list */ } + }, +}; + /** * Get machine options * @@ -2892,6 +2915,7 @@ int main(int argc, char **argv, char **envp) qemu_add_opts(&qemu_tpmdev_opts); qemu_add_opts(&qemu_realtime_opts); qemu_add_opts(&qemu_msg_opts); + qemu_add_opts(&qemu_mem_path_opts); runstate_init(); @@ -3209,11 +3233,18 @@ int main(int argc, char **argv, char **envp) break; #endif case QEMU_OPTION_mempath: - mem_path = optarg; + if (!qemu_opts_parse(qemu_find_opts("mem-path"), optarg, 1)) { + exit(1); + } break; - case QEMU_OPTION_mem_prealloc: - mem_prealloc = 1; + case QEMU_OPTION_mem_prealloc: { + QemuOpts *mem_opts = qemu_opts_find(qemu_find_opts("mem-path"), + NULL); + if (mem_opts) { + qemu_opt_set(mem_opts, "prealloc", "on"); + } break; + } case QEMU_OPTION_d: log_mask = optarg; break;