From 2499539bb43ed4685c7c531277e27ec1399c5fce Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 19 Apr 2022 19:53:38 +0100 Subject: [PATCH] expanding the page range id feature to e able to distinguish better page states. --- src/snmalloc/pal/pal_consts.h | 8 +++++ src/snmalloc/pal/pal_linux.h | 64 ++++++++++++++++++++++------------ src/snmalloc/pal/pal_posix.h | 18 +++++++++- src/snmalloc/pal/pal_windows.h | 1 + 4 files changed, 68 insertions(+), 23 deletions(-) diff --git a/src/snmalloc/pal/pal_consts.h b/src/snmalloc/pal/pal_consts.h index 8de4cb09c..601ee64f2 100644 --- a/src/snmalloc/pal/pal_consts.h +++ b/src/snmalloc/pal/pal_consts.h @@ -94,6 +94,14 @@ namespace snmalloc YesZero }; + enum StateMem + { + Unused, + Allocated, + Pagemap, + Metadata + }; + /** * Default Tag ID for the Apple class */ diff --git a/src/snmalloc/pal/pal_linux.h b/src/snmalloc/pal/pal_linux.h index 3a06bf8e8..50bce40fa 100644 --- a/src/snmalloc/pal/pal_linux.h +++ b/src/snmalloc/pal/pal_linux.h @@ -35,35 +35,54 @@ namespace snmalloc */ static constexpr int default_mmap_flags = MAP_NORESERVE; - static void* reserve(size_t size) noexcept + /** + * Not generalizing this handler purposely as in other platforms + * mechanisms could differ greatly. + */ + template + static void pageid(void* p, size_t size) noexcept { - void* p = PALPOSIX::reserve(size); - if (p) - { - madvise(p, size, MADV_DONTDUMP); # ifdef SNMALLOC_PAGEID # ifndef PR_SET_VMA # define PR_SET_VMA 0x53564d41 # define PR_SET_VMA_ANON_NAME 0 # endif - /** - * - * If the kernel is set with CONFIG_ANON_VMA_NAME - * the reserved pages would appear as follow - * - * 7fa5f0ceb000-7fa5f0e00000 rw-p 00000000 00:00 0 [anon:snmalloc] - * 7fa5f0e00000-7fa5f1800000 rw-p 00000000 00:00 0 [anon:snmalloc] - * - */ - - prctl( - PR_SET_VMA, - PR_SET_VMA_ANON_NAME, - (unsigned long)p, - size, - (unsigned long)"snmalloc"); + /** + * + * If the kernel is set with CONFIG_ANON_VMA_NAME + * the reserved pages would appear as follow + * + * 7fa5f0ceb000-7fa5f0e00000 rw-p 00000000 00:00 0 [anon:snmalloc + * ()] 7fa5f0e00000-7fa5f1800000 rw-p 00000000 00:00 0 + * [anon:snmalloc ()] + * + * The 80 buffer limit is specific to this syscall. + */ + + char buf[80] = {0}; + PALPOSIX::pagetype(buf, sizeof(buf)); + + prctl( + PR_SET_VMA, + PR_SET_VMA_ANON_NAME, + (unsigned long)p, + size, + (unsigned long)buf); +# else + UNUSED(p); + UNUSED(size); # endif + } + + template + static void* reserve(size_t size) noexcept + { + void* p = PALPOSIX::reserve(size); + if (p) + { + madvise(p, size, MADV_DONTDUMP); + pageid(p, size); } return p; } @@ -131,11 +150,12 @@ namespace snmalloc /** * Notify platform that we will be using these pages. */ - template + template static void notify_using(void* p, size_t size) noexcept { PALPOSIX::notify_using(p, size); madvise(p, size, MADV_DODUMP); + pageid(p, size); } static uint64_t get_entropy64() diff --git a/src/snmalloc/pal/pal_posix.h b/src/snmalloc/pal/pal_posix.h index f71755d20..02d64ed1a 100644 --- a/src/snmalloc/pal/pal_posix.h +++ b/src/snmalloc/pal/pal_posix.h @@ -221,7 +221,7 @@ namespace snmalloc * are also zeroing the pages in which case we call the platform's `zero` * function, or we have initially mapped the pages as PROT_NONE. */ - template + template static void notify_using(void* p, size_t size) noexcept { SNMALLOC_ASSERT( @@ -316,6 +316,7 @@ namespace snmalloc * POSIX does not define a portable interface for specifying alignment * greater than a page. */ + template static void* reserve(size_t size) noexcept { // If enforcing access, map pages initially as None, and then @@ -428,5 +429,20 @@ namespace snmalloc error("Failed to get system randomness"); } + + template + static void pagetype(char* buf, size_t len) + { + ssize_t sz; + if constexpr (state_mem == Unused) + sz = snprintf(buf, len, "snmalloc (Unused)"); + else if constexpr (state_mem == Allocated) + sz = snprintf(buf, len, "snmalloc (Allocated)"); + else if constexpr (state_mem == Pagemap) + sz = snprintf(buf, len, "snmalloc (Pagemap)"); + else if constexpr (state_mem == Metadata) + sz = snprintf(buf, len, "snmalloc (Metadata)"); + buf[sz] = 0; + } }; } // namespace snmalloc diff --git a/src/snmalloc/pal/pal_windows.h b/src/snmalloc/pal/pal_windows.h index 2d6f82283..a6f355dff 100644 --- a/src/snmalloc/pal/pal_windows.h +++ b/src/snmalloc/pal/pal_windows.h @@ -198,6 +198,7 @@ namespace snmalloc } # endif + template static void* reserve(size_t size) noexcept { void* ret = VirtualAlloc(nullptr, size, MEM_RESERVE, PAGE_READWRITE);