summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hridya Valsaraju <hridya@google.com> 2019-08-12 22:10:01 -0700
committer android-build-merger <android-build-merger@google.com> 2019-08-12 22:10:01 -0700
commit7e465a9917f5493bca7015aa7da20259757ba2d9 (patch)
tree10a7a15d37c559c784262c66923547f57dec5958
parent499d257f06106ba6d454efabe8fd54975ff2a415 (diff)
parent8587fec4e169ce22ec0fb0927a197b872b4e620e (diff)
Merge "Dump 'external fragmentation unusable index'." am: b3701625d9
am: 8587fec4e1 Change-Id: I01503ea2e32651cfe3f4d35eb0d804fdd2dae9db
-rw-r--r--cmds/dumpstate/dumpstate.cpp43
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");