Skip to content

Commit 5b5dbc2

Browse files
q-gecopybara-github
authored andcommitted
Revert: Use recent demand to decide the number of pages to release from HugeRegion.
PiperOrigin-RevId: 827735509 Change-Id: I33df32552b13e5194f5eb0b08011574db5146cb7
1 parent 1bf8f22 commit 5b5dbc2

File tree

9 files changed

+8
-657
lines changed

9 files changed

+8
-657
lines changed

tcmalloc/BUILD

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,6 @@ cc_test(
975975
copts = TCMALLOC_DEFAULT_COPTS,
976976
deps = [
977977
":common_8k_pages",
978-
"//tcmalloc/internal:clock",
979978
"//tcmalloc/internal:logging",
980979
"//tcmalloc/internal:system_allocator",
981980
"//tcmalloc/testing:thread_manager",

tcmalloc/global_stats.cc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -565,8 +565,6 @@ void DumpStats(Printer& out, int level) {
565565
Parameters::filler_skip_subrelease_long_interval()));
566566
out.printf("PARAMETER tcmalloc_release_partial_alloc_pages %d\n",
567567
Parameters::release_partial_alloc_pages() ? 1 : 0);
568-
out.printf("PARAMETER tcmalloc_huge_region_demand_based_release %d\n",
569-
Parameters::huge_region_demand_based_release() ? 1 : 0);
570568
out.printf("PARAMETER tcmalloc_release_pages_from_huge_region %d\n",
571569
Parameters::release_pages_from_huge_region() ? 1 : 0);
572570
out.printf("PARAMETER tcmalloc_use_wider_slabs %d\n",
@@ -776,8 +774,6 @@ void DumpStatsInPbtxt(Printer& out, int level) {
776774
Parameters::filler_skip_subrelease_long_interval()));
777775
region.PrintBool("tcmalloc_release_partial_alloc_pages",
778776
Parameters::release_partial_alloc_pages());
779-
region.PrintBool("tcmalloc_huge_region_demand_based_release",
780-
Parameters::huge_region_demand_based_release());
781777
region.PrintBool("tcmalloc_release_pages_from_huge_region",
782778
Parameters::release_pages_from_huge_region());
783779
region.PrintI64("profile_sampling_interval",

tcmalloc/huge_page_aware_allocator.h

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,6 @@ class StaticForwarder {
7171
return Parameters::release_partial_alloc_pages();
7272
}
7373

74-
static bool huge_region_demand_based_release() {
75-
return Parameters::huge_region_demand_based_release();
76-
}
7774

7875
static bool hpaa_subrelease() { return Parameters::hpaa_subrelease(); }
7976

@@ -1003,19 +1000,7 @@ inline Length HugePageAwareAllocator<Forwarder>::ReleaseAtLeastNPages(
10031000
// the experiment is enabled. We can also explore releasing only a desired
10041001
// number of pages.
10051002
if (regions_.UseHugeRegionMoreOften()) {
1006-
if (forwarder_.huge_region_demand_based_release()) {
1007-
Length desired = released > num_pages ? Length(0) : num_pages - released;
1008-
released += regions_.ReleasePagesByPeakDemand(
1009-
desired,
1010-
SkipSubreleaseIntervals{
1011-
.short_interval =
1012-
forwarder_.filler_skip_subrelease_short_interval(),
1013-
.long_interval =
1014-
forwarder_.filler_skip_subrelease_long_interval()},
1015-
/*hit_limit*/ false);
1016-
} else {
1017-
released += regions_.ReleasePages(kFractionToReleaseFromRegion);
1018-
}
1003+
released += regions_.ReleasePages(kFractionToReleaseFromRegion);
10191004
}
10201005

10211006
// This is our long term plan but in current state will lead to insufficient
@@ -1216,13 +1201,7 @@ HugePageAwareAllocator<Forwarder>::ReleaseAtLeastNPagesBreakingHugepages(
12161201
released += cache_.ReleaseCachedPages(HLFromPages(n)).in_pages();
12171202

12181203
// We try to release as many free hugepages from HugeRegion as possible.
1219-
if (forwarder_.huge_region_demand_based_release()) {
1220-
released += regions_.ReleasePagesByPeakDemand(
1221-
n - released, SkipSubreleaseIntervals{}, /*hit_limit=*/true);
1222-
} else {
1223-
released += regions_.ReleasePages(/*release_fraction=*/1.0);
1224-
}
1225-
1204+
released += regions_.ReleasePages(/*release_fraction=*/1.0);
12261205
if (released >= n) {
12271206
info_.RecordRelease(n, released, reason);
12281207
return released;

tcmalloc/huge_region.h

Lines changed: 1 addition & 214 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,8 @@
2323
#include "absl/base/internal/cycleclock.h"
2424
#include "absl/base/nullability.h"
2525
#include "absl/base/optimization.h"
26-
#include "absl/time/time.h"
2726
#include "tcmalloc/huge_cache.h"
28-
#include "tcmalloc/huge_page_subrelease.h"
2927
#include "tcmalloc/huge_pages.h"
30-
#include "tcmalloc/internal/clock.h"
3128
#include "tcmalloc/internal/config.h"
3229
#include "tcmalloc/internal/linked_list.h"
3330
#include "tcmalloc/internal/logging.h"
@@ -152,17 +149,8 @@ class HugeRegion : public TList<HugeRegion>::Elem {
152149
template <typename Region>
153150
class HugeRegionSet {
154151
public:
155-
// For testing with mock clock.
156-
HugeRegionSet(HugeRegionUsageOption use_huge_region_more_often, Clock clock)
157-
: n_(0),
158-
use_huge_region_more_often_(use_huge_region_more_often),
159-
regionstats_tracker_(clock, absl::Minutes(10), absl::Minutes(5)) {}
160-
161152
explicit HugeRegionSet(HugeRegionUsageOption use_huge_region_more_often)
162-
: HugeRegionSet(
163-
use_huge_region_more_often,
164-
Clock{.now = absl::base_internal::CycleClock::Now,
165-
.freq = absl::base_internal::CycleClock::Frequency}) {}
153+
: n_(0), use_huge_region_more_often_(use_huge_region_more_often) {}
166154

167155
// If available, return a range of n free pages, setting *from_released =
168156
// true iff the returned range is currently unbacked.
@@ -176,19 +164,6 @@ class HugeRegionSet {
176164
// Add region to the set.
177165
void Contribute(Region* region);
178166

179-
// Tries to release up to <desired> number of pages from fully-free but backed
180-
// hugepages in HugeRegions. <intervals> defines the skip-subrelease
181-
// intervals, but unlike HugePageFiller skip-subrelease, it only releases free
182-
// hugepages.
183-
// Releases all free and backed hugepages to system when <hit_limit> is set to
184-
// true. Else, it uses intervals to determine recent demand as seen by
185-
// HugeRegions to compute realized fragmentation. It may only release as much
186-
// memory in free pages as determined by the realized fragmentation.
187-
// Returns the number of pages actually released.
188-
Length ReleasePagesByPeakDemand(Length desired,
189-
SkipSubreleaseIntervals intervals,
190-
bool hit_limit);
191-
192167
// Release hugepages that are unused but backed.
193168
// Releases up to <release_fraction> times number of free-but-backed hugepages
194169
// from each huge region. Note that this clamps release_fraction between 0 and
@@ -259,59 +234,10 @@ class HugeRegionSet {
259234
list_.append(r);
260235
}
261236

262-
using StatsTrackerType = SubreleaseStatsTracker<600>;
263-
StatsTrackerType::SubreleaseStats GetSubreleaseStats() const {
264-
StatsTrackerType::SubreleaseStats stats;
265-
for (Region* region : list_) {
266-
stats.num_pages += region->used_pages();
267-
stats.free_pages += region->free_pages();
268-
stats.unmapped_pages += region->unmapped_pages();
269-
stats.huge_pages[StatsTrackerType::kRegular] += region->size();
270-
}
271-
stats.num_pages_subreleased = subrelease_stats_.num_pages_subreleased;
272-
return stats;
273-
}
274-
275-
Length used_pages() const {
276-
Length used;
277-
for (Region* region : list_) {
278-
used += region->used_pages();
279-
}
280-
return used;
281-
}
282-
283-
Length free_pages() const {
284-
Length free;
285-
for (Region* region : list_) {
286-
free += region->free_pages();
287-
}
288-
return free;
289-
}
290-
291-
HugeLength size() const {
292-
HugeLength size;
293-
for (Region* region : list_) {
294-
size += region->size();
295-
}
296-
return size;
297-
}
298-
299237
size_t n_;
300238
HugeRegionUsageOption use_huge_region_more_often_;
301239
// Sorted by longest_free increasing.
302240
TList<Region> list_;
303-
304-
// Computes the recent demand to compute the number of pages that may be
305-
// released. <desired> determines an upper-bound on the number of pages to
306-
// release.
307-
// Returns number of pages that may be released based on recent demand.
308-
Length GetDesiredReleasablePages(Length desired,
309-
SkipSubreleaseIntervals intervals);
310-
311-
// Functionality related to tracking demand.
312-
void UpdateStatsTracker();
313-
StatsTrackerType regionstats_tracker_;
314-
SubreleaseStats subrelease_stats_;
315241
};
316242

317243
// REQUIRES: r.len() == size(); r unbacked.
@@ -558,78 +484,6 @@ inline HugeLength HugeRegion::UnbackHugepages(
558484
return released;
559485
}
560486

561-
template <typename Region>
562-
inline Length HugeRegionSet<Region>::GetDesiredReleasablePages(
563-
Length desired, SkipSubreleaseIntervals intervals) {
564-
if (!intervals.SkipSubreleaseEnabled()) {
565-
return desired;
566-
}
567-
UpdateStatsTracker();
568-
569-
Length required_pages;
570-
// There are two ways to calculate the demand requirement. We give priority to
571-
// using the peak if peak_interval is set.
572-
if (intervals.IsPeakIntervalSet()) {
573-
required_pages =
574-
regionstats_tracker_.GetRecentPeak(intervals.peak_interval);
575-
} else {
576-
required_pages = regionstats_tracker_.GetRecentDemand(
577-
intervals.short_interval, intervals.long_interval);
578-
}
579-
580-
Length current_pages = used_pages() + free_pages();
581-
582-
if (required_pages != Length(0)) {
583-
Length new_desired;
584-
if (required_pages < current_pages) {
585-
new_desired = current_pages - required_pages;
586-
}
587-
588-
// Because we currently release pages from fully backed and free hugepages,
589-
// make sure that the realized fragmentation in HugeRegion is at least equal
590-
// to kPagesPerHugePage. Otherwise, return zero to make sure we do not
591-
// release any pages.
592-
if (new_desired < kPagesPerHugePage) {
593-
new_desired = Length(0);
594-
}
595-
596-
if (new_desired >= desired) {
597-
return desired;
598-
}
599-
600-
// Compute the number of releasable pages from HugeRegion. We do not
601-
// subrelease pages yet. Instead, we only release hugepages that are fully
602-
// free but backed. Note: the remaining target should always be smaller or
603-
// equal to the number of free pages according to the mechanism (recent peak
604-
// is always larger or equal to current used_pages), however, we still
605-
// calculate allowed release using the minimum of the two to avoid relying
606-
// on that assumption.
607-
Length free_backed_pages = free_backed().in_pages();
608-
Length releasable_pages = std::min(free_backed_pages, new_desired);
609-
610-
// Reports the amount of memory that we didn't release due to this
611-
// mechanism, but never more than skipped free pages. In other words,
612-
// skipped_pages is zero if all free pages are allowed to be released by
613-
// this mechanism. Note, only free pages in the smaller of the two
614-
// (current_pages and required_pages) are skipped, the rest are allowed to
615-
// be subreleased.
616-
Length skipped_pages = std::min((free_backed_pages - releasable_pages),
617-
(desired - new_desired));
618-
619-
regionstats_tracker_.ReportSkippedSubreleasePages(
620-
skipped_pages, std::min(current_pages, required_pages));
621-
return new_desired;
622-
}
623-
624-
return desired;
625-
}
626-
627-
template <typename Region>
628-
inline void HugeRegionSet<Region>::UpdateStatsTracker() {
629-
regionstats_tracker_.Report(GetSubreleaseStats());
630-
subrelease_stats_.reset();
631-
}
632-
633487
// If available, return a range of n free pages, setting *from_released =
634488
// true iff the returned range is currently unbacked.
635489
// Returns false if no range available.
@@ -639,7 +493,6 @@ inline bool HugeRegionSet<Region>::MaybeGet(Length n, PageId* page,
639493
for (Region* region : list_) {
640494
if (region->MaybeGet(n, page, from_released)) {
641495
Fix(region);
642-
UpdateStatsTracker();
643496
return true;
644497
}
645498
}
@@ -657,7 +510,6 @@ inline bool HugeRegionSet<Region>::MaybePut(Range r) {
657510
if (region->contains(r.p)) {
658511
region->Put(r, release);
659512
Fix(region);
660-
UpdateStatsTracker();
661513
return true;
662514
}
663515
}
@@ -670,49 +522,6 @@ template <typename Region>
670522
inline void HugeRegionSet<Region>::Contribute(Region* region) {
671523
n_++;
672524
AddToList(region);
673-
UpdateStatsTracker();
674-
}
675-
676-
template <typename Region>
677-
inline Length HugeRegionSet<Region>::ReleasePagesByPeakDemand(
678-
Length desired, SkipSubreleaseIntervals intervals, bool hit_limit) {
679-
// Because we are releasing fully-freed hugepages, in cases when malloc
680-
// release rate is set to zero, we would still want to release some pages,
681-
// provided it is allowed by the demand-based release strategy. We try to
682-
// release up to 10% of the free and backed hugepages.
683-
if (!hit_limit && desired == Length(0)) {
684-
size_t new_desired =
685-
kFractionToReleaseFromRegion * free_backed().in_pages().raw_num();
686-
desired = Length(new_desired);
687-
}
688-
689-
// Only reduce desired if skip subrelease is on.
690-
//
691-
// Additionally, if we hit the limit, we should not be applying skip
692-
// subrelease. OOM may be imminent.
693-
if (intervals.SkipSubreleaseEnabled() && !hit_limit) {
694-
desired = GetDesiredReleasablePages(desired, intervals);
695-
}
696-
697-
subrelease_stats_.set_limit_hit(hit_limit);
698-
699-
Length released;
700-
if (desired != Length(0)) {
701-
for (Region* region : list_) {
702-
released += region->Release(desired - released).in_pages();
703-
if (released >= desired) break;
704-
}
705-
}
706-
707-
subrelease_stats_.num_pages_subreleased += released;
708-
709-
// Keep separate stats if the on going release is triggered by reaching
710-
// tcmalloc limit.
711-
if (subrelease_stats_.limit_hit()) {
712-
subrelease_stats_.total_pages_subreleased_due_to_limit += released;
713-
}
714-
715-
return released;
716525
}
717526

718527
template <typename Region>
@@ -758,17 +567,6 @@ inline void HugeRegionSet<Region>::Print(Printer& out) const {
758567
in_pages > Length(0) ? static_cast<double>(total_free.raw_num()) /
759568
static_cast<double>(in_pages.raw_num())
760569
: 0.0);
761-
762-
// Subrelease telemetry.
763-
out.printf(
764-
"HugeRegion: Since startup, %zu pages subreleased, %zu hugepages "
765-
"broken, (%zu pages, %zu hugepages due to reaching tcmalloc limit)\n",
766-
subrelease_stats_.total_pages_subreleased.raw_num(),
767-
subrelease_stats_.total_hugepages_broken.raw_num(),
768-
subrelease_stats_.total_pages_subreleased_due_to_limit.raw_num(),
769-
subrelease_stats_.total_hugepages_broken_due_to_limit.raw_num());
770-
771-
regionstats_tracker_.Print(out, "HugeRegion");
772570
}
773571

774572
template <typename Region>
@@ -779,17 +577,6 @@ inline void HugeRegionSet<Region>::PrintInPbtxt(PbtxtRegion& hpaa) const {
779577
auto detail = hpaa.CreateSubRegion("huge_region_details");
780578
region->PrintInPbtxt(detail);
781579
}
782-
783-
hpaa.PrintI64("region_num_pages_subreleased",
784-
subrelease_stats_.total_pages_subreleased.raw_num());
785-
hpaa.PrintI64(
786-
"region_num_pages_subreleased_due_to_limit",
787-
subrelease_stats_.total_pages_subreleased_due_to_limit.raw_num());
788-
789-
regionstats_tracker_.PrintSubreleaseStatsInPbtxt(hpaa,
790-
"region_skipped_subrelease");
791-
regionstats_tracker_.PrintTimeseriesStatsInPbtxt(hpaa,
792-
"region_stats_timeseries");
793580
}
794581

795582
template <typename Region>

0 commit comments

Comments
 (0)