Changeset 258835 in webkit
- Timestamp:
- Mar 23, 2020 6:33:51 AM (4 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r258831 r258835 1 2020-03-23 Pablo Saavedra <psaavedra@igalia.com> 2 3 [GTK][WPE] Check the cgroups memory limits (v1 and v2) to calculate the systemMemoryUsedAsPercentage() in the MemoryPressureMonitor 4 https://bugs.webkit.org/show_bug.cgi?id=209186 5 6 Reviewed by Carlos Alberto Lopez Perez. 7 8 Modifies the systemMemoryUsedAsPercentage() function adding the logic 9 to read the memory limits and the current memory used in the cgroup 10 associated to the WebKit process: 11 12 - memory.memsw.usage_in_bytes (or memory.memsw.max in cgroupV2): 13 current usage for memory+Swap 14 - memory.limit_in_bytes (or memory.current in cgroupV2): 15 limit of memory usage 16 - memory.memsw.limit_in_bytes (or memory.max in cgroupV2): 17 limit of memory+Swap usage 18 19 In case of the WK processes are associated to a cgroup with memory 20 controller, the function reads the memory.limit_in_bytes or 21 the memory.memsw.limit_in_bytes and the and memory.usage_in_bytes 22 from the cgroup mount point and calculates the percentage of 23 memory used. 24 25 In other cases (no cgroup memory controller associated or limits 26 higher than the real memory available), the function will return the 27 percentage based on the real memory available and real total memory 28 in the system. 29 30 The logic supports supports both cgroupV1 and cgroupV2 31 32 * UIProcess/linux/MemoryPressureMonitor.cpp: 33 (WebKit::getMemoryTotalWithCgroup): 34 (WebKit::getMemoryUsageWithCgroup): 35 (WebKit::getCgroupController): 36 (WebKit::systemMemoryUsedAsPercentage): 37 1 38 2020-03-23 Chris Lord <clord@igalia.com> 2 39 -
trunk/Source/WebKit/UIProcess/linux/MemoryPressureMonitor.cpp
r248264 r258835 36 36 #include <wtf/Threading.h> 37 37 #include <wtf/UniStdExtras.h> 38 #include <wtf/text/CString.h> 38 39 39 40 namespace WebKit { … … 47 48 static const int s_memoryPresurePercentageThreshold = 90; 48 49 static const int s_memoryPresurePercentageThresholdCritical = 95; 50 // cgroups.7: The usual place for such mounts is under a tmpfs(5) 51 // filesystem mounted at /sys/fs/cgroup. 52 static const char* s_cgroupMemoryPath = "/sys/fs/cgroup/memory/%s/%s"; 53 static const char* s_cgroupController = "/proc/self/cgroup"; 54 static const unsigned maxCgroupPath = 4096; // PATH_MAX = 4096 from (Linux) include/uapi/linux/limits.h 49 55 50 56 static size_t lowWatermarkPages() … … 127 133 } 128 134 135 size_t getMemoryTotalWithCgroup(CString memoryControllerName) 136 { 137 char buffer[128]; 138 char cgroupPath[maxCgroupPath]; 139 char* token; 140 FILE* file; 141 142 // Check memory limits in cgroupV2 143 snprintf(cgroupPath, maxCgroupPath, s_cgroupMemoryPath, memoryControllerName.data(), "memory.memsw.max"); 144 file = fopen(cgroupPath, "r"); 145 if (file) { 146 token = fgets(buffer, 128, file); 147 fclose(file); 148 return atoll(token); 149 } 150 snprintf(cgroupPath, maxCgroupPath, s_cgroupMemoryPath, memoryControllerName.data(), "memory.max"); 151 file = fopen(cgroupPath, "r"); 152 if (file) { 153 token = fgets(buffer, 128, file); 154 fclose(file); 155 return atoll(token); 156 } 157 158 // Check memory limits in cgroupV1 159 snprintf(cgroupPath, maxCgroupPath, s_cgroupMemoryPath, memoryControllerName.data(), "memory.memsw.limit_in_bytes"); 160 file = fopen(cgroupPath, "r"); 161 if (file) { 162 token = fgets(buffer, 128, file); 163 fclose(file); 164 return atoll(token); 165 } 166 snprintf(cgroupPath, maxCgroupPath, s_cgroupMemoryPath, memoryControllerName.data(), "memory.limit_in_bytes"); 167 file = fopen(cgroupPath, "r"); 168 if (file) { 169 token = fgets(buffer, 128, file); 170 fclose(file); 171 return atoll(token); 172 } 173 return 0; 174 } 175 176 static size_t getMemoryUsageWithCgroup(CString memoryControllerName) 177 { 178 char buffer[128]; 179 char cgroupPath[maxCgroupPath]; 180 char* token; 181 char* line; 182 FILE* fileCgroupPathUsageBytes; 183 184 // Check memory limits in cgroupV2 185 snprintf(cgroupPath, maxCgroupPath, s_cgroupMemoryPath, memoryControllerName.data(), "memory.current"); 186 fileCgroupPathUsageBytes = fopen(cgroupPath, "r"); 187 if (fileCgroupPathUsageBytes) { 188 line = fgets(buffer, 128, fileCgroupPathUsageBytes); 189 token = strtok(line, " "); 190 fclose(fileCgroupPathUsageBytes); 191 return atoll(token); 192 } 193 194 // Check memory limits in cgroupV1 195 snprintf(cgroupPath, maxCgroupPath, s_cgroupMemoryPath, memoryControllerName.data(), "memory.usage_in_bytes"); 196 fileCgroupPathUsageBytes = fopen(cgroupPath, "r"); 197 if (fileCgroupPathUsageBytes) { 198 line = fgets(buffer, 128, fileCgroupPathUsageBytes); 199 token = strtok(line, " "); 200 fclose(fileCgroupPathUsageBytes); 201 return atoll(token); 202 } 203 return 0; 204 } 205 206 // This file describes control groups to which the process with 207 // the corresponding PID belongs. The displayed information differs 208 // for cgroups version 1 and version 2 hierarchies. 209 // 210 // Example: 211 // 212 // $ cat /proc/self/cgroup 213 // 12:hugetlb:/ 214 // 11:rdma:/ 215 // 10:net_cls,net_prio:/ 216 // 9:devices:/user.slice 217 // 8:memory:/user.slice 218 // 7:freezer:/user/psaavedra/0 219 // 6:pids:/user.slice/user-1000.slice/user@1000.service 220 // 5:blkio:/user.slice 221 // 4:perf_event:/ 222 // 3:cpu,cpuacct:/user.slice 223 // 2:cpuset:/ 224 // 1:name=systemd:/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service 225 // 0::/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service 226 static CString getCgroupController(const char* controllerName) 227 { 228 CString memoryControllerName; 229 FILE* file = fopen(s_cgroupController, "r"); 230 if (!file) 231 return CString(); 232 233 char buffer[maxCgroupPath]; 234 while (char* line = fgets(buffer, maxCgroupPath, file)) { 235 char* token = strtok(line, "\n"); 236 if (!token) 237 break; 238 239 token = strtok(token, ":"); 240 token = strtok(nullptr, ":"); 241 if (!strcmp(token, controllerName)) { 242 token = strtok(nullptr, ":"); 243 memoryControllerName = CString(token); 244 fclose(file); 245 return memoryControllerName; 246 } 247 } 248 fclose(file); 249 return CString(); 250 } 251 252 129 253 static int systemMemoryUsedAsPercentage() 130 254 { … … 191 315 return -1; 192 316 193 return ((memoryTotal - memoryAvailable) * 100) / memoryTotal; 317 int memoryUsagePercentage = ((memoryTotal - memoryAvailable) * 100) / memoryTotal; 318 CString memoryControllerName = getCgroupController("memory"); 319 if (!memoryControllerName.isNull()) { 320 memoryTotal = getMemoryTotalWithCgroup(memoryControllerName); 321 size_t memoryUsage = getMemoryUsageWithCgroup(memoryControllerName); 322 if (memoryTotal) { 323 int memoryUsagePercentageWithCgroup = 100 * ((float) memoryUsage / (float) memoryTotal); 324 if (memoryUsagePercentageWithCgroup > memoryUsagePercentage) 325 memoryUsagePercentage = memoryUsagePercentageWithCgroup; 326 } 327 } 328 return memoryUsagePercentage; 194 329 } 195 330
Note: See TracChangeset
for help on using the changeset viewer.