blob: 3b471235cdb140bf3ba77b9f3b1a223730c74d57 [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_stats.h"
#include <string>
#include <utility>
#include <vector>
#include <base/logging.h>
#include <base/strings/string_split.h>
#include <base/strings/string_number_conversions.h>
#include <base/files/file_path.h>
namespace swap_management {
absl::Status ParseZramMmStat(const std::string& input,
ZramMmStat* zram_mm_stat) {
std::vector<std::string> zram_mm_stat_list = base::SplitString(
input, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
// Return false if the list size is less than number of items in ZramMmStat
// From first version of Zram mm_stat in v4.4, there are seven fields inside.
if (zram_mm_stat_list.size() < 7)
return absl::InvalidArgumentError("Malformed zram mm_stat input");
// In zram_drv.h we define max_used_pages as atomic_long_t which could
// be negative, but negative value does not make sense for the
// variable. return false if negative max_used_pages.
int64_t tmp_mem_used_max = 0;
if (!base::StringToInt64(zram_mm_stat_list[4], &tmp_mem_used_max) ||
tmp_mem_used_max < 0)
return absl::InvalidArgumentError("Bad value for zram max_used_pages");
zram_mm_stat->mem_used_max = static_cast<uint64_t>(tmp_mem_used_max);
bool status =
base::StringToUint64(zram_mm_stat_list[0],
&zram_mm_stat->orig_data_size) &&
base::StringToUint64(zram_mm_stat_list[1],
&zram_mm_stat->compr_data_size) &&
base::StringToUint64(zram_mm_stat_list[2],
&zram_mm_stat->mem_used_total) &&
base::StringToUint(zram_mm_stat_list[3], &zram_mm_stat->mem_limit) &&
base::StringToUint64(zram_mm_stat_list[5], &zram_mm_stat->same_pages) &&
base::StringToUint(zram_mm_stat_list[6], &zram_mm_stat->pages_compacted);
constexpr static size_t kHugeIdx = 7;
constexpr static size_t kHugeSinceIdx = 8;
uint64_t value = 0;
if (zram_mm_stat_list.size() > kHugeIdx) {
status &= base::StringToUint64(zram_mm_stat_list[kHugeIdx], &value);
if (status)
zram_mm_stat->huge_pages = value;
}
if (zram_mm_stat_list.size() > kHugeSinceIdx) {
status &= base::StringToUint64(zram_mm_stat_list[kHugeSinceIdx], &value);
if (status)
zram_mm_stat->huge_pages_since = value;
}
return status ? absl::OkStatus()
: absl::InvalidArgumentError("Failed to parse zram mm_stat");
}
absl::Status ParseZramBdStat(const std::string& input,
ZramBdStat* zram_bd_stat) {
std::vector<std::string> zram_bd_stat_list = base::SplitString(
input, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
// Return false if the list size is less than number of items in ZramBdStat
if (zram_bd_stat_list.size() < 3)
return absl::InvalidArgumentError("Malformed zram bd_stat input");
bool status =
base::StringToUint64(zram_bd_stat_list[0], &zram_bd_stat->bd_count) &&
base::StringToUint64(zram_bd_stat_list[1], &zram_bd_stat->bd_reads) &&
base::StringToUint64(zram_bd_stat_list[2], &zram_bd_stat->bd_writes);
return status ? absl::OkStatus()
: absl::InvalidArgumentError("Failed to parse zram bd_stat");
}
absl::Status ParseZramIoStat(const std::string& input,
ZramIoStat* zram_io_stat) {
std::vector<std::string> zram_io_stat_list = base::SplitString(
input, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
// Return false if the list size is less than number of items in ZramIoStat
if (zram_io_stat_list.size() < 3)
return absl::InvalidArgumentError("Malformed zram bd_stat input");
bool status =
base::StringToUint64(zram_io_stat_list[0], &zram_io_stat->failed_reads) &&
base::StringToUint64(zram_io_stat_list[1],
&zram_io_stat->failed_writes) &&
base::StringToUint64(zram_io_stat_list[2], &zram_io_stat->invalid_io) &&
base::StringToUint64(zram_io_stat_list[3], &zram_io_stat->notify_free);
return status ? absl::OkStatus()
: absl::InvalidArgumentError("Failed to parse zram bd_stat");
}
absl::StatusOr<ZramBdStat> GetZramBdStat() {
std::string buf;
absl::Status status = Utils::Get()->ReadFileToString(
base::FilePath(kZramSysfsDir).Append("bd_stat"), &buf);
if (!status.ok())
return status;
ZramBdStat zram_bd_stat;
status = ParseZramBdStat(buf, &zram_bd_stat);
if (!status.ok())
return status;
return std::move(zram_bd_stat);
}
absl::StatusOr<ZramMmStat> GetZramMmStat() {
std::string buf;
absl::Status status = Utils::Get()->ReadFileToString(
base::FilePath(kZramSysfsDir).Append("mm_stat"), &buf);
if (!status.ok())
return status;
ZramMmStat zram_mm_stat;
status = ParseZramMmStat(buf, &zram_mm_stat);
if (!status.ok())
return status;
return std::move(zram_mm_stat);
}
absl::StatusOr<ZramIoStat> GetZramIoStat() {
std::string buf;
absl::Status status = Utils::Get()->ReadFileToString(
base::FilePath(kZramSysfsDir).Append("io_stat"), &buf);
if (!status.ok())
return status;
ZramIoStat zram_io_stat;
status = ParseZramIoStat(buf, &zram_io_stat);
if (!status.ok())
return status;
return std::move(zram_io_stat);
}
} // namespace swap_management