| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2018 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
| Sandeep Patil | fa2d8d5 | 2018-12-29 21:05:38 -0800 | [diff] [blame] | 17 | #include <meminfo/procmeminfo.h> | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 18 | #include <meminfo/sysmeminfo.h> | 
|  | 19 |  | 
|  | 20 | #include <fcntl.h> | 
| Sandeep Patil | 70fa72d | 2018-11-09 19:18:29 -0800 | [diff] [blame] | 21 | #include <inttypes.h> | 
|  | 22 | #include <stdio.h> | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 23 | #include <sys/stat.h> | 
|  | 24 | #include <sys/types.h> | 
|  | 25 |  | 
|  | 26 | #include <string> | 
|  | 27 |  | 
|  | 28 | #include <android-base/file.h> | 
|  | 29 | #include <android-base/logging.h> | 
| Sandeep Patil | c24f1e3 | 2018-12-29 14:34:20 -0800 | [diff] [blame] | 30 | #include <android-base/stringprintf.h> | 
|  | 31 | #include <android-base/unique_fd.h> | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 32 |  | 
|  | 33 | #include <benchmark/benchmark.h> | 
|  | 34 |  | 
| Sandeep Patil | fa2d8d5 | 2018-12-29 21:05:38 -0800 | [diff] [blame] | 35 | using ::android::meminfo::MemUsage; | 
|  | 36 | using ::android::meminfo::ProcMemInfo; | 
|  | 37 | using ::android::meminfo::SmapsOrRollupFromFile; | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 38 | using ::android::meminfo::SysMemInfo; | 
|  | 39 |  | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 40 | enum { | 
|  | 41 | MEMINFO_TOTAL, | 
|  | 42 | MEMINFO_FREE, | 
|  | 43 | MEMINFO_BUFFERS, | 
|  | 44 | MEMINFO_CACHED, | 
|  | 45 | MEMINFO_SHMEM, | 
|  | 46 | MEMINFO_SLAB, | 
|  | 47 | MEMINFO_SLAB_RECLAIMABLE, | 
|  | 48 | MEMINFO_SLAB_UNRECLAIMABLE, | 
|  | 49 | MEMINFO_SWAP_TOTAL, | 
|  | 50 | MEMINFO_SWAP_FREE, | 
|  | 51 | MEMINFO_ZRAM_TOTAL, | 
|  | 52 | MEMINFO_MAPPED, | 
|  | 53 | MEMINFO_VMALLOC_USED, | 
|  | 54 | MEMINFO_PAGE_TABLES, | 
|  | 55 | MEMINFO_KERNEL_STACK, | 
|  | 56 | MEMINFO_COUNT | 
|  | 57 | }; | 
|  | 58 |  | 
| Sandeep Patil | 70fa72d | 2018-11-09 19:18:29 -0800 | [diff] [blame] | 59 | static void get_mem_info(uint64_t mem[], const char* file) { | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 60 | char buffer[4096]; | 
|  | 61 | unsigned int numFound = 0; | 
|  | 62 |  | 
|  | 63 | int fd = open(file, O_RDONLY); | 
|  | 64 |  | 
|  | 65 | if (fd < 0) { | 
|  | 66 | printf("Unable to open %s: %s\n", file, strerror(errno)); | 
|  | 67 | return; | 
|  | 68 | } | 
|  | 69 |  | 
|  | 70 | const int len = read(fd, buffer, sizeof(buffer) - 1); | 
|  | 71 | close(fd); | 
|  | 72 |  | 
|  | 73 | if (len < 0) { | 
|  | 74 | printf("Empty %s\n", file); | 
|  | 75 | return; | 
|  | 76 | } | 
|  | 77 | buffer[len] = 0; | 
|  | 78 |  | 
|  | 79 | static const char* const tags[] = { | 
| Sandeep Patil | 70fa72d | 2018-11-09 19:18:29 -0800 | [diff] [blame] | 80 | "MemTotal:",     "MemFree:",    "Buffers:",     "Cached:",   "Shmem:", "Slab:", | 
|  | 81 | "SReclaimable:", "SUnreclaim:", "SwapTotal:",   "SwapFree:", "ZRam:",  "Mapped:", | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 82 | "VmallocUsed:",  "PageTables:", "KernelStack:", NULL}; | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 83 |  | 
|  | 84 | static const int tagsLen[] = {9, 8, 8, 7, 6, 5, 13, 11, 10, 9, 5, 7, 12, 11, 12, 0}; | 
|  | 85 |  | 
|  | 86 | memset(mem, 0, sizeof(uint64_t) * 15); | 
|  | 87 | char* p = buffer; | 
|  | 88 | while (*p && (numFound < (sizeof(tagsLen) / sizeof(tagsLen[0])))) { | 
|  | 89 | int i = 0; | 
|  | 90 | while (tags[i]) { | 
| Sandeep Patil | 70fa72d | 2018-11-09 19:18:29 -0800 | [diff] [blame] | 91 | // std::cout << "tag =" << tags[i] << " p = " << std::string(p, tagsLen[i]) << | 
|  | 92 | // std::endl; | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 93 | if (strncmp(p, tags[i], tagsLen[i]) == 0) { | 
|  | 94 | p += tagsLen[i]; | 
|  | 95 | while (*p == ' ') p++; | 
|  | 96 | char* num = p; | 
|  | 97 | while (*p >= '0' && *p <= '9') p++; | 
|  | 98 | if (*p != 0) { | 
|  | 99 | *p = 0; | 
|  | 100 | p++; | 
|  | 101 | } | 
|  | 102 | mem[i] = atoll(num); | 
|  | 103 | numFound++; | 
|  | 104 | break; | 
|  | 105 | } | 
|  | 106 | i++; | 
|  | 107 | } | 
|  | 108 | while (*p && *p != '\n') { | 
|  | 109 | p++; | 
|  | 110 | } | 
|  | 111 | if (*p) p++; | 
|  | 112 | } | 
|  | 113 | } | 
|  | 114 |  | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 115 | static void BM_ReadMemInfo_old(benchmark::State& state) { | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 116 | std::string meminfo = R"meminfo(MemTotal:        3019740 kB | 
|  | 117 | MemFree:         1809728 kB | 
|  | 118 | MemAvailable:    2546560 kB | 
|  | 119 | Buffers:           54736 kB | 
|  | 120 | Cached:           776052 kB | 
|  | 121 | SwapCached:            0 kB | 
|  | 122 | Active:           445856 kB | 
|  | 123 | Inactive:         459092 kB | 
|  | 124 | Active(anon):      78492 kB | 
|  | 125 | Inactive(anon):     2240 kB | 
|  | 126 | Active(file):     367364 kB | 
|  | 127 | Inactive(file):   456852 kB | 
|  | 128 | Unevictable:        3096 kB | 
|  | 129 | Mlocked:            3096 kB | 
|  | 130 | SwapTotal:             0 kB | 
|  | 131 | SwapFree:              0 kB | 
|  | 132 | Dirty:                32 kB | 
|  | 133 | Writeback:             0 kB | 
|  | 134 | AnonPages:         74988 kB | 
|  | 135 | Mapped:            62624 kB | 
|  | 136 | Shmem:              4020 kB | 
|  | 137 | Slab:              86464 kB | 
|  | 138 | SReclaimable:      44432 kB | 
|  | 139 | SUnreclaim:        42032 kB | 
|  | 140 | KernelStack:        4880 kB | 
|  | 141 | PageTables:         2900 kB | 
|  | 142 | NFS_Unstable:          0 kB | 
|  | 143 | Bounce:                0 kB | 
|  | 144 | WritebackTmp:          0 kB | 
|  | 145 | CommitLimit:     1509868 kB | 
|  | 146 | Committed_AS:      80296 kB | 
|  | 147 | VmallocTotal:   263061440 kB | 
|  | 148 | VmallocUsed:           0 kB | 
|  | 149 | VmallocChunk:          0 kB | 
|  | 150 | AnonHugePages:      6144 kB | 
|  | 151 | ShmemHugePages:        0 kB | 
|  | 152 | ShmemPmdMapped:        0 kB | 
|  | 153 | CmaTotal:         131072 kB | 
|  | 154 | CmaFree:          130380 kB | 
|  | 155 | HugePages_Total:       0 | 
|  | 156 | HugePages_Free:        0 | 
|  | 157 | HugePages_Rsvd:        0 | 
|  | 158 | HugePages_Surp:        0 | 
|  | 159 | Hugepagesize:       2048 kB)meminfo"; | 
|  | 160 |  | 
|  | 161 | TemporaryFile tf; | 
|  | 162 | ::android::base::WriteStringToFd(meminfo, tf.fd); | 
|  | 163 |  | 
|  | 164 | uint64_t mem[MEMINFO_COUNT]; | 
|  | 165 | for (auto _ : state) { | 
|  | 166 | get_mem_info(mem, tf.path); | 
|  | 167 | } | 
|  | 168 | } | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 169 | BENCHMARK(BM_ReadMemInfo_old); | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 170 |  | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 171 | static void BM_ReadMemInfo_new(benchmark::State& state) { | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 172 | std::string meminfo = R"meminfo(MemTotal:        3019740 kB | 
|  | 173 | MemFree:         1809728 kB | 
|  | 174 | MemAvailable:    2546560 kB | 
|  | 175 | Buffers:           54736 kB | 
|  | 176 | Cached:           776052 kB | 
|  | 177 | SwapCached:            0 kB | 
|  | 178 | Active:           445856 kB | 
|  | 179 | Inactive:         459092 kB | 
|  | 180 | Active(anon):      78492 kB | 
|  | 181 | Inactive(anon):     2240 kB | 
|  | 182 | Active(file):     367364 kB | 
|  | 183 | Inactive(file):   456852 kB | 
|  | 184 | Unevictable:        3096 kB | 
|  | 185 | Mlocked:            3096 kB | 
|  | 186 | SwapTotal:             0 kB | 
|  | 187 | SwapFree:              0 kB | 
|  | 188 | Dirty:                32 kB | 
|  | 189 | Writeback:             0 kB | 
|  | 190 | AnonPages:         74988 kB | 
|  | 191 | Mapped:            62624 kB | 
|  | 192 | Shmem:              4020 kB | 
|  | 193 | Slab:              86464 kB | 
|  | 194 | SReclaimable:      44432 kB | 
|  | 195 | SUnreclaim:        42032 kB | 
|  | 196 | KernelStack:        4880 kB | 
|  | 197 | PageTables:         2900 kB | 
|  | 198 | NFS_Unstable:          0 kB | 
|  | 199 | Bounce:                0 kB | 
|  | 200 | WritebackTmp:          0 kB | 
|  | 201 | CommitLimit:     1509868 kB | 
|  | 202 | Committed_AS:      80296 kB | 
|  | 203 | VmallocTotal:   263061440 kB | 
|  | 204 | VmallocUsed:           0 kB | 
|  | 205 | VmallocChunk:          0 kB | 
|  | 206 | AnonHugePages:      6144 kB | 
|  | 207 | ShmemHugePages:        0 kB | 
|  | 208 | ShmemPmdMapped:        0 kB | 
|  | 209 | CmaTotal:         131072 kB | 
|  | 210 | CmaFree:          130380 kB | 
|  | 211 | HugePages_Total:       0 | 
|  | 212 | HugePages_Free:        0 | 
|  | 213 | HugePages_Rsvd:        0 | 
|  | 214 | HugePages_Surp:        0 | 
|  | 215 | Hugepagesize:       2048 kB)meminfo"; | 
|  | 216 |  | 
|  | 217 | TemporaryFile tf; | 
|  | 218 | android::base::WriteStringToFd(meminfo, tf.fd); | 
|  | 219 |  | 
|  | 220 | std::string file = std::string(tf.path); | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 221 | std::vector<uint64_t> mem(MEMINFO_COUNT); | 
|  | 222 | const std::vector<std::string> tags = { | 
|  | 223 | SysMemInfo::kMemTotal,      SysMemInfo::kMemFree,        SysMemInfo::kMemBuffers, | 
|  | 224 | SysMemInfo::kMemCached,     SysMemInfo::kMemShmem,       SysMemInfo::kMemSlab, | 
|  | 225 | SysMemInfo::kMemSReclaim,   SysMemInfo::kMemSUnreclaim,  SysMemInfo::kMemSwapTotal, | 
|  | 226 | SysMemInfo::kMemSwapFree,   SysMemInfo::kMemMapped,      SysMemInfo::kMemVmallocUsed, | 
|  | 227 | SysMemInfo::kMemPageTables, SysMemInfo::kMemKernelStack, | 
|  | 228 | }; | 
|  | 229 |  | 
|  | 230 | SysMemInfo smi; | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 231 | for (auto _ : state) { | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 232 | smi.ReadMemInfo(tags, &mem, file); | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 233 | } | 
|  | 234 | } | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 235 | BENCHMARK(BM_ReadMemInfo_new); | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 236 |  | 
| Sandeep Patil | 70fa72d | 2018-11-09 19:18:29 -0800 | [diff] [blame] | 237 | static uint64_t get_zram_mem_used(const std::string& zram_dir) { | 
|  | 238 | FILE* f = fopen((zram_dir + "mm_stat").c_str(), "r"); | 
|  | 239 | if (f) { | 
|  | 240 | uint64_t mem_used_total = 0; | 
|  | 241 |  | 
|  | 242 | int matched = fscanf(f, "%*d %*d %" SCNu64 " %*d %*d %*d %*d", &mem_used_total); | 
|  | 243 | if (matched != 1) | 
|  | 244 | fprintf(stderr, "warning: failed to parse %s\n", (zram_dir + "mm_stat").c_str()); | 
|  | 245 |  | 
|  | 246 | fclose(f); | 
|  | 247 | return mem_used_total; | 
|  | 248 | } | 
|  | 249 |  | 
|  | 250 | f = fopen((zram_dir + "mem_used_total").c_str(), "r"); | 
|  | 251 | if (f) { | 
|  | 252 | uint64_t mem_used_total = 0; | 
|  | 253 |  | 
|  | 254 | int matched = fscanf(f, "%" SCNu64, &mem_used_total); | 
|  | 255 | if (matched != 1) | 
|  | 256 | fprintf(stderr, "warning: failed to parse %s\n", (zram_dir + "mem_used_total").c_str()); | 
|  | 257 |  | 
|  | 258 | fclose(f); | 
|  | 259 | return mem_used_total; | 
|  | 260 | } | 
|  | 261 |  | 
|  | 262 | return 0; | 
|  | 263 | } | 
|  | 264 |  | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 265 | static void BM_ZramTotal_old(benchmark::State& state) { | 
| Sandeep Patil | 70fa72d | 2018-11-09 19:18:29 -0800 | [diff] [blame] | 266 | std::string exec_dir = ::android::base::GetExecutableDirectory(); | 
|  | 267 | std::string zram_mmstat_dir = exec_dir + "/testdata1/"; | 
|  | 268 | for (auto _ : state) { | 
|  | 269 | uint64_t zram_total __attribute__((unused)) = get_zram_mem_used(zram_mmstat_dir) / 1024; | 
|  | 270 | } | 
|  | 271 | } | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 272 | BENCHMARK(BM_ZramTotal_old); | 
| Sandeep Patil | 70fa72d | 2018-11-09 19:18:29 -0800 | [diff] [blame] | 273 |  | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 274 | static void BM_ZramTotal_new(benchmark::State& state) { | 
| Sandeep Patil | 70fa72d | 2018-11-09 19:18:29 -0800 | [diff] [blame] | 275 | std::string exec_dir = ::android::base::GetExecutableDirectory(); | 
|  | 276 | std::string zram_mmstat_dir = exec_dir + "/testdata1/"; | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 277 | SysMemInfo smi; | 
| Sandeep Patil | 70fa72d | 2018-11-09 19:18:29 -0800 | [diff] [blame] | 278 | for (auto _ : state) { | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 279 | uint64_t zram_total __attribute__((unused)) = smi.mem_zram_kb(zram_mmstat_dir); | 
| Sandeep Patil | 70fa72d | 2018-11-09 19:18:29 -0800 | [diff] [blame] | 280 | } | 
|  | 281 | } | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 282 | BENCHMARK(BM_ZramTotal_new); | 
|  | 283 |  | 
|  | 284 | static void BM_MemInfoWithZram_old(benchmark::State& state) { | 
|  | 285 | std::string meminfo = R"meminfo(MemTotal:        3019740 kB | 
|  | 286 | MemFree:         1809728 kB | 
|  | 287 | MemAvailable:    2546560 kB | 
|  | 288 | Buffers:           54736 kB | 
|  | 289 | Cached:           776052 kB | 
|  | 290 | SwapCached:            0 kB | 
|  | 291 | Active:           445856 kB | 
|  | 292 | Inactive:         459092 kB | 
|  | 293 | Active(anon):      78492 kB | 
|  | 294 | Inactive(anon):     2240 kB | 
|  | 295 | Active(file):     367364 kB | 
|  | 296 | Inactive(file):   456852 kB | 
|  | 297 | Unevictable:        3096 kB | 
|  | 298 | Mlocked:            3096 kB | 
|  | 299 | SwapTotal:             0 kB | 
|  | 300 | SwapFree:              0 kB | 
|  | 301 | Dirty:                32 kB | 
|  | 302 | Writeback:             0 kB | 
|  | 303 | AnonPages:         74988 kB | 
|  | 304 | Mapped:            62624 kB | 
|  | 305 | Shmem:              4020 kB | 
|  | 306 | Slab:              86464 kB | 
|  | 307 | SReclaimable:      44432 kB | 
|  | 308 | SUnreclaim:        42032 kB | 
|  | 309 | KernelStack:        4880 kB | 
|  | 310 | PageTables:         2900 kB | 
|  | 311 | NFS_Unstable:          0 kB | 
|  | 312 | Bounce:                0 kB | 
|  | 313 | WritebackTmp:          0 kB | 
|  | 314 | CommitLimit:     1509868 kB | 
|  | 315 | Committed_AS:      80296 kB | 
|  | 316 | VmallocTotal:   263061440 kB | 
|  | 317 | VmallocUsed:           0 kB | 
|  | 318 | VmallocChunk:          0 kB | 
|  | 319 | AnonHugePages:      6144 kB | 
|  | 320 | ShmemHugePages:        0 kB | 
|  | 321 | ShmemPmdMapped:        0 kB | 
|  | 322 | CmaTotal:         131072 kB | 
|  | 323 | CmaFree:          130380 kB | 
|  | 324 | HugePages_Total:       0 | 
|  | 325 | HugePages_Free:        0 | 
|  | 326 | HugePages_Rsvd:        0 | 
|  | 327 | HugePages_Surp:        0 | 
|  | 328 | Hugepagesize:       2048 kB)meminfo"; | 
|  | 329 |  | 
|  | 330 | TemporaryFile tf; | 
|  | 331 | ::android::base::WriteStringToFd(meminfo, tf.fd); | 
|  | 332 | std::string exec_dir = ::android::base::GetExecutableDirectory(); | 
|  | 333 | std::string zram_mmstat_dir = exec_dir + "/testdata1/"; | 
|  | 334 | uint64_t mem[MEMINFO_COUNT]; | 
|  | 335 | for (auto _ : state) { | 
|  | 336 | get_mem_info(mem, tf.path); | 
|  | 337 | mem[MEMINFO_ZRAM_TOTAL] = get_zram_mem_used("/sys/block/zram0/") / 1024; | 
|  | 338 | CHECK_EQ(mem[MEMINFO_KERNEL_STACK], 4880u); | 
|  | 339 | } | 
|  | 340 | } | 
|  | 341 | BENCHMARK(BM_MemInfoWithZram_old); | 
|  | 342 |  | 
|  | 343 | static void BM_MemInfoWithZram_new(benchmark::State& state) { | 
|  | 344 | std::string meminfo = R"meminfo(MemTotal:        3019740 kB | 
|  | 345 | MemFree:         1809728 kB | 
|  | 346 | MemAvailable:    2546560 kB | 
|  | 347 | Buffers:           54736 kB | 
|  | 348 | Cached:           776052 kB | 
|  | 349 | SwapCached:            0 kB | 
|  | 350 | Active:           445856 kB | 
|  | 351 | Inactive:         459092 kB | 
|  | 352 | Active(anon):      78492 kB | 
|  | 353 | Inactive(anon):     2240 kB | 
|  | 354 | Active(file):     367364 kB | 
|  | 355 | Inactive(file):   456852 kB | 
|  | 356 | Unevictable:        3096 kB | 
|  | 357 | Mlocked:            3096 kB | 
|  | 358 | SwapTotal:             0 kB | 
|  | 359 | SwapFree:              0 kB | 
|  | 360 | Dirty:                32 kB | 
|  | 361 | Writeback:             0 kB | 
|  | 362 | AnonPages:         74988 kB | 
|  | 363 | Mapped:            62624 kB | 
|  | 364 | Shmem:              4020 kB | 
|  | 365 | Slab:              86464 kB | 
|  | 366 | SReclaimable:      44432 kB | 
|  | 367 | SUnreclaim:        42032 kB | 
|  | 368 | KernelStack:        4880 kB | 
|  | 369 | PageTables:         2900 kB | 
|  | 370 | NFS_Unstable:          0 kB | 
|  | 371 | Bounce:                0 kB | 
|  | 372 | WritebackTmp:          0 kB | 
|  | 373 | CommitLimit:     1509868 kB | 
|  | 374 | Committed_AS:      80296 kB | 
|  | 375 | VmallocTotal:   263061440 kB | 
|  | 376 | VmallocUsed:           0 kB | 
|  | 377 | VmallocChunk:          0 kB | 
|  | 378 | AnonHugePages:      6144 kB | 
|  | 379 | ShmemHugePages:        0 kB | 
|  | 380 | ShmemPmdMapped:        0 kB | 
|  | 381 | CmaTotal:         131072 kB | 
|  | 382 | CmaFree:          130380 kB | 
|  | 383 | HugePages_Total:       0 | 
|  | 384 | HugePages_Free:        0 | 
|  | 385 | HugePages_Rsvd:        0 | 
|  | 386 | HugePages_Surp:        0 | 
|  | 387 | Hugepagesize:       2048 kB)meminfo"; | 
|  | 388 |  | 
|  | 389 | TemporaryFile tf; | 
|  | 390 | android::base::WriteStringToFd(meminfo, tf.fd); | 
|  | 391 |  | 
|  | 392 | std::string file = std::string(tf.path); | 
|  | 393 | std::vector<uint64_t> mem(MEMINFO_COUNT); | 
|  | 394 | std::vector<std::string> tags(SysMemInfo::kDefaultSysMemInfoTags); | 
|  | 395 | auto it = tags.begin(); | 
|  | 396 | tags.insert(it + MEMINFO_ZRAM_TOTAL, "Zram:"); | 
|  | 397 | SysMemInfo smi; | 
|  | 398 |  | 
|  | 399 | for (auto _ : state) { | 
|  | 400 | smi.ReadMemInfo(tags, &mem, file); | 
|  | 401 | CHECK_EQ(mem[MEMINFO_KERNEL_STACK], 4880u); | 
|  | 402 | } | 
|  | 403 | } | 
|  | 404 | BENCHMARK(BM_MemInfoWithZram_new); | 
| Sandeep Patil | 70fa72d | 2018-11-09 19:18:29 -0800 | [diff] [blame] | 405 |  | 
| Sandeep Patil | c24f1e3 | 2018-12-29 14:34:20 -0800 | [diff] [blame] | 406 | // Current implementation is in frameworks/base/core/jni/android_os_Debug.cpp. | 
|  | 407 | // That implementation is still buggy and it skips over vmalloc allocated memory by kernel modules. | 
|  | 408 | // This is the *fixed* version of the same implementation intended for benchmarking against the new | 
|  | 409 | // one. | 
|  | 410 | static uint64_t get_allocated_vmalloc_memory(const std::string& vm_file) { | 
|  | 411 | char line[1024]; | 
|  | 412 |  | 
|  | 413 | uint64_t vmalloc_allocated_size = 0; | 
|  | 414 | auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(vm_file.c_str(), "re"), fclose}; | 
|  | 415 | if (fp == nullptr) { | 
|  | 416 | return 0; | 
|  | 417 | } | 
|  | 418 |  | 
|  | 419 | while (true) { | 
|  | 420 | if (fgets(line, 1024, fp.get()) == NULL) { | 
|  | 421 | break; | 
|  | 422 | } | 
|  | 423 |  | 
|  | 424 | // check to see if there are pages mapped in vmalloc area | 
|  | 425 | if (!strstr(line, "pages=")) { | 
|  | 426 | continue; | 
|  | 427 | } | 
|  | 428 |  | 
|  | 429 | long nr_pages; | 
|  | 430 | if (sscanf(line, "%*x-%*x %*ld %*s pages=%ld", &nr_pages) == 1) { | 
|  | 431 | vmalloc_allocated_size += (nr_pages * getpagesize()); | 
|  | 432 | } else if (sscanf(line, "%*x-%*x %*ld %*s %*s pages=%ld", &nr_pages) == 1) { | 
|  | 433 | // The second case is for kernel modules. If allocation comes from the module, | 
|  | 434 | // kernel puts an extra string containing the module name before "pages=" in | 
|  | 435 | // the line. | 
|  | 436 | //    See: https://elixir.bootlin.com/linux/latest/source/kernel/kallsyms.c#L373 | 
|  | 437 | vmalloc_allocated_size += (nr_pages * getpagesize()); | 
|  | 438 | } | 
|  | 439 | } | 
|  | 440 | return vmalloc_allocated_size; | 
|  | 441 | } | 
|  | 442 |  | 
|  | 443 | static void BM_VmallocInfo_old_fixed(benchmark::State& state) { | 
|  | 444 | std::string exec_dir = ::android::base::GetExecutableDirectory(); | 
|  | 445 | std::string vmallocinfo = | 
|  | 446 | ::android::base::StringPrintf("%s/testdata1/vmallocinfo", exec_dir.c_str()); | 
|  | 447 | for (auto _ : state) { | 
|  | 448 | CHECK_EQ(get_allocated_vmalloc_memory(vmallocinfo), 29884416); | 
|  | 449 | } | 
|  | 450 | } | 
|  | 451 | BENCHMARK(BM_VmallocInfo_old_fixed); | 
|  | 452 |  | 
|  | 453 | static void BM_VmallocInfo_new(benchmark::State& state) { | 
|  | 454 | std::string exec_dir = ::android::base::GetExecutableDirectory(); | 
|  | 455 | std::string vmallocinfo = | 
|  | 456 | ::android::base::StringPrintf("%s/testdata1/vmallocinfo", exec_dir.c_str()); | 
|  | 457 | for (auto _ : state) { | 
| Sandeep Patil | e04680d | 2019-01-19 12:04:18 -0800 | [diff] [blame] | 458 | CHECK_EQ(::android::meminfo::ReadVmallocInfo(vmallocinfo), 29884416); | 
| Sandeep Patil | c24f1e3 | 2018-12-29 14:34:20 -0800 | [diff] [blame] | 459 | } | 
|  | 460 | } | 
|  | 461 | BENCHMARK(BM_VmallocInfo_new); | 
|  | 462 |  | 
| Sandeep Patil | fa2d8d5 | 2018-12-29 21:05:38 -0800 | [diff] [blame] | 463 | // This implementation is picked up as-is from frameworks/base/core/jni/android_os_Debug.cpp | 
|  | 464 | // and only slightly modified to use std:unique_ptr. | 
|  | 465 | static bool get_smaps_rollup(const std::string path, MemUsage* rollup) { | 
|  | 466 | char lineBuffer[1024]; | 
|  | 467 | auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose}; | 
|  | 468 | if (fp != nullptr) { | 
|  | 469 | char* line; | 
|  | 470 | while (true) { | 
|  | 471 | if (fgets(lineBuffer, sizeof(lineBuffer), fp.get()) == NULL) { | 
|  | 472 | break; | 
|  | 473 | } | 
|  | 474 | line = lineBuffer; | 
|  | 475 |  | 
|  | 476 | switch (line[0]) { | 
|  | 477 | case 'P': | 
|  | 478 | if (strncmp(line, "Pss:", 4) == 0) { | 
|  | 479 | char* c = line + 4; | 
|  | 480 | while (*c != 0 && (*c < '0' || *c > '9')) { | 
|  | 481 | c++; | 
|  | 482 | } | 
|  | 483 | rollup->pss += atoi(c); | 
|  | 484 | } else if (strncmp(line, "Private_Clean:", 14) == 0 || | 
|  | 485 | strncmp(line, "Private_Dirty:", 14) == 0) { | 
|  | 486 | char* c = line + 14; | 
|  | 487 | while (*c != 0 && (*c < '0' || *c > '9')) { | 
|  | 488 | c++; | 
|  | 489 | } | 
|  | 490 | rollup->uss += atoi(c); | 
|  | 491 | } | 
|  | 492 | break; | 
|  | 493 | case 'R': | 
|  | 494 | if (strncmp(line, "Rss:", 4) == 0) { | 
|  | 495 | char* c = line + 4; | 
|  | 496 | while (*c != 0 && (*c < '0' || *c > '9')) { | 
|  | 497 | c++; | 
|  | 498 | } | 
|  | 499 | rollup->rss += atoi(c); | 
|  | 500 | } | 
|  | 501 | break; | 
|  | 502 | case 'S': | 
|  | 503 | if (strncmp(line, "SwapPss:", 8) == 0) { | 
|  | 504 | char* c = line + 8; | 
|  | 505 | long lSwapPss; | 
|  | 506 | while (*c != 0 && (*c < '0' || *c > '9')) { | 
|  | 507 | c++; | 
|  | 508 | } | 
|  | 509 | lSwapPss = atoi(c); | 
|  | 510 | rollup->swap_pss += lSwapPss; | 
|  | 511 | } | 
|  | 512 | break; | 
|  | 513 | } | 
|  | 514 | } | 
|  | 515 | } else { | 
|  | 516 | return false; | 
|  | 517 | } | 
|  | 518 |  | 
|  | 519 | return true; | 
|  | 520 | } | 
|  | 521 |  | 
|  | 522 | static void BM_SmapsRollup_old(benchmark::State& state) { | 
|  | 523 | std::string exec_dir = ::android::base::GetExecutableDirectory(); | 
|  | 524 | std::string path = ::android::base::StringPrintf("%s/testdata1/smaps", exec_dir.c_str()); | 
|  | 525 | for (auto _ : state) { | 
|  | 526 | MemUsage stats; | 
|  | 527 | CHECK_EQ(get_smaps_rollup(path, &stats), true); | 
|  | 528 | CHECK_EQ(stats.pss, 108384); | 
|  | 529 | } | 
|  | 530 | } | 
|  | 531 | BENCHMARK(BM_SmapsRollup_old); | 
|  | 532 |  | 
|  | 533 | static void BM_SmapsRollup_new(benchmark::State& state) { | 
|  | 534 | std::string exec_dir = ::android::base::GetExecutableDirectory(); | 
|  | 535 | std::string path = ::android::base::StringPrintf("%s/testdata1/smaps", exec_dir.c_str()); | 
|  | 536 | for (auto _ : state) { | 
|  | 537 | MemUsage stats; | 
|  | 538 | CHECK_EQ(SmapsOrRollupFromFile(path, &stats), true); | 
|  | 539 | CHECK_EQ(stats.pss, 108384); | 
|  | 540 | } | 
|  | 541 | } | 
|  | 542 | BENCHMARK(BM_SmapsRollup_new); | 
|  | 543 |  | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 544 | BENCHMARK_MAIN(); |