From 463274594ae381d09bf81a07b3e9092feb9d14c3 Mon Sep 17 00:00:00 2001 From: ChiaHungDuan Date: Tue, 10 Sep 2024 17:46:02 -0700 Subject: [PATCH] [scudo] Fix the logic of MaxAllowedFragmentedPages (#107927) MTE doesn't support MaxReleasedCachePages which may break the assumption that only the first 4 pages will have memory tagged. GitOrigin-RevId: 6e854a6a01d310689a8b5d50126decd46b3880ea Change-Id: Ib0aaacd0eb66d155fdd075c03bc1a9e4642e16f7 --- standalone/secondary.h | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/standalone/secondary.h b/standalone/secondary.h index 1a232b9b9fb..c79ec1360b0 100644 --- a/standalone/secondary.h +++ b/standalone/secondary.h @@ -72,13 +72,16 @@ namespace { struct CachedBlock { static constexpr u16 CacheIndexMax = UINT16_MAX; static constexpr u16 InvalidEntry = CacheIndexMax; - // * MaxReleasedCachePages default is currently 4 - // - We arrived at this value after noticing that mapping - // in larger memory regions performs better than releasing - // memory and forcing a cache hit. According to the data, - // it suggests that beyond 4 pages, the release execution time is - // longer than the map execution time. In this way, the default - // is dependent on the platform. + // We allow a certain amount of fragmentation and part of the fragmented bytes + // will be released by `releaseAndZeroPagesToOS()`. This increases the chance + // of cache hit rate and reduces the overhead to the RSS at the same time. See + // more details in the `MapAllocatorCache::retrieve()` section. + // + // We arrived at this default value after noticing that mapping in larger + // memory regions performs better than releasing memory and forcing a cache + // hit. According to the data, it suggests that beyond 4 pages, the release + // execution time is longer than the map execution time. In this way, + // the default is dependent on the platform. static constexpr uptr MaxReleasedCachePages = 4U; uptr CommitBase = 0; @@ -725,8 +728,14 @@ MapAllocator::tryAllocateFromCache(const Options &Options, uptr Size, uptr EntryHeaderPos; uptr MaxAllowedFragmentedPages = MaxUnreleasedCachePages; - if (UNLIKELY(useMemoryTagging(Options))) + if (LIKELY(!useMemoryTagging(Options))) { MaxAllowedFragmentedPages += CachedBlock::MaxReleasedCachePages; + } else { + // TODO: Enable MaxReleasedCachePages may result in pages for an entry being + // partially released and it erases the tag of those pages as well. To + // support this feature for MTE, we need to tag those pages again. + DCHECK_EQ(CachedBlock::MaxReleasedCachePages, 0U); + } Entry = Cache.retrieve(MaxAllowedFragmentedPages, Size, Alignment, getHeadersSize(), EntryHeaderPos);