Add support for 16K pages Removes base::kPageSize and make everything depend on base::GetPageSize(). There is only one thing missing that I need to figure out: the fact that this needs a: extra_target_ldflags="-Wl,-z,max-page-size=65536" to work. I need to consult with 16K experts to figure out what's the best way forward. Test: all existing tests pass. Test: manual smoke test of traced_probes & traced_perf Bug: 269635302 Change-Id: I105e02ad364f9e8daffbf5cb2235493fda8dca11
diff --git a/src/base/paged_memory_unittest.cc b/src/base/paged_memory_unittest.cc index 7e3508b..388b5b2 100644 --- a/src/base/paged_memory_unittest.cc +++ b/src/base/paged_memory_unittest.cc
@@ -35,14 +35,14 @@ TEST(PagedMemoryTest, Basic) { const size_t kNumPages = 10; - const size_t kSize = 4096 * kNumPages; + const size_t kSize = GetSysPageSize() * kNumPages; #if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) void* ptr_raw = nullptr; #endif { PagedMemory mem = PagedMemory::Allocate(kSize); ASSERT_TRUE(mem.IsValid()); - ASSERT_EQ(0u, reinterpret_cast<uintptr_t>(mem.Get()) % 4096); + ASSERT_EQ(0u, reinterpret_cast<uintptr_t>(mem.Get()) % GetSysPageSize()); #if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) ptr_raw = mem.Get(); #endif @@ -95,8 +95,8 @@ } TEST(PagedMemoryTest, Uncommitted) { - constexpr size_t kNumPages = 4096; - constexpr size_t kSize = 4096 * kNumPages; + const size_t kNumPages = 4096; + const size_t kSize = GetSysPageSize() * kNumPages; #if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) char* ptr_raw = nullptr; #endif @@ -156,14 +156,14 @@ TEST(PagedMemoryTest, AccessUncommittedMemoryTriggersASAN) { EXPECT_DEATH_IF_SUPPORTED( { - constexpr size_t kNumPages = 4096; - constexpr size_t kSize = 4096 * kNumPages; + const size_t kNumPages = 2000; + const size_t kSize = GetSysPageSize() * kNumPages; PagedMemory mem = PagedMemory::Allocate(kSize, PagedMemory::kDontCommit); ASSERT_TRUE(mem.IsValid()); char* ptr_raw = reinterpret_cast<char*>(mem.Get()); // Only the first 1024 pages are mapped. - constexpr size_t kMappedSize = 4096 * 1024; + const size_t kMappedSize = GetSysPageSize() * 1024; ptr_raw[kMappedSize] = 'x'; abort(); },
diff --git a/src/base/utils.cc b/src/base/utils.cc index 82386fa..ab3f390 100644 --- a/src/base/utils.cc +++ b/src/base/utils.cc
@@ -136,6 +136,34 @@ namespace perfetto { namespace base { +namespace internal { + +std::atomic<uint32_t> g_cached_page_size{0}; + +uint32_t GetSysPageSizeSlowpath() { + uint32_t page_size = 0; +#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \ + PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) + const int page_size_int = getpagesize(); + // If sysconf() fails for obscure reasons (e.g. SELinux denial) assume the + // page size is 4KB. This is to avoid regressing subtle SDK usages, as old + // versions of this code had a static constant baked in. + page_size = static_cast<uint32_t>(page_size_int > 0 ? page_size_int : 4096); +#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) + page_size = static_cast<uint32_t>(vm_page_size); +#else + page_size = 4096; +#endif + + PERFETTO_CHECK(page_size > 0 && page_size % 4096 == 0); + + // Races here are fine because any thread will write the same value. + g_cached_page_size.store(page_size, std::memory_order_relaxed); + return page_size; +} + +} // namespace internal + void MaybeReleaseAllocatorMemToOS() { #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) // mallopt() on Android requires SDK level 26. Many targets and embedders @@ -153,27 +181,6 @@ #endif } -uint32_t GetSysPageSize() { - ignore_result(kPageSize); // Just to keep the amalgamated build happy. -#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \ - PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) - static std::atomic<uint32_t> page_size{0}; - // This function might be called in hot paths. Avoid calling getpagesize() all - // the times, in many implementations getpagesize() calls sysconf() which is - // not cheap. - uint32_t cached_value = page_size.load(std::memory_order_relaxed); - if (PERFETTO_UNLIKELY(cached_value == 0)) { - cached_value = static_cast<uint32_t>(getpagesize()); - page_size.store(cached_value, std::memory_order_relaxed); - } - return cached_value; -#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) - return static_cast<uint32_t>(vm_page_size); -#else - return 4096; -#endif -} - uid_t GetCurrentUserId() { #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \