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
|