Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac582cd6 authored by Hridya Valsaraju's avatar Hridya Valsaraju
Browse files

Dump 'external fragmentation unusable index'.

Currently, /d/extfrag/unusable_index is read by dumpstate to print the
unusable index for each allocation order. From Android R, platform code
is no longer allowed to access debugfs since its ABI is not considered
to be stable. Hence, instead of reading /d/extrag/unusable_index, this
CL calculates unusable index information from /proc/buddyinfo instead.
Here are the calculated values and those read from
/d/extfrag/unusable_index for comparison.

------ FRAGMENTATION INFO (/d/extfrag/unusable_index) ------                                        
Node 0, zone      DMA 0.000 0.399 0.720 0.884 0.966 0.978 0.982 0.992 1.000 1.000 1.000            
Node 0, zone   Normal 0.000 0.101 0.444 0.561 0.680 0.780 0.906 1.000 1.000 1.000 1.000            
                                                                                                   
------ EXTERNAL FRAGMENTATION INFO ------                                                          
Node 0, zone      DMA 0.000 0.399 0.721 0.884 0.966 0.979 0.983 0.992 1.000 1.000 1.000            
Node 0, zone   Normal 0.000 0.101 0.445 0.561 0.681 0.781 0.907 1.000 1.000 1.000 1.000  

Bug: 134669095
Test: adb shell dumpstate

Change-Id: I3e84505cca8ef2327ad7058385d3f60928b2e436
parent ef211707
Loading
Loading
Loading
Loading
+42 −1
Original line number Diff line number Diff line
@@ -34,10 +34,12 @@
#include <unistd.h>

#include <chrono>
#include <cmath>
#include <fstream>
#include <functional>
#include <future>
#include <memory>
#include <numeric>
#include <regex>
#include <set>
#include <string>
@@ -1283,6 +1285,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
@@ -1309,7 +1350,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");