Snap for 8564071 from 35f68506d29b8031ac98bdaf89fd6a22c83f9192 to mainline-adbd-release

Change-Id: I1e24e8e61d7758ae89479513bb647ea6c63a9de2
diff --git a/Android.bp b/Android.bp
index 7306d44..d16b05d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -34,21 +34,6 @@
         "libdmabufinfo",
     ],
     target: {
-        android: {
-            static_libs: [
-                "libbpf_android",
-            ],
-        },
-        apex: {
-            exclude_static_libs: [
-                "libbpf_android",
-            ],
-        },
-	vendor: {
-	    exclude_static_libs: [
-	        "libbpf_android",
-	    ],
-	},
         darwin: {
             enabled: false,
         },
@@ -67,6 +52,7 @@
         "libdmabufinfo/include",
     ],
     export_shared_lib_headers: ["libbase"],
+    header_libs: ["bpf_headers"],
     srcs: [
         "pageacct.cpp",
         "procmeminfo.cpp",
diff --git a/OWNERS b/OWNERS
index b15bb48..5a7a0bd 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1 +1,2 @@
+# Bug component: 391836
 [email protected]
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 32750b0..8dae108 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -3,5 +3,10 @@
     {
       "name": "libmeminfo_test"
     }
+  ],
+  "hwasan-postsubmit": [
+    {
+      "name": "libmeminfo_test"
+    }
   ]
 }
diff --git a/include/meminfo/sysmeminfo.h b/include/meminfo/sysmeminfo.h
index 175a0df..a17f8ef 100644
--- a/include/meminfo/sysmeminfo.h
+++ b/include/meminfo/sysmeminfo.h
@@ -24,6 +24,7 @@
 #include <map>
 #include <string>
 #include <string_view>
+#include <unordered_map>
 
 namespace android {
 namespace meminfo {
@@ -121,6 +122,12 @@
 bool ReadDmabufHeapPoolsSizeKb(uint64_t* size,
                             const std::string& path = "/sys/kernel/dma_heap/total_pools_kb");
 
+// Read per-process GPU memory usage. Returns a map of pid -> GPU Mem in kilobytes.
+bool ReadPerProcessGpuMem(std::unordered_map<uint32_t, uint64_t>* out);
+
+// Read GPU usage of the specified process in kb.
+bool ReadProcessGpuUsageKb(uint32_t pid, uint32_t gpu_id, uint64_t* size);
+
 // Read GPU total usage size in kb
 bool ReadGpuTotalUsageKb(uint64_t* size);
 
diff --git a/libdmabufinfo/dmabufinfo.cpp b/libdmabufinfo/dmabufinfo.cpp
index 422fc6e..cb639c1 100644
--- a/libdmabufinfo/dmabufinfo.cpp
+++ b/libdmabufinfo/dmabufinfo.cpp
@@ -302,5 +302,36 @@
     return true;
 }
 
+bool ReadDmaBufs(std::vector<DmaBuffer>* bufs) {
+    bufs->clear();
+
+    std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir("/proc"), closedir);
+    if (!dir) {
+        LOG(ERROR) << "Failed to open /proc directory";
+        bufs->clear();
+        return false;
+    }
+
+    struct dirent* dent;
+    while ((dent = readdir(dir.get()))) {
+        if (dent->d_type != DT_DIR) continue;
+
+        int pid = atoi(dent->d_name);
+        if (pid == 0) {
+            continue;
+        }
+
+        if (!ReadDmaBufFdRefs(pid, bufs)) {
+            LOG(ERROR) << "Failed to read dmabuf fd references for pid " << pid;
+        }
+
+        if (!ReadDmaBufMapRefs(pid, bufs)) {
+            LOG(ERROR) << "Failed to read dmabuf map references for pid " << pid;
+        }
+    }
+
+    return true;
+}
+
 }  // namespace dmabufinfo
 }  // namespace android
diff --git a/libdmabufinfo/include/dmabufinfo/dmabufinfo.h b/libdmabufinfo/include/dmabufinfo/dmabufinfo.h
index 93736df..bb4aff1 100644
--- a/libdmabufinfo/include/dmabufinfo/dmabufinfo.h
+++ b/libdmabufinfo/include/dmabufinfo/dmabufinfo.h
@@ -127,5 +127,10 @@
 bool ReadDmaBufPss(int pid, uint64_t* pss, const std::string& procfs_path = "/proc",
                    const std::string& dmabuf_sysfs_path = "/sys/kernel/dmabuf/buffers");
 
