Loading libmeminfo/include/meminfo/sysmeminfo.h +6 −1 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ class SysMemInfo final { // in vmalloc area by the kernel. // Note that this deliberately ignores binder buffers. They are _always_ // mapped in a process and are counted for in each process. uint64_t ReadVmallocInfo(const std::string& path = "/proc/vmallocinfo"); uint64_t ReadVmallocInfo(); // getters uint64_t mem_total_kb() { return mem_in_kb_[kMemTotal]; } Loading @@ -84,5 +84,10 @@ class SysMemInfo final { std::function<void(const std::string&, uint64_t)> store_val); }; // Parse /proc/vmallocinfo and return total physical memory mapped // in vmalloc area by the kernel. Note that this deliberately ignores binder buffers. They are // _always_ mapped in a process and are counted for in each process. uint64_t ReadVmallocInfo(const std::string& path = "/proc/vmallocinfo"); } // namespace meminfo } // namespace android libmeminfo/libmeminfo_benchmark.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -455,8 +455,7 @@ static void BM_VmallocInfo_new(benchmark::State& state) { std::string vmallocinfo = ::android::base::StringPrintf("%s/testdata1/vmallocinfo", exec_dir.c_str()); for (auto _ : state) { SysMemInfo smi; CHECK_EQ(smi.ReadVmallocInfo(vmallocinfo), 29884416); CHECK_EQ(::android::meminfo::ReadVmallocInfo(vmallocinfo), 29884416); } } BENCHMARK(BM_VmallocInfo_new); Loading libmeminfo/libmeminfo_test.cpp +4 −8 Original line number Diff line number Diff line Loading @@ -861,8 +861,7 @@ TEST(SysMemInfoParser, TestVmallocInfoNoMemory) { ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd)); std::string file = std::string(tf.path); SysMemInfo smi; EXPECT_EQ(smi.ReadVmallocInfo(file), 0); EXPECT_EQ(ReadVmallocInfo(file), 0); } TEST(SysMemInfoParser, TestVmallocInfoKernel) { Loading @@ -874,8 +873,7 @@ TEST(SysMemInfoParser, TestVmallocInfoKernel) { ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd)); std::string file = std::string(tf.path); SysMemInfo smi; EXPECT_EQ(smi.ReadVmallocInfo(file), getpagesize()); EXPECT_EQ(ReadVmallocInfo(file), getpagesize()); } TEST(SysMemInfoParser, TestVmallocInfoModule) { Loading @@ -887,8 +885,7 @@ TEST(SysMemInfoParser, TestVmallocInfoModule) { ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd)); std::string file = std::string(tf.path); SysMemInfo smi; EXPECT_EQ(smi.ReadVmallocInfo(file), 6 * getpagesize()); EXPECT_EQ(ReadVmallocInfo(file), 6 * getpagesize()); } TEST(SysMemInfoParser, TestVmallocInfoAll) { Loading @@ -905,8 +902,7 @@ TEST(SysMemInfoParser, TestVmallocInfoAll) { ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd)); std::string file = std::string(tf.path); SysMemInfo smi; EXPECT_EQ(smi.ReadVmallocInfo(file), 7 * getpagesize()); EXPECT_EQ(ReadVmallocInfo(file), 7 * getpagesize()); } int main(int argc, char** argv) { Loading libmeminfo/sysmeminfo.cpp +38 −30 Original line number Diff line number Diff line Loading @@ -79,36 +79,8 @@ bool SysMemInfo::ReadMemInfo(const std::vector<std::string>& tags, std::vector<u }); } uint64_t SysMemInfo::ReadVmallocInfo(const std::string& path) { uint64_t vmalloc_total = 0; auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose}; if (fp == nullptr) { return vmalloc_total; } char line[1024]; while (fgets(line, 1024, fp.get()) != nullptr) { // We are looking for lines like // 0x0000000000000000-0x0000000000000000 12288 drm_property_create_blob+0x44/0xec pages=2 // vmalloc 0x0000000000000000-0x0000000000000000 8192 // wlan_logging_sock_init_svc+0xf8/0x4f0 [wlan] pages=1 vmalloc Notice that if the caller is // coming from a module, the kernel prints and extra "[module_name]" after the address and // the symbol of the call site. This means we can't use the old sscanf() method of getting // the # of pages. char* p_start = strstr(line, "pages="); if (p_start == nullptr) { // we didn't find anything continue; } p_start = strtok(p_start, " "); long nr_pages; if (sscanf(p_start, "pages=%ld", &nr_pages) == 1) { vmalloc_total += (nr_pages * getpagesize()); } } return vmalloc_total; uint64_t SysMemInfo::ReadVmallocInfo() { return ::android::meminfo::ReadVmallocInfo(); } // TODO: Delete this function if it can't match up with the c-like implementation below. Loading Loading @@ -263,5 +235,41 @@ bool SysMemInfo::MemZramDevice(const std::string& zram_dev, uint64_t* mem_zram_d return false; } // Public methods uint64_t ReadVmallocInfo(const std::string& path) { uint64_t vmalloc_total = 0; auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose}; if (fp == nullptr) { return vmalloc_total; } char* line = nullptr; size_t line_alloc = 0; while (getline(&line, &line_alloc, fp.get()) > 0) { // We are looking for lines like // // 0x0000000000000000-0x0000000000000000 12288 drm_property_create_blob+0x44/0xec pages=2 vmalloc // 0x0000000000000000-0x0000000000000000 8192 wlan_logging_sock_init_svc+0xf8/0x4f0 [wlan] pages=1 vmalloc // // Notice that if the caller is coming from a module, the kernel prints and extra // "[module_name]" after the address and the symbol of the call site. This means we can't // use the old sscanf() method of getting the # of pages. char* p_start = strstr(line, "pages="); if (p_start == nullptr) { // we didn't find anything continue; } uint64_t nr_pages; if (sscanf(p_start, "pages=%" SCNu64 "", &nr_pages) == 1) { vmalloc_total += (nr_pages * getpagesize()); } } free(line); return vmalloc_total; } } // namespace meminfo } // namespace android Loading
libmeminfo/include/meminfo/sysmeminfo.h +6 −1 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ class SysMemInfo final { // in vmalloc area by the kernel. // Note that this deliberately ignores binder buffers. They are _always_ // mapped in a process and are counted for in each process. uint64_t ReadVmallocInfo(const std::string& path = "/proc/vmallocinfo"); uint64_t ReadVmallocInfo(); // getters uint64_t mem_total_kb() { return mem_in_kb_[kMemTotal]; } Loading @@ -84,5 +84,10 @@ class SysMemInfo final { std::function<void(const std::string&, uint64_t)> store_val); }; // Parse /proc/vmallocinfo and return total physical memory mapped // in vmalloc area by the kernel. Note that this deliberately ignores binder buffers. They are // _always_ mapped in a process and are counted for in each process. uint64_t ReadVmallocInfo(const std::string& path = "/proc/vmallocinfo"); } // namespace meminfo } // namespace android
libmeminfo/libmeminfo_benchmark.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -455,8 +455,7 @@ static void BM_VmallocInfo_new(benchmark::State& state) { std::string vmallocinfo = ::android::base::StringPrintf("%s/testdata1/vmallocinfo", exec_dir.c_str()); for (auto _ : state) { SysMemInfo smi; CHECK_EQ(smi.ReadVmallocInfo(vmallocinfo), 29884416); CHECK_EQ(::android::meminfo::ReadVmallocInfo(vmallocinfo), 29884416); } } BENCHMARK(BM_VmallocInfo_new); Loading
libmeminfo/libmeminfo_test.cpp +4 −8 Original line number Diff line number Diff line Loading @@ -861,8 +861,7 @@ TEST(SysMemInfoParser, TestVmallocInfoNoMemory) { ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd)); std::string file = std::string(tf.path); SysMemInfo smi; EXPECT_EQ(smi.ReadVmallocInfo(file), 0); EXPECT_EQ(ReadVmallocInfo(file), 0); } TEST(SysMemInfoParser, TestVmallocInfoKernel) { Loading @@ -874,8 +873,7 @@ TEST(SysMemInfoParser, TestVmallocInfoKernel) { ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd)); std::string file = std::string(tf.path); SysMemInfo smi; EXPECT_EQ(smi.ReadVmallocInfo(file), getpagesize()); EXPECT_EQ(ReadVmallocInfo(file), getpagesize()); } TEST(SysMemInfoParser, TestVmallocInfoModule) { Loading @@ -887,8 +885,7 @@ TEST(SysMemInfoParser, TestVmallocInfoModule) { ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd)); std::string file = std::string(tf.path); SysMemInfo smi; EXPECT_EQ(smi.ReadVmallocInfo(file), 6 * getpagesize()); EXPECT_EQ(ReadVmallocInfo(file), 6 * getpagesize()); } TEST(SysMemInfoParser, TestVmallocInfoAll) { Loading @@ -905,8 +902,7 @@ TEST(SysMemInfoParser, TestVmallocInfoAll) { ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd)); std::string file = std::string(tf.path); SysMemInfo smi; EXPECT_EQ(smi.ReadVmallocInfo(file), 7 * getpagesize()); EXPECT_EQ(ReadVmallocInfo(file), 7 * getpagesize()); } int main(int argc, char** argv) { Loading
libmeminfo/sysmeminfo.cpp +38 −30 Original line number Diff line number Diff line Loading @@ -79,36 +79,8 @@ bool SysMemInfo::ReadMemInfo(const std::vector<std::string>& tags, std::vector<u }); } uint64_t SysMemInfo::ReadVmallocInfo(const std::string& path) { uint64_t vmalloc_total = 0; auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose}; if (fp == nullptr) { return vmalloc_total; } char line[1024]; while (fgets(line, 1024, fp.get()) != nullptr) { // We are looking for lines like // 0x0000000000000000-0x0000000000000000 12288 drm_property_create_blob+0x44/0xec pages=2 // vmalloc 0x0000000000000000-0x0000000000000000 8192 // wlan_logging_sock_init_svc+0xf8/0x4f0 [wlan] pages=1 vmalloc Notice that if the caller is // coming from a module, the kernel prints and extra "[module_name]" after the address and // the symbol of the call site. This means we can't use the old sscanf() method of getting // the # of pages. char* p_start = strstr(line, "pages="); if (p_start == nullptr) { // we didn't find anything continue; } p_start = strtok(p_start, " "); long nr_pages; if (sscanf(p_start, "pages=%ld", &nr_pages) == 1) { vmalloc_total += (nr_pages * getpagesize()); } } return vmalloc_total; uint64_t SysMemInfo::ReadVmallocInfo() { return ::android::meminfo::ReadVmallocInfo(); } // TODO: Delete this function if it can't match up with the c-like implementation below. Loading Loading @@ -263,5 +235,41 @@ bool SysMemInfo::MemZramDevice(const std::string& zram_dev, uint64_t* mem_zram_d return false; } // Public methods uint64_t ReadVmallocInfo(const std::string& path) { uint64_t vmalloc_total = 0; auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose}; if (fp == nullptr) { return vmalloc_total; } char* line = nullptr; size_t line_alloc = 0; while (getline(&line, &line_alloc, fp.get()) > 0) { // We are looking for lines like // // 0x0000000000000000-0x0000000000000000 12288 drm_property_create_blob+0x44/0xec pages=2 vmalloc // 0x0000000000000000-0x0000000000000000 8192 wlan_logging_sock_init_svc+0xf8/0x4f0 [wlan] pages=1 vmalloc // // Notice that if the caller is coming from a module, the kernel prints and extra // "[module_name]" after the address and the symbol of the call site. This means we can't // use the old sscanf() method of getting the # of pages. char* p_start = strstr(line, "pages="); if (p_start == nullptr) { // we didn't find anything continue; } uint64_t nr_pages; if (sscanf(p_start, "pages=%" SCNu64 "", &nr_pages) == 1) { vmalloc_total += (nr_pages * getpagesize()); } } free(line); return vmalloc_total; } } // namespace meminfo } // namespace android