From nobody Tue May 7 22:42:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1488422232207269.4762349355897; Wed, 1 Mar 2017 18:37:12 -0800 (PST) Received: from localhost ([::1]:49827 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cjGcA-0004Qz-EB for importer@patchew.org; Wed, 01 Mar 2017 21:37:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46691) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cjGbN-0004Qs-Rn for qemu-devel@nongnu.org; Wed, 01 Mar 2017 21:36:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cjGbJ-0003PA-4n for qemu-devel@nongnu.org; Wed, 01 Mar 2017 21:36:21 -0500 Received: from ozlabs.ru ([107.173.13.209]:55992) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cjGbI-0003Oa-SP; Wed, 01 Mar 2017 21:36:17 -0500 Received: from vpl2.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 738A13A60247; Wed, 1 Mar 2017 21:36:06 -0500 (EST) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Thu, 2 Mar 2017 13:36:11 +1100 Message-Id: <20170302023611.15541-1-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v4] exec, kvm, target-ppc: Move getrampagesize() to common code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini , qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" getrampagesize() returns the largest supported page size and mainly used to know if huge pages are enabled. However is implemented in target-ppc/kvm.c and not available in TCG or other architectures. This renames and moves gethugepagesize() to mmap-alloc.c where fd-based analog of it is already implemented. This renames and moves getrampagesize() to exec.c as it seems to be the common place for helpers like this. Signed-off-by: Alexey Kardashevskiy --- Changes: v4: * removed numa.h from kvm.c as it is not needed there anymore v3: * in exec.c, moved "include numa.h" under #ifndef CONFIG_USER_ONLY to fix linux-user target build v2: * rebased on top of ppc-for-2.9-20170301 --- include/exec/ram_addr.h | 1 + include/qemu/mmap-alloc.h | 2 + exec.c | 82 ++++++++++++++++++++++++++++++++++ target/ppc/kvm.c | 109 +++---------------------------------------= ---- util/mmap-alloc.c | 25 +++++++++++ 5 files changed, 115 insertions(+), 104 deletions(-) diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index 3e79466a44..cd432e73ae 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -52,6 +52,7 @@ static inline void *ramblock_ptr(RAMBlock *block, ram_add= r_t offset) return (char *)block->host + offset; } =20 +long qemu_getrampagesize(void); ram_addr_t last_ram_offset(void); RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, bool share, const char *mem_path, diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h index 933c024ac5..50385e3f81 100644 --- a/include/qemu/mmap-alloc.h +++ b/include/qemu/mmap-alloc.h @@ -5,6 +5,8 @@ =20 size_t qemu_fd_getpagesize(int fd); =20 +size_t qemu_mempath_getpagesize(const char *mem_path); + void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared); =20 void qemu_ram_munmap(void *ptr, size_t size); diff --git a/exec.c b/exec.c index 3adf2b1861..4c90cbf366 100644 --- a/exec.c +++ b/exec.c @@ -42,6 +42,7 @@ #include "exec/memory.h" #include "exec/ioport.h" #include "sysemu/dma.h" +#include "sysemu/numa.h" #include "exec/address-spaces.h" #include "sysemu/xen-mapcache.h" #include "trace-root.h" @@ -1251,6 +1252,87 @@ void qemu_mutex_unlock_ramlist(void) } =20 #ifdef __linux__ +/* + * FIXME TOCTTOU: this iterates over memory backends' mem-path, which + * may or may not name the same files / on the same filesystem now as + * when we actually open and map them. Iterate over the file + * descriptors instead, and use qemu_fd_getpagesize(). + */ +static int find_max_supported_pagesize(Object *obj, void *opaque) +{ + char *mem_path; + long *hpsize_min =3D opaque; + + if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) { + mem_path =3D object_property_get_str(obj, "mem-path", NULL); + if (mem_path) { + long hpsize =3D qemu_mempath_getpagesize(mem_path); + if (hpsize < *hpsize_min) { + *hpsize_min =3D hpsize; + } + } else { + *hpsize_min =3D getpagesize(); + } + } + + return 0; +} + +long qemu_getrampagesize(void) +{ + long hpsize =3D LONG_MAX; + long mainrampagesize; + Object *memdev_root; + + if (mem_path) { + mainrampagesize =3D qemu_mempath_getpagesize(mem_path); + } else { + mainrampagesize =3D getpagesize(); + } + + /* it's possible we have memory-backend objects with + * hugepage-backed RAM. these may get mapped into system + * address space via -numa parameters or memory hotplug + * hooks. we want to take these into account, but we + * also want to make sure these supported hugepage + * sizes are applicable across the entire range of memory + * we may boot from, so we take the min across all + * backends, and assume normal pages in cases where a + * backend isn't backed by hugepages. + */ + memdev_root =3D object_resolve_path("/objects", NULL); + if (memdev_root) { + object_child_foreach(memdev_root, find_max_supported_pagesize, &hp= size); + } + if (hpsize =3D=3D LONG_MAX) { + /* No additional memory regions found =3D=3D> Report main RAM page= size */ + return mainrampagesize; + } + + /* If NUMA is disabled or the NUMA nodes are not backed with a + * memory-backend, then there is at least one node using "normal" RAM, + * so if its page size is smaller we have got to report that size inst= ead. + */ + if (hpsize > mainrampagesize && + (nb_numa_nodes =3D=3D 0 || numa_info[0].node_memdev =3D=3D NULL)) { + static bool warned; + if (!warned) { + error_report("Huge page support disabled (n/a for main memory)= ."); + warned =3D true; + } + return mainrampagesize; + } + + return hpsize; +} +#else +long qemu_getrampagesize(void) +{ + return getpagesize(); +} +#endif + +#ifdef __linux__ static int64_t get_file_size(int fd) { int64_t size =3D lseek(fd, 0, SEEK_END); diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 18f33f2d93..0b8763cda5 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -28,7 +28,6 @@ #include "qemu/timer.h" #include "sysemu/sysemu.h" #include "sysemu/hw_accel.h" -#include "sysemu/numa.h" #include "kvm_ppc.h" #include "sysemu/cpus.h" #include "sysemu/device_tree.h" @@ -43,8 +42,10 @@ #include "trace.h" #include "exec/gdbstub.h" #include "exec/memattrs.h" +#include "exec/ram_addr.h" #include "sysemu/hostmem.h" #include "qemu/cutils.h" +#include "qemu/mmap-alloc.h" #if defined(TARGET_PPC64) #include "hw/ppc/spapr_cpu_core.h" #endif @@ -331,106 +332,6 @@ static void kvm_get_smmu_info(PowerPCCPU *cpu, struct= kvm_ppc_smmu_info *info) kvm_get_fallback_smmu_info(cpu, info); } =20 -static long gethugepagesize(const char *mem_path) -{ - struct statfs fs; - int ret; - - do { - ret =3D statfs(mem_path, &fs); - } while (ret !=3D 0 && errno =3D=3D EINTR); - - if (ret !=3D 0) { - fprintf(stderr, "Couldn't statfs() memory path: %s\n", - strerror(errno)); - exit(1); - } - -#define HUGETLBFS_MAGIC 0x958458f6 - - if (fs.f_type !=3D HUGETLBFS_MAGIC) { - /* Explicit mempath, but it's ordinary pages */ - return getpagesize(); - } - - /* It's hugepage, return the huge page size */ - return fs.f_bsize; -} - -/* - * FIXME TOCTTOU: this iterates over memory backends' mem-path, which - * may or may not name the same files / on the same filesystem now as - * when we actually open and map them. Iterate over the file - * descriptors instead, and use qemu_fd_getpagesize(). - */ -static int find_max_supported_pagesize(Object *obj, void *opaque) -{ - char *mem_path; - long *hpsize_min =3D opaque; - - if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) { - mem_path =3D object_property_get_str(obj, "mem-path", NULL); - if (mem_path) { - long hpsize =3D gethugepagesize(mem_path); - if (hpsize < *hpsize_min) { - *hpsize_min =3D hpsize; - } - } else { - *hpsize_min =3D getpagesize(); - } - } - - return 0; -} - -static long getrampagesize(void) -{ - long hpsize =3D LONG_MAX; - long mainrampagesize; - Object *memdev_root; - - if (mem_path) { - mainrampagesize =3D gethugepagesize(mem_path); - } else { - mainrampagesize =3D getpagesize(); - } - - /* it's possible we have memory-backend objects with - * hugepage-backed RAM. these may get mapped into system - * address space via -numa parameters or memory hotplug - * hooks. we want to take these into account, but we - * also want to make sure these supported hugepage - * sizes are applicable across the entire range of memory - * we may boot from, so we take the min across all - * backends, and assume normal pages in cases where a - * backend isn't backed by hugepages. - */ - memdev_root =3D object_resolve_path("/objects", NULL); - if (memdev_root) { - object_child_foreach(memdev_root, find_max_supported_pagesize, &hp= size); - } - if (hpsize =3D=3D LONG_MAX) { - /* No additional memory regions found =3D=3D> Report main RAM page= size */ - return mainrampagesize; - } - - /* If NUMA is disabled or the NUMA nodes are not backed with a - * memory-backend, then there is at least one node using "normal" RAM, - * so if its page size is smaller we have got to report that size inst= ead. - */ - if (hpsize > mainrampagesize && - (nb_numa_nodes =3D=3D 0 || numa_info[0].node_memdev =3D=3D NULL)) { - static bool warned; - if (!warned) { - error_report("Huge page support disabled (n/a for main memory)= ."); - warned =3D true; - } - return mainrampagesize; - } - - return hpsize; -} - static bool kvm_valid_page_size(uint32_t flags, long rampgsize, uint32_t s= hift) { if (!(flags & KVM_PPC_PAGE_SIZES_REAL)) { @@ -462,7 +363,7 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu) } =20 if (!max_cpu_page_size) { - max_cpu_page_size =3D getrampagesize(); + max_cpu_page_size =3D qemu_getrampagesize(); } =20 /* Convert to QEMU form */ @@ -523,7 +424,7 @@ bool kvmppc_is_mem_backend_page_size_ok(char *obj_path) long pagesize; =20 if (mempath) { - pagesize =3D gethugepagesize(mempath); + pagesize =3D qemu_mempath_getpagesize(mempath); } else { pagesize =3D getpagesize(); } @@ -2207,7 +2108,7 @@ uint64_t kvmppc_rma_size(uint64_t current_size, unsig= ned int hash_shift) /* Find the largest hardware supported page size that's less than * or equal to the (logical) backing page size of guest RAM */ kvm_get_smmu_info(POWERPC_CPU(first_cpu), &info); - rampagesize =3D getrampagesize(); + rampagesize =3D qemu_getrampagesize(); best_page_shift =3D 0; =20 for (i =3D 0; i < KVM_PPC_PAGE_SIZES_MAX_SZ; i++) { diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c index 2f55f5e94f..3ec029a9ea 100644 --- a/util/mmap-alloc.c +++ b/util/mmap-alloc.c @@ -40,6 +40,31 @@ size_t qemu_fd_getpagesize(int fd) return getpagesize(); } =20 +size_t qemu_mempath_getpagesize(const char *mem_path) +{ +#ifdef CONFIG_LINUX + struct statfs fs; + int ret; + + do { + ret =3D statfs(mem_path, &fs); + } while (ret !=3D 0 && errno =3D=3D EINTR); + + if (ret !=3D 0) { + fprintf(stderr, "Couldn't statfs() memory path: %s\n", + strerror(errno)); + exit(1); + } + + if (fs.f_type =3D=3D HUGETLBFS_MAGIC) { + /* It's hugepage, return the huge page size */ + return fs.f_bsize; + } +#endif + + return getpagesize(); +} + void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) { /* --=20 2.11.0