blob: 0516ffb01fc94a5a8231368828a1366e4a3e1566 [file] [log] [blame] [edit]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "swap_management/utils.h"
#include "swap_management/zram_idle.h"
#include <base/logging.h>
namespace swap_management {
namespace {
constexpr base::TimeDelta kMaxIdleAge = base::Days(30);
}
absl::Status MarkIdle(uint32_t age_seconds) {
const auto age = base::Seconds(age_seconds);
// Only allow marking pages as idle between 0 sec and 30 days.
if (age > kMaxIdleAge)
return absl::OutOfRangeError("Invalid age " + std::to_string(age_seconds));
base::FilePath filepath = base::FilePath(kZramSysfsDir).Append("idle");
return Utils::Get()->WriteFile(filepath, std::to_string(age.InSeconds()));
}
std::optional<uint64_t> GetCurrentIdleTimeSec(uint64_t min_sec,
uint64_t max_sec) {
absl::StatusOr<base::SystemMemoryInfoKB> meminfo =
Utils::Get()->GetSystemMemoryInfo();
if (!meminfo.ok()) {
LOG(ERROR) << "Can not read meminfo: " << meminfo.status();
return std::nullopt;
}
// Stay between idle_(min|max)_time.
double mem_utilization =
(1.0 - (static_cast<double>((*meminfo).available) / (*meminfo).total));
// Exponentially decay the age vs. memory utilization. The reason
// we choose exponential decay is because we want to do as little work as
// possible when the system is under very low memory pressure. As pressure
// increases we want to start aggressively shrinking our idle age to force
// newer pages to be written back/recompressed.
constexpr double kLambda = 5;
return (max_sec - min_sec) * pow(M_E, -kLambda * mem_utilization) + min_sec;
}
} // namespace swap_management