diff options
| author | 2019-08-12 22:10:01 -0700 | |
|---|---|---|
| committer | 2019-08-12 22:10:01 -0700 | |
| commit | 7e465a9917f5493bca7015aa7da20259757ba2d9 (patch) | |
| tree | 10a7a15d37c559c784262c66923547f57dec5958 | |
| parent | 499d257f06106ba6d454efabe8fd54975ff2a415 (diff) | |
| parent | 8587fec4e169ce22ec0fb0927a197b872b4e620e (diff) | |
Merge "Dump 'external fragmentation unusable index'." am: b3701625d9
am: 8587fec4e1
Change-Id: I01503ea2e32651cfe3f4d35eb0d804fdd2dae9db
| -rw-r--r-- | cmds/dumpstate/dumpstate.cpp | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index 79f345b697..af9ce78c17 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -44,10 +44,12 @@ #include <unistd.h> #include <chrono> +#include <cmath> #include <fstream> #include <functional> #include <future> #include <memory> +#include <numeric> #include <regex> #include <set> #include <string> @@ -1232,6 +1234,45 @@ static void DumpHals() { } } +static void DumpExternalFragmentationInfo() { + struct stat st; + if (stat("/proc/buddyinfo", &st) != 0) { + MYLOGE("Unable to dump external fragmentation info\n"); + return; + } + + printf("------ EXTERNAL FRAGMENTATION INFO ------\n"); + std::ifstream ifs("/proc/buddyinfo"); + auto unusable_index_regex = std::regex{"Node\\s+([0-9]+),\\s+zone\\s+(\\S+)\\s+(.*)"}; + for (std::string line; std::getline(ifs, line);) { + std::smatch match_results; + if (std::regex_match(line, match_results, unusable_index_regex)) { + std::stringstream free_pages(std::string{match_results[3]}); + std::vector<int> free_pages_per_order(std::istream_iterator<int>{free_pages}, + std::istream_iterator<int>()); + + int total_free_pages = 0; + for (size_t i = 0; i < free_pages_per_order.size(); i++) { + total_free_pages += (free_pages_per_order[i] * std::pow(2, i)); + } + + printf("Node %s, zone %8s", match_results[1].str().c_str(), + match_results[2].str().c_str()); + + int usable_free_pages = total_free_pages; + for (size_t i = 0; i < free_pages_per_order.size(); i++) { + auto unusable_index = (total_free_pages - usable_free_pages) / + static_cast<double>(total_free_pages); + printf(" %5.3f", unusable_index); + usable_free_pages -= (free_pages_per_order[i] * std::pow(2, i)); + } + + printf("\n"); + } + } + printf("\n"); +} + // Dumps various things. Returns early with status USER_CONSENT_DENIED if user denies consent // via the consent they are shown. Ignores other errors that occur while running various // commands. The consent checking is currently done around long running tasks, which happen to @@ -1258,7 +1299,7 @@ static Dumpstate::RunStatus dumpstate() { DumpFile("ZONEINFO", "/proc/zoneinfo"); DumpFile("PAGETYPEINFO", "/proc/pagetypeinfo"); DumpFile("BUDDYINFO", "/proc/buddyinfo"); - DumpFile("FRAGMENTATION INFO", "/d/extfrag/unusable_index"); + DumpExternalFragmentationInfo(); DumpFile("KERNEL WAKE SOURCES", "/d/wakeup_sources"); DumpFile("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state"); |