-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[scudo] Show the resident pages from the secondary cache. #170568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
cferris1000
wants to merge
1
commit into
llvm:main
Choose a base branch
from
cferris1000:resident_pages
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Move the test utility to get the resident pages into linux.cpp. Add some specific tests for this function. Add displaying of resident pages from in the secondary cache when calling getStats.
Member
|
@llvm/pr-subscribers-compiler-rt-sanitizer Author: Christopher Ferris (cferris1000) ChangesMove the test utility to get the resident pages into linux.cpp. Add some specific tests for this function. Add displaying of resident pages from in the secondary cache when calling getStats. Full diff: https://github.com/llvm/llvm-project/pull/170568.diff 6 Files Affected:
diff --git a/compiler-rt/lib/scudo/standalone/common.h b/compiler-rt/lib/scudo/standalone/common.h
index 8adcebd55698d..9097532f750d9 100644
--- a/compiler-rt/lib/scudo/standalone/common.h
+++ b/compiler-rt/lib/scudo/standalone/common.h
@@ -188,6 +188,11 @@ u32 getThreadID();
constexpr uptr MaxRandomLength = 256U;
bool getRandom(void *Buffer, uptr Length, bool Blocking = false);
+// Get the total number of resident pages for BaseAddress to BaseAddress + Size.
+// This function can run slowly, and is only expected to be called
+// from getStats functions where performance does not matter.
+u64 getResidentPages(uptr BaseAddress, uptr Size);
+
// Platform memory mapping functions.
#define MAP_ALLOWNOMEM (1U << 0)
diff --git a/compiler-rt/lib/scudo/standalone/fuchsia.cpp b/compiler-rt/lib/scudo/standalone/fuchsia.cpp
index 2144f1b63f894..f5a2e4d601361 100644
--- a/compiler-rt/lib/scudo/standalone/fuchsia.cpp
+++ b/compiler-rt/lib/scudo/standalone/fuchsia.cpp
@@ -231,6 +231,8 @@ void outputRaw(const char *Buffer) {
void setAbortMessage(const char *Message) {}
+u64 getResidentPages(uptr BaseAddress, uptr Size) { return 0; }
+
} // namespace scudo
#endif // SCUDO_FUCHSIA
diff --git a/compiler-rt/lib/scudo/standalone/linux.cpp b/compiler-rt/lib/scudo/standalone/linux.cpp
index 57171edac1e9e..3ef857f76b702 100644
--- a/compiler-rt/lib/scudo/standalone/linux.cpp
+++ b/compiler-rt/lib/scudo/standalone/linux.cpp
@@ -246,6 +246,34 @@ void setAbortMessage(const char *Message) {
android_set_abort_message(Message);
}
+u64 getResidentPages(uptr BaseAddress, uptr Size) {
+ unsigned char PageData[256];
+
+ uptr PageSize = getPageSizeCached();
+ uptr PageSizeLog = getPageSizeLogCached();
+
+ // Make sure the address is page aligned.
+ uptr CurrentAddress = BaseAddress & ~(PageSize - 1);
+ uptr LastAddress = roundUp(BaseAddress + Size, PageSize);
+ u64 ResidentPages = 0;
+ while (CurrentAddress < LastAddress) {
+ uptr Length = LastAddress - CurrentAddress;
+ if ((Length >> PageSizeLog) > sizeof(PageData)) {
+ Length = sizeof(PageData) << PageSizeLog;
+ }
+ if (mincore(reinterpret_cast<void *>(CurrentAddress), Length, PageData) ==
+ -1)
+ break;
+ for (size_t I = 0; I < Length >> PageSizeLog; I++) {
+ if (PageData[I])
+ ResidentPages++;
+ }
+ CurrentAddress += Length;
+ }
+
+ return ResidentPages;
+}
+
} // namespace scudo
#endif // SCUDO_LINUX
diff --git a/compiler-rt/lib/scudo/standalone/secondary.h b/compiler-rt/lib/scudo/standalone/secondary.h
index 2509db26e6c82..04e33c04baa34 100644
--- a/compiler-rt/lib/scudo/standalone/secondary.h
+++ b/compiler-rt/lib/scudo/standalone/secondary.h
@@ -9,6 +9,12 @@
#ifndef SCUDO_SECONDARY_H_
#define SCUDO_SECONDARY_H_
+#ifndef __STDC_FORMAT_MACROS
+// Ensure PRId64 macro is available
+#define __STDC_FORMAT_MACROS 1
+#endif
+#include <inttypes.h>
+
#include "chunk.h"
#include "common.h"
#include "list.h"
@@ -221,9 +227,17 @@ class MapAllocatorCache {
for (CachedBlock &Entry : LRUEntries) {
Str->append(" StartBlockAddress: 0x%zx, EndBlockAddress: 0x%zx, "
- "BlockSize: %zu %s\n",
+ "BlockSize: %zu%s",
Entry.CommitBase, Entry.CommitBase + Entry.CommitSize,
- Entry.CommitSize, Entry.Time == 0 ? "[R]" : "");
+ Entry.CommitSize, Entry.Time == 0 ? " [R]" : "");
+#if SCUDO_LINUX
+ // getResidentPages only works on linux systems currently.
+ Str->append(", Resident Pages: %" PRId64 "/%zu\n",
+ getResidentPages(Entry.CommitBase, Entry.CommitSize),
+ Entry.CommitSize / getPageSizeCached());
+#else
+ Str->append("\n");
+#endif
}
}
diff --git a/compiler-rt/lib/scudo/standalone/tests/common_test.cpp b/compiler-rt/lib/scudo/standalone/tests/common_test.cpp
index 71f810e9d9724..9a7687356fced 100644
--- a/compiler-rt/lib/scudo/standalone/tests/common_test.cpp
+++ b/compiler-rt/lib/scudo/standalone/tests/common_test.cpp
@@ -21,50 +21,74 @@
namespace scudo {
-static void getResidentPages(void *BaseAddress, size_t TotalPages,
- size_t *ResidentPages) {
- std::vector<unsigned char> Pages(TotalPages, 0);
- ASSERT_EQ(
- 0, mincore(BaseAddress, TotalPages * getPageSizeCached(), Pages.data()))
- << strerror(errno);
- *ResidentPages = 0;
- for (unsigned char Value : Pages) {
- if (Value & 1) {
- ++*ResidentPages;
- }
- }
+TEST(ScudoCommonTest, VerifyGetResidentPages) {
+ if (!SCUDO_LINUX)
+ GTEST_SKIP() << "Only valid on linux systems.";
+
+ constexpr uptr NumPages = 512;
+ const uptr SizeBytes = NumPages * getPageSizeCached();
+
+ MemMapT MemMap;
+ ASSERT_TRUE(MemMap.map(/*Addr=*/0U, SizeBytes, "ResidentMemorySize"));
+ ASSERT_NE(MemMap.getBase(), 0U);
+
+ // Only android seem to properly detect when single pages are touched.
+#if SCUDO_ANDROID
+ // Verify nothing should be mapped in right after the map is created.
+ EXPECT_EQ(0U, getResidentPages(MemMap.getBase(), SizeBytes));
+
+ // Touch a page.
+ u8 *Data = reinterpret_cast<u8 *>(MemMap.getBase());
+ Data[0] = 1;
+ EXPECT_EQ(1U, getResidentPages(MemMap.getBase(), SizeBytes));
+
+ // Touch a non-consective page.
+ Data[getPageSizeCached() * 2] = 1;
+ EXPECT_EQ(2U, getResidentPages(MemMap.getBase(), SizeBytes));
+
+ // Touch a page far enough that the function has to make multiple calls
+ // to mincore.
+ Data[getPageSizeCached() * 300] = 1;
+ EXPECT_EQ(3U, getResidentPages(MemMap.getBase(), SizeBytes));
+
+ // Touch another page in the same range to make sure the second
+ // read is working.
+ Data[getPageSizeCached() * 400] = 1;
+ EXPECT_EQ(4U, getResidentPages(MemMap.getBase(), SizeBytes));
+#endif
+
+ // Now write the whole thing.
+ memset(reinterpret_cast<void *>(MemMap.getBase()), 1, SizeBytes);
+ EXPECT_EQ(NumPages, getResidentPages(MemMap.getBase(), SizeBytes));
+
+ MemMap.unmap();
}
-// Fuchsia needs getResidentPages implementation.
-TEST(ScudoCommonTest, SKIP_ON_FUCHSIA(ResidentMemorySize)) {
- // Make sure to have the size of the map on a page boundary.
- const uptr PageSize = getPageSizeCached();
- const size_t NumPages = 1000;
- const uptr SizeBytes = NumPages * PageSize;
+TEST(ScudoCommonTest, VerifyReleasePagesToOS) {
+ if (!SCUDO_LINUX)
+ GTEST_SKIP() << "Only valid on linux systems.";
+
+ constexpr uptr NumPages = 1000;
+ const uptr SizeBytes = NumPages * getPageSizeCached();
MemMapT MemMap;
ASSERT_TRUE(MemMap.map(/*Addr=*/0U, SizeBytes, "ResidentMemorySize"));
ASSERT_NE(MemMap.getBase(), 0U);
void *P = reinterpret_cast<void *>(MemMap.getBase());
- size_t ResidentPages;
- getResidentPages(P, NumPages, &ResidentPages);
- EXPECT_EQ(0U, ResidentPages);
+ EXPECT_EQ(0U, getResidentPages(MemMap.getBase(), SizeBytes));
// Make the entire map resident.
memset(P, 1, SizeBytes);
- getResidentPages(P, NumPages, &ResidentPages);
- EXPECT_EQ(NumPages, ResidentPages);
+ EXPECT_EQ(NumPages, getResidentPages(MemMap.getBase(), SizeBytes));
// Should release the memory to the kernel immediately.
MemMap.releasePagesToOS(MemMap.getBase(), SizeBytes);
- getResidentPages(P, NumPages, &ResidentPages);
- EXPECT_EQ(0U, ResidentPages);
+ EXPECT_EQ(0U, getResidentPages(MemMap.getBase(), SizeBytes));
// Make the entire map resident again.
memset(P, 1, SizeBytes);
- getResidentPages(P, NumPages, &ResidentPages);
- EXPECT_EQ(NumPages, ResidentPages);
+ EXPECT_EQ(NumPages, getResidentPages(MemMap.getBase(), SizeBytes));
MemMap.unmap();
}
diff --git a/compiler-rt/lib/scudo/standalone/trusty.cpp b/compiler-rt/lib/scudo/standalone/trusty.cpp
index 26b349c6e506e..d4b5b6bf1c3bc 100644
--- a/compiler-rt/lib/scudo/standalone/trusty.cpp
+++ b/compiler-rt/lib/scudo/standalone/trusty.cpp
@@ -113,6 +113,8 @@ void outputRaw(const char *Buffer) { printf("%s", Buffer); }
void setAbortMessage(UNUSED const char *Message) {}
+u64 getResidentPages(UNUSED uptr BaseAddress, UNUSED uptr Size) { return 0; }
+
} // namespace scudo
#endif // SCUDO_TRUSTY
|
Collaborator
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Move the test utility to get the resident pages into linux.cpp.
Add some specific tests for this function.
Add displaying of resident pages from in the secondary cache when calling getStats.