Commit 335fab93 authored by Kuo-Hsin Yang's avatar Kuo-Hsin Yang Committed by Commit Bot

Move GetAvailableMemoryKB logic out of CrOS SystemMemoryPressureEvaluator

GetAvailableMemoryKB will be used by the memory pressure D-Bus service
provider, and SystemMemoryPressureEvaluator will call the memory
pressure D-Bus API. Move GetAvailableMemoryKB to avoid the circular
dependency between SystemMemoryPressureEvaluator and the memory pressure
D-Bus service provider.

BUG=b:149833548
TEST=run chromeos_unittests

Change-Id: Ieab7763fe9b9291e2503463dbdce19cc92838c9a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2381241
Commit-Queue: Kuo-Hsin Yang <vovoy@chromium.org>
Reviewed-by: default avatarBrian Geffon <bgeffon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#802690}
parent be8533f2
...@@ -35,6 +35,8 @@ component("memory") { ...@@ -35,6 +35,8 @@ component("memory") {
"memory.h", "memory.h",
"pagemap.cc", "pagemap.cc",
"pagemap.h", "pagemap.h",
"pressure/pressure.cc",
"pressure/pressure.h",
"pressure/system_memory_pressure_evaluator.cc", "pressure/system_memory_pressure_evaluator.cc",
"pressure/system_memory_pressure_evaluator.h", "pressure/system_memory_pressure_evaluator.h",
"swap_configuration.cc", "swap_configuration.cc",
...@@ -57,6 +59,7 @@ source_set("unit_tests") { ...@@ -57,6 +59,7 @@ source_set("unit_tests") {
] ]
sources = [ sources = [
"pagemap_unittest.cc", "pagemap_unittest.cc",
"pressure/pressure_unittest.cc",
"pressure/system_memory_pressure_evaluator_unittest.cc", "pressure/system_memory_pressure_evaluator_unittest.cc",
] ]
} }
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/metrics/field_trial_params.h" #include "base/metrics/field_trial_params.h"
#include "chromeos/memory/pressure/system_memory_pressure_evaluator.h" #include "chromeos/memory/pressure/pressure.h"
#include "chromeos/memory/swap_configuration.h" #include "chromeos/memory/swap_configuration.h"
namespace chromeos { namespace chromeos {
...@@ -86,9 +86,7 @@ CHROMEOS_EXPORT void LockMainProgramText() { ...@@ -86,9 +86,7 @@ CHROMEOS_EXPORT void LockMainProgramText() {
} }
CHROMEOS_EXPORT void UpdateMemoryParameters() { CHROMEOS_EXPORT void UpdateMemoryParameters() {
auto* monitor = memory::SystemMemoryPressureEvaluator::Get(); chromeos::memory::pressure::UpdateMemoryParameters();
if (monitor)
monitor->UpdateMemoryParameters();
ConfigureSwap(); ConfigureSwap();
} }
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/memory/pressure/pressure.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/system/sys_info.h"
namespace chromeos {
namespace memory {
namespace pressure {
namespace {
// The reserved file cache.
constexpr char kMinFilelist[] = "/proc/sys/vm/min_filelist_kbytes";
// The estimation of how well zram based swap is compressed.
constexpr char kRamVsSwapWeight[] =
"/sys/kernel/mm/chromeos-low_mem/ram_vs_swap_weight";
// The extra free to trigger kernel memory reclaim earlier.
constexpr char kExtraFree[] = "/proc/sys/vm/extra_free_kbytes";
// Values saved for user space available memory calculation. The value of
// |reserved_free| should not change unless min_free_kbytes or
// lowmem_reserve_ratio change. The value of |min_filelist| and
// |ram_swap_weight| should not change unless the user sets them manually.
uint64_t reserved_free = 0;
uint64_t min_filelist = 0;
uint64_t ram_swap_weight = 0;
uint64_t ReadFileToUint64(const base::FilePath& file) {
std::string file_contents;
if (!base::ReadFileToStringNonBlocking(file, &file_contents)) {
PLOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
<< "Unable to read uint64 from: " << file;
return 0;
}
TrimWhitespaceASCII(file_contents, base::TRIM_ALL, &file_contents);
uint64_t file_contents_uint64 = 0;
if (!base::StringToUint64(file_contents, &file_contents_uint64))
return 0;
return file_contents_uint64;
}
} // namespace
// CalculateReservedFreeKB() calculates the reserved free memory in KiB from
// /proc/zoneinfo. Reserved pages are free pages reserved for emergent kernel
// allocation and are not available to the user space. It's the sum of high
// watermarks and max protection pages of memory zones. It implements the same
// reserved pages calculation in linux kernel calculate_totalreserve_pages().
//
// /proc/zoneinfo example:
// ...
// Node 0, zone DMA32
// pages free 422432
// min 16270
// low 20337
// high 24404
// ...
// protection: (0, 0, 1953, 1953)
//
// The high field is the high watermark for this zone. The protection field is
// the protected pages for lower zones. See the lowmem_reserve_ratio section in
// https://www.kernel.org/doc/Documentation/sysctl/vm.txt.
uint64_t CalculateReservedFreeKB(const std::string& zoneinfo) {
constexpr uint64_t kPageSizeKB = 4;
uint64_t num_reserved_pages = 0;
for (const base::StringPiece& line : base::SplitStringPiece(
zoneinfo, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
std::vector<base::StringPiece> tokens = base::SplitStringPiece(
line, base::kWhitespaceASCII, base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
// Skip the line if there are not enough tokens.
if (tokens.size() < 2) {
continue;
}
if (tokens[0] == "high") {
// Parse the high watermark.
uint64_t high = 0;
if (base::StringToUint64(tokens[1], &high)) {
num_reserved_pages += high;
} else {
LOG(ERROR) << "Couldn't parse the high field in /proc/zoneinfo: "
<< tokens[1];
}
} else if (tokens[0] == "protection:") {
// Parse the protection pages.
uint64_t max = 0;
for (size_t i = 1; i < tokens.size(); ++i) {
uint64_t num = 0;
base::StringPiece entry;
if (i == 1) {
// Exclude the leading '(' and the trailing ','.
entry = tokens[i].substr(1, tokens[i].size() - 2);
} else {
// Exclude the trailing ',' or ')'.
entry = tokens[i].substr(0, tokens[i].size() - 1);
}
if (base::StringToUint64(entry, &num)) {
max = std::max(max, num);
} else {
LOG(ERROR)
<< "Couldn't parse the protection field in /proc/zoneinfo: "
<< entry;
}
}
num_reserved_pages += max;
}
}
return num_reserved_pages * kPageSizeKB;
}
static uint64_t GetReservedMemoryKB() {
std::string file_contents;
if (!base::ReadFileToStringNonBlocking(base::FilePath("/proc/zoneinfo"),
&file_contents)) {
PLOG(ERROR) << "Couldn't get /proc/zoneinfo";
return 0;
}
// Reserve free pages is high watermark + lowmem_reserve and extra_free_kbytes
// raises the high watermark. Nullify the effect of extra_free_kbytes by
// excluding it from the reserved pages. The default extra_free_kbytes value
// is 0 if the file couldn't be accessed.
return CalculateReservedFreeKB(file_contents) -
ReadFileToUint64(base::FilePath(kExtraFree));
}
// CalculateAvailableMemoryUserSpaceKB implements the same available memory
// calculation as kernel function get_available_mem_adj(). The available memory
// consists of 3 parts: the free memory, the file cache, and the swappable
// memory. The available free memory is free memory minus reserved free memory.
// The available file cache is the total file cache minus reserved file cache
// (min_filelist). Because swapping is prohibited if there is no anonymous
// memory or no swap free, the swappable memory is the minimal of anonymous
// memory and swap free. As swapping memory is more costly than dropping file
// cache, only a fraction (1 / ram_swap_weight) of the swappable memory
// contributes to the available memory.
uint64_t CalculateAvailableMemoryUserSpaceKB(
const base::SystemMemoryInfoKB& info,
uint64_t reserved_free,
uint64_t min_filelist,
uint64_t ram_swap_weight) {
const uint64_t free = info.free;
const uint64_t anon = info.active_anon + info.inactive_anon;
const uint64_t file = info.active_file + info.inactive_file;
const uint64_t dirty = info.dirty;
const uint64_t swap_free = info.swap_free;
uint64_t available = (free > reserved_free) ? free - reserved_free : 0;
available += (file > dirty + min_filelist) ? file - dirty - min_filelist : 0;
available += std::min<uint64_t>(anon, swap_free) / ram_swap_weight;
return available;
}
uint64_t GetAvailableMemoryKB() {
base::SystemMemoryInfoKB info;
CHECK(base::GetSystemMemoryInfo(&info));
return CalculateAvailableMemoryUserSpaceKB(info, reserved_free, min_filelist,
ram_swap_weight);
}
void UpdateMemoryParameters() {
reserved_free = GetReservedMemoryKB();
min_filelist = ReadFileToUint64(base::FilePath(kMinFilelist));
ram_swap_weight = ReadFileToUint64(base::FilePath(kRamVsSwapWeight));
}
} // namespace pressure
} // namespace memory
} // namespace chromeos
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_MEMORY_PRESSURE_PRESSURE_H_
#define CHROMEOS_MEMORY_PRESSURE_PRESSURE_H_
#include <cstdint>
#include <string>
#include "base/process/process_metrics.h"
#include "chromeos/chromeos_export.h"
namespace chromeos {
namespace memory {
namespace pressure {
// Export for unittest.
CHROMEOS_EXPORT uint64_t CalculateReservedFreeKB(const std::string& zoneinfo);
// Export for unittest.
CHROMEOS_EXPORT uint64_t
CalculateAvailableMemoryUserSpaceKB(const base::SystemMemoryInfoKB& info,
uint64_t reserved_free,
uint64_t min_filelist,
uint64_t ram_swap_weight);
// GetAvailableMemoryKB returns the available memory in KiB.
uint64_t GetAvailableMemoryKB();
// The memory parameters are saved for optimization. If these memory
// parameters are changed, call this function to update the saved values.
void UpdateMemoryParameters();
} // namespace pressure
} // namespace memory
} // namespace chromeos
#endif // CHROMEOS_MEMORY_PRESSURE_PRESSURE_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/memory/pressure/pressure.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(MemoryPressureTest, CalculateReservedFreeKB) {
const std::string kMockPartialZoneinfo(R"(
Node 0, zone DMA
pages free 3968
min 137
low 171
high 205
spanned 4095
present 3999
managed 3976
protection: (0, 1832, 3000, 3786)
Node 0, zone DMA32
pages free 422432
min 16270
low 20337
high 24404
spanned 1044480
present 485541
managed 469149
protection: (0, 0, 1953, 1500)
Node 0, zone Normal
pages free 21708
min 17383
low 21728
high 26073
spanned 524288
present 524288
managed 501235
protection: (0, 0, 0, 0))");
constexpr uint64_t kPageSizeKB = 4;
const uint64_t high_watermarks = 205 + 24404 + 26073;
const uint64_t lowmem_reserves = 3786 + 1953 + 0;
const uint64_t reserved =
chromeos::memory::pressure::CalculateReservedFreeKB(kMockPartialZoneinfo);
ASSERT_EQ(reserved, (high_watermarks + lowmem_reserves) * kPageSizeKB);
}
TEST(MemoryPressureTest, CalculateAvailableMemoryUserSpaceKB) {
base::SystemMemoryInfoKB info;
uint64_t available;
const uint64_t min_filelist = 400 * 1024;
const uint64_t reserved_free = 0;
const uint64_t ram_swap_weight = 4;
// Available determined by file cache.
info.inactive_file = 500 * 1024;
info.active_file = 500 * 1024;
available = chromeos::memory::pressure::CalculateAvailableMemoryUserSpaceKB(
info, reserved_free, min_filelist, ram_swap_weight);
ASSERT_EQ(available, 1000 * 1024 - min_filelist);
// Available determined by swap free.
info.swap_free = 1200 * 1024;
info.inactive_anon = 1000 * 1024;
info.active_anon = 1000 * 1024;
info.inactive_file = 0;
info.active_file = 0;
available = chromeos::memory::pressure::CalculateAvailableMemoryUserSpaceKB(
info, reserved_free, min_filelist, ram_swap_weight);
ASSERT_EQ(available, uint64_t(300 * 1024));
// Available determined by anonymous.
info.swap_free = 6000 * 1024;
info.inactive_anon = 500 * 1024;
info.active_anon = 500 * 1024;
available = chromeos::memory::pressure::CalculateAvailableMemoryUserSpaceKB(
info, reserved_free, min_filelist, ram_swap_weight);
ASSERT_EQ(available, uint64_t(250 * 1024));
}
// Copyright 2019 The Chromium Authors. All rights reserved. // Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chromeos/memory/pressure/system_memory_pressure_evaluator.h" #include "chromeos/memory/pressure/system_memory_pressure_evaluator.h"
#include <fcntl.h> #include <fcntl.h>
...@@ -24,6 +25,7 @@ ...@@ -24,6 +25,7 @@
#include "base/threading/scoped_blocking_call.h" #include "base/threading/scoped_blocking_call.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chromeos/memory/pressure/pressure.h"
namespace chromeos { namespace chromeos {
namespace memory { namespace memory {
...@@ -52,16 +54,6 @@ constexpr char kMarginMemFile[] = "/sys/kernel/mm/chromeos-low_mem/margin"; ...@@ -52,16 +54,6 @@ constexpr char kMarginMemFile[] = "/sys/kernel/mm/chromeos-low_mem/margin";
constexpr char kAvailableMemFile[] = constexpr char kAvailableMemFile[] =
"/sys/kernel/mm/chromeos-low_mem/available"; "/sys/kernel/mm/chromeos-low_mem/available";
// The reserved file cache.
constexpr char kMinFilelist[] = "/proc/sys/vm/min_filelist_kbytes";
// The estimation of how well zram based swap is compressed.
constexpr char kRamVsSwapWeight[] =
"/sys/kernel/mm/chromeos-low_mem/ram_vs_swap_weight";
// The extra free to trigger kernel memory reclaim earlier.
constexpr char kExtraFree[] = "/proc/sys/vm/extra_free_kbytes";
// Converts an available memory value in MB to a memory pressure level. // Converts an available memory value in MB to a memory pressure level.
base::MemoryPressureListener::MemoryPressureLevel base::MemoryPressureListener::MemoryPressureLevel
GetMemoryPressureLevelFromAvailable(int available_mb, GetMemoryPressureLevelFromAvailable(int available_mb,
...@@ -75,20 +67,6 @@ GetMemoryPressureLevelFromAvailable(int available_mb, ...@@ -75,20 +67,6 @@ GetMemoryPressureLevelFromAvailable(int available_mb,
return base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE; return base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
} }
uint64_t ReadFileToUint64(const base::FilePath& file) {
std::string file_contents;
if (!base::ReadFileToStringNonBlocking(file, &file_contents)) {
PLOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
<< "Unable to read uint64 from: " << file;
return 0;
}
TrimWhitespaceASCII(file_contents, base::TRIM_ALL, &file_contents);
uint64_t file_contents_uint64 = 0;
if (!base::StringToUint64(file_contents, &file_contents_uint64))
return 0;
return file_contents_uint64;
}
uint64_t ReadAvailableMemoryMB(int available_fd) { uint64_t ReadAvailableMemoryMB(int available_fd) {
// Read the available memory. // Read the available memory.
char buf[32] = {}; char buf[32] = {};
...@@ -173,7 +151,9 @@ SystemMemoryPressureEvaluator::SystemMemoryPressureEvaluator( ...@@ -173,7 +151,9 @@ SystemMemoryPressureEvaluator::SystemMemoryPressureEvaluator(
critical_pressure_threshold_mb_ = margin_parts[0]; critical_pressure_threshold_mb_ = margin_parts[0];
moderate_pressure_threshold_mb_ = margin_parts[1]; moderate_pressure_threshold_mb_ = margin_parts[1];
UpdateMemoryParameters(); if (is_user_space_notify_) {
chromeos::memory::pressure::UpdateMemoryParameters();
}
if (!is_user_space_notify_) { if (!is_user_space_notify_) {
kernel_waiting_callback_ = base::BindRepeating( kernel_waiting_callback_ = base::BindRepeating(
...@@ -237,128 +217,9 @@ std::vector<int> SystemMemoryPressureEvaluator::GetMarginFileParts( ...@@ -237,128 +217,9 @@ std::vector<int> SystemMemoryPressureEvaluator::GetMarginFileParts(
return margin_values; return margin_values;
} }
// CalculateReservedFreeKB() calculates the reserved free memory in KiB from
// /proc/zoneinfo. Reserved pages are free pages reserved for emergent kernel
// allocation and are not available to the user space. It's the sum of high
// watermarks and max protection pages of memory zones. It implements the same
// reserved pages calculation in linux kernel calculate_totalreserve_pages().
//
// /proc/zoneinfo example:
// ...
// Node 0, zone DMA32
// pages free 422432
// min 16270
// low 20337
// high 24404
// ...
// protection: (0, 0, 1953, 1953)
//
// The high field is the high watermark for this zone. The protection field is
// the protected pages for lower zones. See the lowmem_reserve_ratio section in
// https://www.kernel.org/doc/Documentation/sysctl/vm.txt.
uint64_t SystemMemoryPressureEvaluator::CalculateReservedFreeKB(
const std::string& zoneinfo) {
constexpr uint64_t kPageSizeKB = 4;
uint64_t num_reserved_pages = 0;
for (const base::StringPiece& line : base::SplitStringPiece(
zoneinfo, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
std::vector<base::StringPiece> tokens = base::SplitStringPiece(
line, base::kWhitespaceASCII, base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
// Skip the line if there are not enough tokens.
if (tokens.size() < 2) {
continue;
}
if (tokens[0] == "high") {
// Parse the high watermark.
uint64_t high = 0;
if (base::StringToUint64(tokens[1], &high)) {
num_reserved_pages += high;
} else {
LOG(ERROR) << "Couldn't parse the high field in /proc/zoneinfo: "
<< tokens[1];
}
} else if (tokens[0] == "protection:") {
// Parse the protection pages.
uint64_t max = 0;
for (size_t i = 1; i < tokens.size(); ++i) {
uint64_t num = 0;
base::StringPiece entry;
if (i == 1) {
// Exclude the leading '(' and the trailing ','.
entry = tokens[i].substr(1, tokens[i].size() - 2);
} else {
// Exclude the trailing ',' or ')'.
entry = tokens[i].substr(0, tokens[i].size() - 1);
}
if (base::StringToUint64(entry, &num)) {
max = std::max(max, num);
} else {
LOG(ERROR)
<< "Couldn't parse the protection field in /proc/zoneinfo: "
<< entry;
}
}
num_reserved_pages += max;
}
}
return num_reserved_pages * kPageSizeKB;
}
uint64_t SystemMemoryPressureEvaluator::GetReservedMemoryKB() {
std::string file_contents;
if (!base::ReadFileToStringNonBlocking(base::FilePath("/proc/zoneinfo"),
&file_contents)) {
PLOG(ERROR) << "Couldn't get /proc/zoneinfo";
return 0;
}
// Reserve free pages is high watermark + lowmem_reserve and extra_free_kbytes
// raises the high watermark. Nullify the effect of extra_free_kbytes by
// excluding it from the reserved pages. The default extra_free_kbytes value
// is 0 if the file couldn't be accessed.
return CalculateReservedFreeKB(file_contents) -
ReadFileToUint64(base::FilePath(kExtraFree));
}
// CalculateAvailableMemoryUserSpaceKB implements the same available memory
// calculation as kernel function get_available_mem_adj(). The available memory
// consists of 3 parts: the free memory, the file cache, and the swappable
// memory. The available free memory is free memory minus reserved free memory.
// The available file cache is the total file cache minus reserved file cache
// (min_filelist). Because swapping is prohibited if there is no anonymous
// memory or no swap free, the swappable memory is the minimal of anonymous
// memory and swap free. As swapping memory is more costly than dropping file
// cache, only a fraction (1 / ram_swap_weight) of the swappable memory
// contributes to the available memory.
uint64_t SystemMemoryPressureEvaluator::CalculateAvailableMemoryUserSpaceKB(
const base::SystemMemoryInfoKB& info,
uint64_t reserved_free,
uint64_t min_filelist,
uint64_t ram_swap_weight) {
const uint64_t free = info.free;
const uint64_t anon = info.active_anon + info.inactive_anon;
const uint64_t file = info.active_file + info.inactive_file;
const uint64_t dirty = info.dirty;
const uint64_t swap_free = info.swap_free;
uint64_t available = (free > reserved_free) ? free - reserved_free : 0;
available += (file > dirty + min_filelist) ? file - dirty - min_filelist : 0;
available += std::min<uint64_t>(anon, swap_free) / ram_swap_weight;
return available;
}
uint64_t SystemMemoryPressureEvaluator::GetAvailableMemoryKB() { uint64_t SystemMemoryPressureEvaluator::GetAvailableMemoryKB() {
if (is_user_space_notify_) { if (is_user_space_notify_) {
base::SystemMemoryInfoKB info; return chromeos::memory::pressure::GetAvailableMemoryKB();
CHECK(base::GetSystemMemoryInfo(&info));
return CalculateAvailableMemoryUserSpaceKB(info, reserved_free_,
min_filelist_, ram_swap_weight_);
} else { } else {
const uint64_t available_mem_mb = const uint64_t available_mem_mb =
ReadAvailableMemoryMB(available_mem_file_.get()); ReadAvailableMemoryMB(available_mem_file_.get());
...@@ -458,14 +319,6 @@ void SystemMemoryPressureEvaluator::ScheduleEarlyCheck() { ...@@ -458,14 +319,6 @@ void SystemMemoryPressureEvaluator::ScheduleEarlyCheck() {
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
} }
void SystemMemoryPressureEvaluator::UpdateMemoryParameters() {
if (is_user_space_notify_) {
reserved_free_ = GetReservedMemoryKB();
min_filelist_ = ReadFileToUint64(base::FilePath(kMinFilelist));
ram_swap_weight_ = ReadFileToUint64(base::FilePath(kRamVsSwapWeight));
}
}
void SystemMemoryPressureEvaluator::ScheduleWaitForKernelNotification() { void SystemMemoryPressureEvaluator::ScheduleWaitForKernelNotification() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
......
// Copyright 2019 The Chromium Authors. All rights reserved. // Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROMEOS_MEMORY_PRESSURE_SYSTEM_MEMORY_PRESSURE_EVALUATOR_H_ #ifndef CHROMEOS_MEMORY_PRESSURE_SYSTEM_MEMORY_PRESSURE_EVALUATOR_H_
#define CHROMEOS_MEMORY_PRESSURE_SYSTEM_MEMORY_PRESSURE_EVALUATOR_H_ #define CHROMEOS_MEMORY_PRESSURE_SYSTEM_MEMORY_PRESSURE_EVALUATOR_H_
...@@ -13,7 +14,6 @@ ...@@ -13,7 +14,6 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/memory_pressure_listener.h" #include "base/memory/memory_pressure_listener.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/process/process_metrics.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "base/util/memory_pressure/memory_pressure_voter.h" #include "base/util/memory_pressure/memory_pressure_voter.h"
...@@ -72,10 +72,6 @@ class COMPONENT_EXPORT(CHROMEOS_MEMORY) SystemMemoryPressureEvaluator ...@@ -72,10 +72,6 @@ class COMPONENT_EXPORT(CHROMEOS_MEMORY) SystemMemoryPressureEvaluator
return critical_pressure_threshold_mb_; return critical_pressure_threshold_mb_;
} }
// The memory parameters are saved for optimization. If these memory
// parameters are changed, call this function to update the saved values.
void UpdateMemoryParameters();
// Returns the current system memory pressure evaluator. // Returns the current system memory pressure evaluator.
static SystemMemoryPressureEvaluator* Get(); static SystemMemoryPressureEvaluator* Get();
...@@ -91,16 +87,6 @@ class COMPONENT_EXPORT(CHROMEOS_MEMORY) SystemMemoryPressureEvaluator ...@@ -91,16 +87,6 @@ class COMPONENT_EXPORT(CHROMEOS_MEMORY) SystemMemoryPressureEvaluator
static std::vector<int> GetMarginFileParts(const std::string& margin_file); static std::vector<int> GetMarginFileParts(const std::string& margin_file);
static uint64_t CalculateReservedFreeKB(const std::string& zoneinfo);
static uint64_t GetReservedMemoryKB();
static uint64_t CalculateAvailableMemoryUserSpaceKB(
const base::SystemMemoryInfoKB& info,
uint64_t reserved_free,
uint64_t min_filelist,
uint64_t ram_swap_weight);
void CheckMemoryPressure(); void CheckMemoryPressure();
private: private:
...@@ -134,14 +120,6 @@ class COMPONENT_EXPORT(CHROMEOS_MEMORY) SystemMemoryPressureEvaluator ...@@ -134,14 +120,6 @@ class COMPONENT_EXPORT(CHROMEOS_MEMORY) SystemMemoryPressureEvaluator
// User space low memory notification mode. // User space low memory notification mode.
const bool is_user_space_notify_; const bool is_user_space_notify_;
// Values saved for user space available memory calculation. The value of
// |reserved_free_| should not change unless min_free_kbytes or
// lowmem_reserve_ratio change. The value of |min_filelist_| and
// |ram_swap_weight_| should not change unless the user sets them manually.
uint64_t reserved_free_;
uint64_t min_filelist_;
uint64_t ram_swap_weight_;
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<SystemMemoryPressureEvaluator> weak_ptr_factory_; base::WeakPtrFactory<SystemMemoryPressureEvaluator> weak_ptr_factory_;
......
...@@ -86,17 +86,6 @@ class TestSystemMemoryPressureEvaluator : public SystemMemoryPressureEvaluator { ...@@ -86,17 +86,6 @@ class TestSystemMemoryPressureEvaluator : public SystemMemoryPressureEvaluator {
static std::vector<int> GetMarginFileParts(const std::string& file) { static std::vector<int> GetMarginFileParts(const std::string& file) {
return SystemMemoryPressureEvaluator::GetMarginFileParts(file); return SystemMemoryPressureEvaluator::GetMarginFileParts(file);
} }
static uint64_t CalculateReservedFreeKB(const std::string& zoneinfo) {
return SystemMemoryPressureEvaluator::CalculateReservedFreeKB(zoneinfo);
}
static int CalculateAvailableMemoryUserSpaceKB(
const base::SystemMemoryInfoKB& info,
uint64_t reserved_free,
uint64_t min_filelist,
uint64_t ram_swap_weight) {
return SystemMemoryPressureEvaluator::CalculateAvailableMemoryUserSpaceKB(
info, reserved_free, min_filelist, ram_swap_weight);
}
~TestSystemMemoryPressureEvaluator() override = default; ~TestSystemMemoryPressureEvaluator() override = default;
...@@ -150,81 +139,6 @@ TEST(ChromeOSSystemMemoryPressureEvaluatorTest, ParseMarginFileBad) { ...@@ -150,81 +139,6 @@ TEST(ChromeOSSystemMemoryPressureEvaluatorTest, ParseMarginFileBad) {
.empty()); .empty());
} }
TEST(ChromeOSSystemMemoryPressureEvaluatorTest, CalculateReservedFreeKB) {
const std::string kMockPartialZoneinfo(R"(
Node 0, zone DMA
pages free 3968
min 137
low 171
high 205
spanned 4095
present 3999
managed 3976
protection: (0, 1832, 3000, 3786)
Node 0, zone DMA32
pages free 422432
min 16270
low 20337
high 24404
spanned 1044480
present 485541
managed 469149
protection: (0, 0, 1953, 1500)
Node 0, zone Normal
pages free 21708
min 17383
low 21728
high 26073
spanned 524288
present 524288
managed 501235
protection: (0, 0, 0, 0))");
constexpr uint64_t kPageSizeKB = 4;
const uint64_t high_watermarks = 205 + 24404 + 26073;
const uint64_t lowmem_reserves = 3786 + 1953 + 0;
const uint64_t reserved =
TestSystemMemoryPressureEvaluator::CalculateReservedFreeKB(
kMockPartialZoneinfo);
ASSERT_EQ(reserved, (high_watermarks + lowmem_reserves) * kPageSizeKB);
}
TEST(ChromeOSSystemMemoryPressureEvaluatorTest,
CalculateAvailableMemoryUserSpaceKB) {
base::SystemMemoryInfoKB info;
uint64_t available;
const uint64_t min_filelist = 400 * 1024;
const uint64_t reserved_free = 0;
const uint64_t ram_swap_weight = 4;
// Available determined by file cache.
info.inactive_file = 500 * 1024;
info.active_file = 500 * 1024;
available =
TestSystemMemoryPressureEvaluator::CalculateAvailableMemoryUserSpaceKB(
info, reserved_free, min_filelist, ram_swap_weight);
ASSERT_EQ(available, 1000 * 1024 - min_filelist);
// Available determined by swap free.
info.swap_free = 1200 * 1024;
info.inactive_anon = 1000 * 1024;
info.active_anon = 1000 * 1024;
info.inactive_file = 0;
info.active_file = 0;
available =
TestSystemMemoryPressureEvaluator::CalculateAvailableMemoryUserSpaceKB(
info, reserved_free, min_filelist, ram_swap_weight);
ASSERT_EQ(available, uint64_t(300 * 1024));
// Available determined by anonymous.
info.swap_free = 6000 * 1024;
info.inactive_anon = 500 * 1024;
info.active_anon = 500 * 1024;
available =
TestSystemMemoryPressureEvaluator::CalculateAvailableMemoryUserSpaceKB(
info, reserved_free, min_filelist, ram_swap_weight);
ASSERT_EQ(available, uint64_t(250 * 1024));
}
TEST(ChromeOSSystemMemoryPressureEvaluatorTest, CheckMemoryPressure) { TEST(ChromeOSSystemMemoryPressureEvaluatorTest, CheckMemoryPressure) {
// Create a temporary directory for our margin and available files. // Create a temporary directory for our margin and available files.
base::ScopedTempDir tmp_dir; base::ScopedTempDir tmp_dir;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment