File: swap_configuration.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (123 lines) | stat: -rw-r--r-- 4,892 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/ash/components/memory/swap_configuration.h"

#include "base/component_export.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/metrics/field_trial_params.h"
#include "base/system/sys_info.h"
#include "chromeos/ash/components/dbus/resourced/resourced_client.h"

namespace ash {

// There are going to be 2 separate experiments for memory pressure signal, one
// for ARC enabled users and one for ARC disabled users.
BASE_FEATURE(kCrOSMemoryPressureSignalStudyNonArc,
             "ChromeOSMemoryPressureSignalStudyNonArc",
             base::FEATURE_ENABLED_BY_DEFAULT);

const base::FeatureParam<int> kCrOSMemoryPressureSignalStudyNonArcModerateBps{
    &kCrOSMemoryPressureSignalStudyNonArc, "moderate_threshold_percentage",
    4000};

const base::FeatureParam<int> kCrOSMemoryPressureSignalStudyNonArcCriticalBps{
    &kCrOSMemoryPressureSignalStudyNonArc, "critical_threshold_percentage",
    1500};

const base::FeatureParam<int>
    kCrOSMemoryPressureSignalStudyNonArcCriticalProtectedBps{
        &kCrOSMemoryPressureSignalStudyNonArc,
        "critical_protected_threshold_percentage", 750};

BASE_FEATURE(kCrOSMemoryPressureSignalStudyArc,
             "ChromeOSMemoryPressureSignalStudyArc",
             base::FEATURE_ENABLED_BY_DEFAULT);

const base::FeatureParam<int> kCrOSMemoryPressureSignalStudyArcModerateBps{
    &kCrOSMemoryPressureSignalStudyArc, "moderate_threshold_percentage", 4000};

const base::FeatureParam<int> kCrOSMemoryPressureSignalStudyArcCriticalBps{
    &kCrOSMemoryPressureSignalStudyArc, "critical_threshold_percentage", 800};

const base::FeatureParam<int>
    kCrOSMemoryPressureSignalStudyArcCriticalProtectedBps{
        &kCrOSMemoryPressureSignalStudyArc,
        "critical_protected_threshold_percentage", 800};

namespace {

void ConfigureResourcedPressureThreshold(bool arc_enabled) {
  if (!ResourcedClient::Get()) {
    return;
  }

  bool experiment_enabled = false;
  uint32_t moderate_bps = 0;
  uint32_t critical_bps = 0;
  uint32_t critical_protected_bps = 0;
  // Limit the critical protected threshold to 600 MiB to avoid setting large
  // critical protected threshold on large RAM device. Setting Large threshold
  // could easily discard protected pages.
  const int kProtectedThresholdLimitMb = 600;
  const int kRatioToBps = 10000;
  // limit_bps = (limit_mb / total_mb) * ratio_to_bps, rearrange the
  // multiplication to avoid floating point arithmetic.
  int protected_threshold_limit_bps =
      static_cast<uint32_t>(kProtectedThresholdLimitMb * kRatioToBps /
                            base::SysInfo::AmountOfPhysicalMemoryMB());
  if (arc_enabled) {
    experiment_enabled =
        base::FeatureList::IsEnabled(kCrOSMemoryPressureSignalStudyArc);
    if (experiment_enabled) {
      moderate_bps = kCrOSMemoryPressureSignalStudyArcModerateBps.Get();
      critical_bps = kCrOSMemoryPressureSignalStudyArcCriticalBps.Get();
      critical_protected_bps =
          std::min(protected_threshold_limit_bps,
                   kCrOSMemoryPressureSignalStudyArcCriticalProtectedBps.Get());
    }
  } else {
    experiment_enabled =
        base::FeatureList::IsEnabled(kCrOSMemoryPressureSignalStudyNonArc);
    if (experiment_enabled) {
      moderate_bps = kCrOSMemoryPressureSignalStudyNonArcModerateBps.Get();
      critical_bps = kCrOSMemoryPressureSignalStudyNonArcCriticalBps.Get();
      critical_protected_bps = std::min(
          protected_threshold_limit_bps,
          kCrOSMemoryPressureSignalStudyNonArcCriticalProtectedBps.Get());
    }
  }

  if (experiment_enabled) {
    // We need to send a debus message to resourced with the critical threshold
    // value (in bps).
    if (critical_bps < 520 || critical_bps > 2500 || moderate_bps > 7500 ||
        moderate_bps < 2000 || critical_bps >= moderate_bps) {
      // To avoid a potentially catastrophic misconfiguration we
      // only allow critical values between 5.2% and 25%, moderate between 20%
      // and 75%, and moderate must be greater than critical.
      LOG(ERROR) << "Invalid values specified for memory thresholds: "
                 << critical_bps << " and " << moderate_bps;
      return;
    }

    LOG(WARNING) << "Overriding memory thresholds with values "
                 << (critical_bps / 100.0) << "% and " << (moderate_bps / 100.0)
                 << "%";
    ResourcedClient::MemoryMargins margins = {
        .moderate_bps = moderate_bps,
        .critical_bps = critical_bps,
        .critical_protected_bps = critical_protected_bps};
    ResourcedClient::Get()->SetMemoryMargins(margins);
  }
}

}  // namespace

void ConfigureSwap(bool arc_enabled) {
  ConfigureResourcedPressureThreshold(arc_enabled);
}

}  // namespace ash