From b5837d1271115515f4f18856888ba14779afc7aa Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 14 Jan 2021 19:59:52 +0300 Subject: [PATCH 1/3] Memory: use MADV_DONTDUMP if available (Linux) Also refactor other madvise() usage --- rpcs3/util/vm_native.cpp | 82 +++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 22 deletions(-) diff --git a/rpcs3/util/vm_native.cpp b/rpcs3/util/vm_native.cpp index 342e94db9ad3..7e8445e02a3a 100644 --- a/rpcs3/util/vm_native.cpp +++ b/rpcs3/util/vm_native.cpp @@ -27,24 +27,44 @@ static int memfd_create_(const char *name, uint flags) { - return syscall(__NR_memfd_create, name, flags); + return syscall(__NR_memfd_create, name, flags); } #endif namespace utils { #ifdef MAP_NORESERVE - constexpr auto c_map_noreserve = MAP_NORESERVE; + constexpr int c_map_noreserve = MAP_NORESERVE; #else constexpr int c_map_noreserve = 0; #endif #ifdef MADV_FREE - constexpr auto c_madv_free = MADV_FREE; + constexpr int c_madv_free = MADV_FREE; #elif defined(MADV_DONTNEED) - constexpr auto c_madv_free = MADV_DONTNEED; + constexpr int c_madv_free = MADV_DONTNEED; #else - constexpr auto c_madv_free = 0; + constexpr int c_madv_free = 0; +#endif + +#ifdef MADV_HUGEPAGE + constexpr int c_madv_hugepage = MADV_HUGEPAGE; +#else + constexpr int c_madv_hugepage = 0; +#endif + +#if defined(MADV_DONTDUMP) && defined(MADV_DODUMP) + constexpr int c_madv_no_dump = MADV_DONTDUMP; + constexpr int c_madv_dump = MADV_DODUMP; +#else + constexpr int c_madv_no_dump = 0; + constexpr int c_madv_dump = 0; +#endif + +#if defined(MFD_HUGETLB) && defined(MFD_HUGE_2MB) + constexpr int c_mfd_huge_2mb = MFD_HUGETLB | MFD_HUGE_2MB; +#else + constexpr int c_mfd_huge_2mb = 0; #endif #ifdef _WIN32 @@ -90,7 +110,7 @@ namespace utils return nullptr; } - [[maybe_unused]] const auto orig_size = size; + const auto orig_size = size; if (!use_addr) { @@ -125,10 +145,18 @@ namespace utils ptr = static_cast(ptr) + (0x10000 - misalign); } -#ifdef MADV_HUGEPAGE - if (orig_size % 0x200000 == 0) - ::madvise(ptr, orig_size, MADV_HUGEPAGE); -#endif + if constexpr (c_madv_hugepage != 0) + { + if (orig_size % 0x200000 == 0) + { + ::madvise(ptr, orig_size, c_madv_hugepage); + } + } + + if constexpr (c_madv_no_dump != 0) + { + ensure(::madvise(ptr, orig_size, c_madv_no_dump) != -1); + } return ptr; #endif @@ -141,7 +169,7 @@ namespace utils #else const u64 ptr64 = reinterpret_cast(pointer); ensure(::mprotect(reinterpret_cast(ptr64 & -4096), size + (ptr64 & 4095), +prot) != -1); - ensure(::madvise(reinterpret_cast(ptr64 & -4096), size + (ptr64 & 4095), MADV_WILLNEED) != -1); + ensure(::madvise(reinterpret_cast(ptr64 & -4096), size + (ptr64 & 4095), MADV_WILLNEED | c_madv_dump) != -1); #endif } @@ -152,7 +180,11 @@ namespace utils #else const u64 ptr64 = reinterpret_cast(pointer); ensure(::mmap(pointer, size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE | c_map_noreserve, -1, 0) != reinterpret_cast(-1)); - ensure(::madvise(reinterpret_cast(ptr64 & -4096), size + (ptr64 & 4095), c_madv_free) != -1); + + if constexpr (c_madv_no_dump != 0) + { + ensure(::madvise(reinterpret_cast(ptr64 & -4096), size + (ptr64 & 4095), c_madv_no_dump) != -1); + } #endif } @@ -163,14 +195,17 @@ namespace utils memory_commit(pointer, size, prot); #else const u64 ptr64 = reinterpret_cast(pointer); - ensure(::madvise(reinterpret_cast(ptr64 & -4096), size + (ptr64 & 4095), c_madv_free) != -1); ensure(::mmap(pointer, size, +prot, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0) != reinterpret_cast(-1)); - ensure(::madvise(reinterpret_cast(ptr64 & -4096), size + (ptr64 & 4095), MADV_WILLNEED) != -1); -#ifdef MADV_HUGEPAGE - if (size % 0x200000 == 0) - ::madvise(reinterpret_cast(ptr64 & -4096), size + (ptr64 & 4095), MADV_HUGEPAGE); -#endif + if constexpr (c_madv_hugepage != 0) + { + if (size % 0x200000 == 0) + { + ::madvise(reinterpret_cast(ptr64 & -4096), size + (ptr64 & 4095), c_madv_hugepage); + } + } + + ensure(::madvise(reinterpret_cast(ptr64 & -4096), size + (ptr64 & 4095), MADV_WILLNEED) != -1); #endif } @@ -225,13 +260,16 @@ namespace utils ensure(m_handle != INVALID_HANDLE_VALUE); #elif __linux__ m_file = -1; -#ifdef MFD_HUGETLB + // Try to use 2MB pages for 2M-aligned shm - if (m_size % 0x200000 == 0 && flags & 2) + if constexpr (c_mfd_huge_2mb) { - m_file = ::memfd_create_("2M", MFD_HUGETLB | MFD_HUGE_2MB); + if (m_size % 0x200000 == 0 && flags & 2) + { + m_file = ::memfd_create_("2M", c_mfd_huge_2mb); + } } -#endif + if (m_file == -1) { m_file = ::memfd_create_("", 0); From 4ed76a15ffd4117486f222be37b73dec8748e2e4 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 15 Jan 2021 19:56:05 +0300 Subject: [PATCH 2/3] Use different approach in shm::unmap_critical (Linux) For now, set protection to PROT_NONE. Attempt to address #9609 --- rpcs3/util/vm_native.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/util/vm_native.cpp b/rpcs3/util/vm_native.cpp index 7e8445e02a3a..55931777ed09 100644 --- a/rpcs3/util/vm_native.cpp +++ b/rpcs3/util/vm_native.cpp @@ -461,7 +461,7 @@ namespace utils return; } #else - ::mmap(reinterpret_cast(target), m_size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE | c_map_noreserve, -1, 0); + ensure(::mprotect(target, m_size, PROT_NONE) != -1); #endif } From aaaeb66cc89b9dea327a33a447af43b85b6f35db Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 15 Jan 2021 20:11:30 +0300 Subject: [PATCH 3/3] vm: Minor fix in vm::close Supplied size was wrong. --- rpcs3/Emu/Memory/vm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 0ce6b7acb0bd..d6d96b6d4184 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -1659,7 +1659,7 @@ namespace vm g_locations.clear(); utils::memory_decommit(g_base_addr, 0x200000000); - utils::memory_decommit(g_exec_addr, 0x100000000); + utils::memory_decommit(g_exec_addr, 0x200000000); utils::memory_decommit(g_stat_addr, 0x100000000); } }