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

Commit d70e2021 authored by Sandeep Patil's avatar Sandeep Patil
Browse files

Fix vmalloc memory usage parsing.

The size in /proc/vmallocinfo actually represents the size of
the virtual region and not the size of memory allocated for the same.
So, we have been over counting vmalloc memory usage in most cases
leading into negative "Lost RAM".

Moreover, as of kernel 4.14, binder allocations that were ignored before
are now counted as vmalloc allocations since binder started using the
'vmalloc' flag instead of 'ioremap' flag for its vm area allocations.

  See: https://android.googlesource.com/kernel/common/+/86eda3864a704a98d5444ae60654b898731bfea5



.. This makes the problem even worse for devices that are running
kernel 4.14 and beyond.

Fix that by looking specifically for "pages=" in each line of
/proc/vmallocinfo to get the number of physical pages associated with
the particular allocation.

Bug: 119639955
Test: 'dumpsys meminfo' before and after on cuttlefish running 4.14 kernel.
Result:
  Lost RAM (before) : -151,462K
  Lost RAM (after) : -5,312K

Change-Id: I3d677572613392383ee8ea0968bde0e0913c42cf
Signed-off-by: default avatarSandeep Patil <sspatil@google.com>
parent d0f47278
Loading
Loading
Loading
Loading
+10 −18
Original line number Diff line number Diff line
@@ -692,14 +692,8 @@ static jlong android_os_Debug_getPss(JNIEnv *env, jobject clazz)

static long get_allocated_vmalloc_memory() {
    char line[1024];
    // Ignored tags that don't actually consume memory (ie remappings)
    static const char* const ignored_tags[] = {
            "ioremap",
            "map_lowmem",
            "vm_map_ram",
            NULL
    };
    long size, vmalloc_allocated_size = 0;

    long vmalloc_allocated_size = 0;

    UniqueFile fp = MakeUniqueFile("/proc/vmallocinfo", "re");
    if (fp == nullptr) {
@@ -710,17 +704,15 @@ static long get_allocated_vmalloc_memory() {
        if (fgets(line, 1024, fp.get()) == NULL) {
            break;
        }
        bool valid_line = true;
        int i = 0;
        while (ignored_tags[i]) {
            if (strstr(line, ignored_tags[i]) != NULL) {
                valid_line = false;
                break;
            }
            i++;

        // check to see if there are pages mapped in vmalloc area
        if (!strstr(line, "pages=")) {
            continue;
        }
        if (valid_line && (sscanf(line, "%*x-%*x %ld", &size) == 1)) {
            vmalloc_allocated_size += size;

        long nr_pages;
        if (sscanf(line, "%*x-%*x %*ld %*s pages=%ld", &nr_pages) == 1) {
            vmalloc_allocated_size += (nr_pages * getpagesize());
        }
    }
    return vmalloc_allocated_size;