+// Writes DmaBuffer info into an existing vector (which will be cleared first.)
+// Will include all DmaBuffers, whether thay are retained or mapped.
+// Returns true on success, otherwise false.
+bool ReadDmaBufs(std::vector<DmaBuffer>* bufs);
+
 }  // namespace dmabufinfo
 }  // namespace android
diff --git a/libdmabufinfo/tools/dmabuf_dump.cpp b/libdmabufinfo/tools/dmabuf_dump.cpp
index 57204f6..65ebd08 100644
--- a/libdmabufinfo/tools/dmabuf_dump.cpp
+++ b/libdmabufinfo/tools/dmabuf_dump.cpp
@@ -179,45 +179,6 @@
            total_size / 1024, kernel_rss / 1024, total_rss / 1024, total_pss / 1024);
 }
 
-static bool ReadDmaBufs(std::vector<DmaBuffer>* bufs) {
-    bufs->clear();
-
-    if (!ReadDmaBufInfo(bufs)) {
-        printf("debugfs entry for dmabuf not available, using /proc/<pid>/fdinfo instead\n");
-    }
-
-    std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir("/proc"), closedir);
-    if (!dir) {
-        fprintf(stderr, "Failed to open /proc directory\n");
-        bufs->clear();
-        return false;
-    }
-
-    struct dirent* dent;
-    while ((dent = readdir(dir.get()))) {
-        if (dent->d_type != DT_DIR) continue;
-
-        int pid = atoi(dent->d_name);
-        if (pid == 0) {
-            continue;
-        }
-
-        if (!ReadDmaBufFdRefs(pid, bufs)) {
-            fprintf(stderr, "Failed to read dmabuf fd references for pid %d\n", pid);
-            bufs->clear();
-            return false;
-        }
-
-        if (!ReadDmaBufMapRefs(pid, bufs)) {
-            fprintf(stderr, "Failed to read dmabuf map references for pid %d\n", pid);
-            bufs->clear();
-            return false;
-        }
-    }
-
-    return true;
-}
-
 static void DumpDmabufSysfsStats() {
     android::dmabufinfo::DmabufSysfsStats stats;
 
@@ -300,7 +261,10 @@
             exit(EXIT_FAILURE);
         }
     } else {
-        if (!ReadDmaBufs(&bufs)) exit(EXIT_FAILURE);
+        if (!ReadDmaBufs(&bufs)) {
+            fprintf(stderr, "Failed to ReadDmaBufs, check logcat for info\n");
+            exit(EXIT_FAILURE);
+        }
     }
 
     // Show the old dmabuf table, inode x process
diff --git a/libmeminfo_test.cpp b/libmeminfo_test.cpp
index c41e4ff..20159bf 100644
--- a/libmeminfo_test.cpp
+++ b/libmeminfo_test.cpp
@@ -967,7 +967,7 @@
 TEST(SysMemInfo, TestReadGpuTotalUsageKb) {
     uint64_t size;
 
-    if (android::base::GetIntProperty("ro.product.first_api_level", 0) < __ANDROID_API_S__) {
+    if (android::base::GetIntProperty("ro.vendor.api_level", 0) < __ANDROID_API_S__) {
         GTEST_SKIP();
     }
 
diff --git a/procmeminfo.cpp b/procmeminfo.cpp
index af64f86..13a17da 100644
--- a/procmeminfo.cpp
+++ b/procmeminfo.cpp
@@ -68,55 +68,58 @@
 
 // Returns true if the line was valid smaps stats line false otherwise.
 static bool parse_smaps_field(const char* line, MemUsage* stats) {
-    char field[64];
-    int len;
-    if (sscanf(line, "%63s %n", field, &len) == 1 && *field && field[strlen(field) - 1] == ':') {
-        const char* c = line + len;
-        switch (field[0]) {
+    const char *end = line;
+
+    // https://lore.kernel.org/patchwork/patch/1088579/ introduced tabs. Handle this case as well.
+    while (*end && !isspace(*end)) end++;
+    if (*end && end > line && *(end - 1) == ':') {
+        const char* c = end;
+        while (isspace(*c)) c++;
+        switch (line[0]) {
             case 'P':
-                if (strncmp(field, "Pss:", 4) == 0) {
+                if (strncmp(line, "Pss:", 4) == 0) {
                     stats->pss = strtoull(c, nullptr, 10);
-                } else if (strncmp(field, "Private_Clean:", 14) == 0) {
+                } else if (strncmp(line, "Private_Clean:", 14) == 0) {
                     uint64_t prcl = strtoull(c, nullptr, 10);
                     stats->private_clean = prcl;
                     stats->uss += prcl;
-                } else if (strncmp(field, "Private_Dirty:", 14) == 0) {
+                } else if (strncmp(line, "Private_Dirty:", 14) == 0) {
                     uint64_t prdi = strtoull(c, nullptr, 10);
                     stats->private_dirty = prdi;
                     stats->uss += prdi;
-                } else if (strncmp(field, "Private_Hugetlb:", 16) == 0) {
+                } else if (strncmp(line, "Private_Hugetlb:", 16) == 0) {
                     stats->private_hugetlb = strtoull(c, nullptr, 10);
                 }
                 break;
             case 'S':
-                if (strncmp(field, "Size:", 5) == 0) {
+                if (strncmp(line, "Size:", 5) == 0) {
                     stats->vss = strtoull(c, nullptr, 10);
-                } else if (strncmp(field, "Shared_Clean:", 13) == 0) {
+                } else if (strncmp(line, "Shared_Clean:", 13) == 0) {
                     stats->shared_clean = strtoull(c, nullptr, 10);
-                } else if (strncmp(field, "Shared_Dirty:", 13) == 0) {
+                } else if (strncmp(line, "Shared_Dirty:", 13) == 0) {
                     stats->shared_dirty = strtoull(c, nullptr, 10);
-                } else if (strncmp(field, "Swap:", 5) == 0) {
+                } else if (strncmp(line, "Swap:", 5) == 0) {
                     stats->swap = strtoull(c, nullptr, 10);
-                } else if (strncmp(field, "SwapPss:", 8) == 0) {
+                } else if (strncmp(line, "SwapPss:", 8) == 0) {
                     stats->swap_pss = strtoull(c, nullptr, 10);
-                } else if (strncmp(field, "ShmemPmdMapped:", 15) == 0) {
+                } else if (strncmp(line, "ShmemPmdMapped:", 15) == 0) {
                     stats->shmem_pmd_mapped = strtoull(c, nullptr, 10);
-                } else if (strncmp(field, "Shared_Hugetlb:", 15) == 0) {
+                } else if (strncmp(line, "Shared_Hugetlb:", 15) == 0) {
                     stats->shared_hugetlb = strtoull(c, nullptr, 10);
                 }
                 break;
             case 'R':
-                if (strncmp(field, "Rss:", 4) == 0) {
+                if (strncmp(line, "Rss:", 4) == 0) {
                     stats->rss = strtoull(c, nullptr, 10);
                 }
                 break;
             case 'A':
-                if (strncmp(field, "AnonHugePages:", 14) == 0) {
+                if (strncmp(line, "AnonHugePages:", 14) == 0) {
                     stats->anon_huge_pages = strtoull(c, nullptr, 10);
                 }
                 break;
             case 'F':
-                if (strncmp(field, "FilePmdMapped:", 14) == 0) {
+                if (strncmp(line, "FilePmdMapped:", 14) == 0) {
                     stats->file_pmd_mapped = strtoull(c, nullptr, 10);
                 }
                 break;
@@ -383,10 +386,6 @@
     size_t num_in_page_cache = 0;
     size_t num_leftover_pages = num_pages;
     for (size_t cur_page = first_page; cur_page < first_page + num_pages; ++cur_page) {
-        if (!get_wss) {
-            vma.usage.vss += pagesz;
-        }
-
         // Cache page map data.
         if (cur_page_cache_index == num_in_page_cache) {
             static constexpr size_t kMaxPages = 2048;
@@ -479,6 +478,9 @@
             vma.usage.shared_clean += is_dirty ? 0 : pagesz;
         }
     }
+    if (!get_wss) {
+        vma.usage.vss += pagesz * num_pages;
+    }
     return true;
 }
 
diff --git a/sysmeminfo.cpp b/sysmeminfo.cpp
index 2dabea8..b7a9c70 100644
--- a/sysmeminfo.cpp
+++ b/sysmeminfo.cpp
@@ -320,11 +320,9 @@
     return true;
 }
 
-bool ReadGpuTotalUsageKb(uint64_t* size) {
+bool ReadPerProcessGpuMem([[maybe_unused]] std::unordered_map<uint32_t, uint64_t>* out) {
 #if defined(__ANDROID__) && !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)
-    static constexpr const char kBpfGpuMemTotalMap[] =
-        "/sys/fs/bpf/map_gpu_mem_gpu_mem_total_map";
-    static constexpr uint64_t kBpfKeyGpuTotalUsage = 0;
+    static constexpr const char kBpfGpuMemTotalMap[] = "/sys/fs/bpf/map_gpu_mem_gpu_mem_total_map";
 
     // Use the read-only wrapper BpfMapRO to properly retrieve the read-only map.
     auto map = bpf::BpfMapRO<uint64_t, uint64_t>(kBpfGpuMemTotalMap);
@@ -333,14 +331,73 @@
         return false;
     }
 
-    auto res = map.readValue(kBpfKeyGpuTotalUsage);
-    if (!res.ok()) {
+    if (!out) {
+        LOG(ERROR) << "ReadPerProcessGpuMem: out param is null";
+        return false;
+    }
+    out->clear();
+
+    auto map_key = map.getFirstKey();
+    if (!map_key.ok()) {
+        return true;
+    }
+
+    do {
+        uint64_t key = map_key.value();
+        uint32_t pid = key;  // BPF Key [32-bits GPU ID | 32-bits PID]
+
+        auto gpu_mem = map.readValue(key);
+        if (!gpu_mem.ok()) {
+            LOG(ERROR) << "Invalid file format: " << kBpfGpuMemTotalMap;
+            return false;
+        }
+
+        const auto& iter = out->find(pid);
+        if (iter == out->end()) {
+            out->insert({pid, gpu_mem.value() / 1024});
+        } else {
+            iter->second += gpu_mem.value() / 1024;
+        }
+
+        map_key = map.getNextKey(key);
+    } while (map_key.ok());
+
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool ReadProcessGpuUsageKb([[maybe_unused]] uint32_t pid, [[maybe_unused]] uint32_t gpu_id,
+                           uint64_t* size) {
+#if defined(__ANDROID__) && !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)
+    static constexpr const char kBpfGpuMemTotalMap[] = "/sys/fs/bpf/map_gpu_mem_gpu_mem_total_map";
+
+    uint64_t gpu_mem;
+
+    // BPF Key [32-bits GPU ID | 32-bits PID]
+    uint64_t kBpfKeyGpuUsage = ((uint64_t)gpu_id << 32) | pid;
+
+    // Use the read-only wrapper BpfMapRO to properly retrieve the read-only map.
+    auto map = bpf::BpfMapRO<uint64_t, uint64_t>(kBpfGpuMemTotalMap);
+    if (!map.isValid()) {
+        LOG(ERROR) << "Can't open file: " << kBpfGpuMemTotalMap;
+        return false;
+    }
+
+    auto res = map.readValue(kBpfKeyGpuUsage);
+
+    if (res.ok()) {
+        gpu_mem = res.value();
+    } else if (res.error().code() == ENOENT) {
+        gpu_mem = 0;
+    } else {
         LOG(ERROR) << "Invalid file format: " << kBpfGpuMemTotalMap;
         return false;
     }
 
     if (size) {
-        *size = res.value() / 1024;
+        *size = gpu_mem / 1024;
     }
     return true;
 #else
@@ -351,5 +408,13 @@
 #endif
 }
 
+bool ReadGpuTotalUsageKb(uint64_t* size) {
+    // gpu_mem_total tracepoint defines PID 0 as global total
+    // GPU ID 0 suffices for current android devices.
+    // This will need to check all GPU IDs in future if more than
+    // one is GPU device is present on the device.
+    return ReadProcessGpuUsageKb(0, 0, size);
+}
+
 }  // namespace meminfo
 }  // namespace android
diff --git a/tools/Android.bp b/tools/Android.bp
index 8cb98fc..d336434 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -55,6 +55,7 @@
     shared_libs: [
         "libbase",
         "libmeminfo",
+        "libprocinfo",
     ],
 }
 
diff --git a/tools/procrank.cpp b/tools/procrank.cpp
index e7c1af9..e4f247a 100644
--- a/tools/procrank.cpp
+++ b/tools/procrank.cpp
@@ -25,6 +25,7 @@
 #include <linux/oom.h>
 #include <meminfo/procmeminfo.h>
 #include <meminfo/sysmeminfo.h>
+#include <procinfo/process.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
@@ -32,7 +33,9 @@
 
 #include <iostream>
 #include <memory>
+#include <set>
 #include <sstream>
+#include <unordered_map>
 #include <vector>
 
 using ::android::meminfo::MemUsage;
@@ -142,7 +145,7 @@
 uint64_t total_zswap = 0;
 
 [[noreturn]] static void usage(int exit_status) {
-    std::cerr << "Usage: " << getprogname() << " [ -W ] [ -v | -r | -p | -u | -s | -h ]"
+    std::cerr << "Usage: " << getprogname() << " [ -W ] [ -v | -r | -p | -u | -s | -h ] [-d PID]"
               << std::endl
               << "    -v  Sort by VSS." << std::endl
               << "    -r  Sort by RSS." << std::endl
@@ -155,14 +158,15 @@
               << "    -C  Only show non-cached (ram/swap backed) pages" << std::endl
               << "    -k  Only show pages collapsed by KSM" << std::endl
               << "    -w  Display statistics for working set only." << std::endl
-              << "    -W  Reset working set of all processes." << std::endl
+              << "    -W  Reset working set of processes." << std::endl
               << "    -o  Show and sort by oom score against lowmemorykiller thresholds."
               << std::endl
+              << "    -d  Filter to descendants of specified process (can be repeated)" << std::endl
               << "    -h  Display this help screen." << std::endl;
     exit(exit_status);
 }
 
-static bool read_all_pids(std::vector<pid_t>* pids, std::function<bool(pid_t pid)> for_each_pid) {
+static bool read_all_pids(std::set<pid_t>* pids) {
     pids->clear();
     std::unique_ptr<DIR, int (*)(DIR*)> procdir(opendir("/proc"), closedir);
     if (!procdir) return false;
@@ -171,8 +175,7 @@
     pid_t pid;
     while ((dir = readdir(procdir.get()))) {
         if (!::android::base::ParseInt(dir->d_name, &pid)) continue;
-        if (!for_each_pid(pid)) return false;
-        pids->emplace_back(pid);
+        pids->insert(pid);
     }
 
     return true;
@@ -375,8 +378,9 @@
     uint64_t pgflags = 0;
     uint64_t pgflags_mask = 0;
 
+    std::vector<pid_t> descendant_filter;
     int opt;
-    while ((opt = getopt(argc, argv, "cChkoprRsuvwW")) != -1) {
+    while ((opt = getopt(argc, argv, "cCd:hkoprRsuvwW")) != -1) {
         switch (opt) {
             case 'c':
                 pgflags = 0;
@@ -386,6 +390,15 @@
                 pgflags = (1 << KPF_SWAPBACKED);
                 pgflags_mask = (1 << KPF_SWAPBACKED);
                 break;
+            case 'd': {
+                pid_t p;
+                if (!android::base::ParseInt(optarg, &p)) {
+                    std::cerr << "Failed to parse pid '" << optarg << "'" << std::endl;
+                    usage(EXIT_FAILURE);
+                }
+                descendant_filter.push_back(p);
+                break;
+            }
             case 'h':
                 usage(EXIT_SUCCESS);
             case 'k':
@@ -425,13 +438,58 @@
         }
     }
 
-    std::vector<pid_t> pids;
+    std::set<pid_t> pids;
     std::vector<ProcessRecord> procs;
+    if (!read_all_pids(&pids)) {
+        std::cerr << "Failed to read pids" << std::endl;
+        exit(EXIT_FAILURE);
+    }
+
+    if (descendant_filter.size()) {
+        // Map from parent pid to all of its children.
+        std::unordered_map<pid_t, std::vector<pid_t>> pid_tree;
+
+        for (pid_t pid : pids) {
+            android::procinfo::ProcessInfo info;
+            std::string error;
+            if (!android::procinfo::GetProcessInfo(pid, &info, &error)) {
+                std::cerr << "warning: failed to get process info for: " << pid << ": " << error
+                          << std::endl;
+                continue;
+            }
+
+            pid_tree[info.ppid].push_back(pid);
+        }
+
+        std::set<pid_t> final_pids;
+        std::vector<pid_t>& frontier = descendant_filter;
+
+        // Do a breadth-first walk of the process tree, starting from the pids we were given.
+        while (!frontier.empty()) {
+            pid_t pid = frontier.back();
+            frontier.pop_back();
+
+            // It's possible for the pid we're looking at to already be in our list if one of the
+            // passed in processes descends from another, or if the same pid is passed twice.
+            auto [it, inserted] = final_pids.insert(pid);
+            if (inserted) {
+                auto it = pid_tree.find(pid);
+                if (it != pid_tree.end()) {
+                    // Add all of the children of |pid| to the list of nodes to visit.
+                    frontier.insert(frontier.end(), it->second.begin(), it->second.end());
+                }
+            }
+        }
+
+        pids = std::move(final_pids);
+    }
+
     if (reset_wss) {
-        if (!read_all_pids(&pids,
-                           [&](pid_t pid) -> bool { return ProcMemInfo::ResetWorkingSet(pid); })) {
-            std::cerr << "Failed to reset working set of all processes" << std::endl;
-            exit(EXIT_FAILURE);
+        for (pid_t pid : pids) {
+            if (!ProcMemInfo::ResetWorkingSet(pid)) {
+                std::cerr << "Failed to reset working set of all processes" << std::endl;
+                exit(EXIT_FAILURE);
+            }
         }
         // we are done, all other options passed to procrank are ignored in the presence of '-W'
         return 0;
@@ -456,42 +514,35 @@
         }
     }
 
-    auto mark_swap_usage = [&](pid_t pid) -> bool {
+    // Mark each swap offset used by the process as we find them for calculating proportional
+    // swap usage later.
+    for (pid_t pid : pids) {
         ProcessRecord proc(pid, show_wss, pgflags, pgflags_mask);
         if (!proc.valid()) {
             // Check to see if the process is still around, skip the process if the proc
             // directory is inaccessible. It was most likely killed while creating the process
             // record
             std::string procdir = ::android::base::StringPrintf("/proc/%d", pid);
-            if (access(procdir.c_str(), F_OK | R_OK)) return true;
+            if (access(procdir.c_str(), F_OK | R_OK)) continue;
 
             // Warn if we failed to gather process stats even while it is still alive.
             // Return success here, so we continue to print stats for other processes.
             std::cerr << "warning: failed to create process record for: " << pid << std::endl;
-            return true;
+            continue;
         }
 
         // Skip processes with no memory mappings
         uint64_t vss = show_wss ? proc.Wss().vss : proc.Usage().vss;
-        if (vss == 0) return true;
+        if (vss == 0) continue;
 
         // collect swap_offset counts from all processes in 1st pass
-        if (!show_wss && has_swap &&
-            !count_swap_offsets(proc, swap_offset_array)) {
+        if (!show_wss && has_swap && !count_swap_offsets(proc, swap_offset_array)) {
             std::cerr << "Failed to count swap offsets for process: " << pid << std::endl;
-            return false;
+            std::cerr << "Failed to read all pids from the system" << std::endl;
+            exit(EXIT_FAILURE);
         }
 
         procs.emplace_back(std::move(proc));
-        return true;
-    };
-
-    // Get a list of all pids currently running in the system in 1st pass through all processes.
-    // Mark each swap offset used by the process as we find them for calculating proportional
-    // swap usage later.
-    if (!read_all_pids(&pids, mark_swap_usage)) {
-        std::cerr << "Failed to read all pids from the system" << std::endl;
-        exit(EXIT_FAILURE);
     }
 
     std::stringstream ss;
diff --git a/tools/showmap.cpp b/tools/showmap.cpp
index 36739b1..452e895 100644
--- a/tools/showmap.cpp
+++ b/tools/showmap.cpp
@@ -16,10 +16,10 @@
 
 #include <getopt.h>
 #include <inttypes.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/mman.h>
-#include <sys/signal.h>
 #include <sys/types.h>
 #include <unistd.h>
 
diff --git a/vts/Android.bp b/vts/Android.bp
index 0f514b5..ec7f58a 100644
--- a/vts/Android.bp
+++ b/vts/Android.bp
@@ -34,5 +34,7 @@
     defaults: ["vts_meminfo_defaults"],
     test_suites: ["vts"],
     require_root: true,
-    test_min_api_level: 29,
+    test_options: {
+        min_shipping_api_level: 29,
+    },
 }
diff --git a/vts/vts_meminfo_test.cpp b/vts/vts_meminfo_test.cpp
index a9b2c26..cec46d5 100644
--- a/vts/vts_meminfo_test.cpp
+++ b/vts/vts_meminfo_test.cpp
@@ -94,7 +94,7 @@
 TEST(SysMemInfo, TestGpuTotalUsageKb) {
     uint64_t size;
 
-    if (android::base::GetIntProperty("ro.product.first_api_level", 0) < __ANDROID_API_S__) {
+    if (android::base::GetIntProperty("ro.vendor.api_level", 0) < __ANDROID_API_S__) {
         GTEST_SKIP();
     }