Title: [259287] trunk/Source/WebKit
Revision
259287
Author
[email protected]
Date
2020-03-31 07:20:40 -0700 (Tue, 31 Mar 2020)

Log Message

Several refactorings done in the MemoryPressureMonitor.cpp
https://bugs.webkit.org/show_bug.cgi?id=209464

Reviewed by Adrian Perez de Castro.

1) toIntegralType() parses the C-string str interpreting its content
as an `unsigned long long int` which is more appropriate for
the size_t (unsigned integer type) variables used by the
MemoryPressureMonitor functions in counterpoint of atoll() what
returns a `long long int`.

This change also controls if the parsing was succesful. In negative
case returns `notSet`.

2) Added the getCgroupFileValue() function what encapsulates the
manipulation of the opened files in the `/sys/fs/cgroup` hierarchy.
This change simplify the code avoding unnecessary code repetion.

3) getCgroupControllerPath() now checks if there is a `name=systemd`
controller listed in the `/proc/self/cgroup`. This important for
cgroup v2 activated with `systemd.unified_cgroup_hierarchy=yes`
through the Linux kernel cmdline. The unified hierarchy simplies
path of the controllers under the same directory (check the
"Deprecated v1 Core Features" section in the Linux Kernel
documentation fir cgroup v2 [1]):

    Multiple hierarchies including named ones are not supported

[1] https://www.kernel.org/doc/Documentation/cgroup-v2.txt

4) Because 3) the patch composited for cgroupV2 changes
getMemoryUsageWithCgroup() slightly. The name of the controller
is not needed anymore.

5) For cgroup v2, the MemoryTotal is calculated as the minimum
between memory.high and memory.max.

* UIProcess/linux/MemoryPressureMonitor.cpp:
(WebKit::lowWatermarkPages):
(WebKit::getCgroupFileValue):
(WebKit::getMemoryTotalWithCgroup):
(WebKit::getMemoryUsageWithCgroup):
(WebKit::getCgroupControllerPath):
(WebKit::systemMemoryUsedAsPercentage):
(WebKit::getCgroupController): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (259286 => 259287)


--- trunk/Source/WebKit/ChangeLog	2020-03-31 14:13:50 UTC (rev 259286)
+++ trunk/Source/WebKit/ChangeLog	2020-03-31 14:20:40 UTC (rev 259287)
@@ -1,3 +1,51 @@
+2020-03-31  Pablo Saavedra  <[email protected]>
+
+        Several refactorings done in the MemoryPressureMonitor.cpp
+        https://bugs.webkit.org/show_bug.cgi?id=209464
+
+        Reviewed by Adrian Perez de Castro.
+
+        1) toIntegralType() parses the C-string str interpreting its content
+        as an `unsigned long long int` which is more appropriate for
+        the size_t (unsigned integer type) variables used by the
+        MemoryPressureMonitor functions in counterpoint of atoll() what
+        returns a `long long int`.
+
+        This change also controls if the parsing was succesful. In negative
+        case returns `notSet`.
+
+        2) Added the getCgroupFileValue() function what encapsulates the
+        manipulation of the opened files in the `/sys/fs/cgroup` hierarchy.
+        This change simplify the code avoding unnecessary code repetion.
+
+        3) getCgroupControllerPath() now checks if there is a `name=systemd`
+        controller listed in the `/proc/self/cgroup`. This important for
+        cgroup v2 activated with `systemd.unified_cgroup_hierarchy=yes`
+        through the Linux kernel cmdline. The unified hierarchy simplies
+        path of the controllers under the same directory (check the
+        "Deprecated v1 Core Features" section in the Linux Kernel
+        documentation fir cgroup v2 [1]):
+
+            Multiple hierarchies including named ones are not supported
+
+        [1] https://www.kernel.org/doc/Documentation/cgroup-v2.txt
+
+        4) Because 3) the patch composited for cgroupV2 changes
+        getMemoryUsageWithCgroup() slightly. The name of the controller
+        is not needed anymore.
+
+        5) For cgroup v2, the MemoryTotal is calculated as the minimum
+        between memory.high and memory.max.
+
+        * UIProcess/linux/MemoryPressureMonitor.cpp:
+        (WebKit::lowWatermarkPages):
+        (WebKit::getCgroupFileValue):
+        (WebKit::getMemoryTotalWithCgroup):
+        (WebKit::getMemoryUsageWithCgroup):
+        (WebKit::getCgroupControllerPath):
+        (WebKit::systemMemoryUsedAsPercentage):
+        (WebKit::getCgroupController): Deleted.
+
 2020-03-31  Zan Dobersek  <[email protected]>
 
         [GTK][WPE] Jumpy rendering of fixed-element layers while scrolling

Modified: trunk/Source/WebKit/UIProcess/linux/MemoryPressureMonitor.cpp (259286 => 259287)


--- trunk/Source/WebKit/UIProcess/linux/MemoryPressureMonitor.cpp	2020-03-31 14:13:50 UTC (rev 259286)
+++ trunk/Source/WebKit/UIProcess/linux/MemoryPressureMonitor.cpp	2020-03-31 14:20:40 UTC (rev 259287)
@@ -36,6 +36,7 @@
 #include <wtf/Threading.h>
 #include <wtf/UniStdExtras.h>
 #include <wtf/text/CString.h>
+#include <wtf/text/StringToIntegerConversion.h>
 
 namespace WebKit {
 
@@ -49,7 +50,7 @@
 static const int s_memoryPresurePercentageThresholdCritical = 95;
 // cgroups.7: The usual place for such mounts is under a tmpfs(5)
 // filesystem mounted at /sys/fs/cgroup.
-static const char* s_cgroupMemoryPath = "/sys/fs/cgroup/memory/%s/%s";
+static const char* s_cgroupMemoryPath = "/sys/fs/cgroup/%s/%s/%s";
 static const char* s_cgroupController = "/proc/self/cgroup";
 static const unsigned maxCgroupPath = 4096; // PATH_MAX = 4096 from (Linux) include/uapi/linux/limits.h
 
@@ -84,7 +85,10 @@
                 low = notSet;
                 break;
             }
-            low += atoll(token);
+            bool ok = true;
+            auto value = toIntegralType<size_t>(token, strlen(token), &ok);
+            if (ok)
+                low += value;
             foundLow = true;
         }
     }
@@ -132,75 +136,75 @@
     return memoryAvailable;
 }
 
-size_t getMemoryTotalWithCgroup(CString memoryControllerName)
+
+size_t getCgroupFileValue(CString cgroupControllerName, CString cgroupControllerPath, CString cgroupFileName)
 {
     char buffer[128];
     char cgroupPath[maxCgroupPath];
     char* token;
     FILE* file;
+    bool ok = true;
 
-    // Check memory limits in cgroupV2
-    snprintf(cgroupPath, maxCgroupPath, s_cgroupMemoryPath, memoryControllerName.data(), "memory.memsw.max");
+    snprintf(cgroupPath, maxCgroupPath, s_cgroupMemoryPath, cgroupControllerName.data(), cgroupControllerPath.data(), cgroupFileName.data());
     file = fopen(cgroupPath, "r");
     if (file) {
         token = fgets(buffer, 128, file);
         fclose(file);
-        return atoll(token);
+        size_t value = toIntegralType<size_t>(token, strlen(token), &ok);
+        if (!ok)
+            value = notSet;
+        return value;
     }
-    snprintf(cgroupPath, maxCgroupPath, s_cgroupMemoryPath, memoryControllerName.data(), "memory.max");
-    file = fopen(cgroupPath, "r");
-    if (file) {
-        token = fgets(buffer, 128, file);
-        fclose(file);
-        return atoll(token);
+    return notSet;
+}
+
+size_t getMemoryTotalWithCgroup(CString memoryControllerName)
+{
+    size_t value = notSet;
+
+    // Check memory limits in cgroupV2
+    value = getCgroupFileValue("/", memoryControllerName, CString("memory.memsw.max"));
+    if (value != notSet)
+        return value;
+
+    value = getCgroupFileValue("/", memoryControllerName, CString("memory.max"));
+    size_t valueHigh = getCgroupFileValue("/", memoryControllerName, CString("memory.high"));
+    if (value != notSet && valueHigh != notSet) {
+        value = std::min(value, valueHigh);
+        return value;
     }
+    if (valueHigh != notSet)
+        return valueHigh;
+    if (value != notSet)
+        return value;
 
     // Check memory limits in cgroupV1
-    snprintf(cgroupPath, maxCgroupPath, s_cgroupMemoryPath, memoryControllerName.data(), "memory.memsw.limit_in_bytes");
-    file = fopen(cgroupPath, "r");
-    if (file) {
-        token = fgets(buffer, 128, file);
-        fclose(file);
-        return atoll(token);
-    }
-    snprintf(cgroupPath, maxCgroupPath, s_cgroupMemoryPath, memoryControllerName.data(), "memory.limit_in_bytes");
-    file = fopen(cgroupPath, "r");
-    if (file) {
-        token = fgets(buffer, 128, file);
-        fclose(file);
-        return atoll(token);
-    }
-    return 0;
+    value = getCgroupFileValue("memory", memoryControllerName, CString("memory.memsw.limit_in_bytes"));
+    if (value != notSet)
+        return value;
+
+    value = getCgroupFileValue("memory", memoryControllerName, CString("memory.limit_in_bytes"));
+    if (value != notSet)
+        return value;
+
+    return value;
 }
 
 static size_t getMemoryUsageWithCgroup(CString memoryControllerName)
 {
-    char buffer[128];
-    char cgroupPath[maxCgroupPath];
-    char* token;
-    char* line;
-    FILE* fileCgroupPathUsageBytes;
+    size_t value = notSet;
 
     // Check memory limits in cgroupV2
-    snprintf(cgroupPath, maxCgroupPath, s_cgroupMemoryPath, memoryControllerName.data(), "memory.current");
-    fileCgroupPathUsageBytes = fopen(cgroupPath, "r");
-    if (fileCgroupPathUsageBytes) {
-        line = fgets(buffer, 128, fileCgroupPathUsageBytes);
-        token = strtok(line, " ");
-        fclose(fileCgroupPathUsageBytes);
-        return atoll(token);
-    }
+    value = getCgroupFileValue("/", memoryControllerName, CString("memory.current"));
+    if (value != notSet)
+        return value;
 
     // Check memory limits in cgroupV1
-    snprintf(cgroupPath, maxCgroupPath, s_cgroupMemoryPath, memoryControllerName.data(), "memory.usage_in_bytes");
-    fileCgroupPathUsageBytes = fopen(cgroupPath, "r");
-    if (fileCgroupPathUsageBytes) {
-        line = fgets(buffer, 128, fileCgroupPathUsageBytes);
-        token = strtok(line, " ");
-        fclose(fileCgroupPathUsageBytes);
-        return atoll(token);
-    }
-    return 0;
+    value = getCgroupFileValue("memory", memoryControllerName, CString("memory.usage_in_bytes"));
+    if (value != notSet)
+        return value;
+
+    return notSet;
 }
 
 // This file describes control groups to which the process with
@@ -223,9 +227,9 @@
 // 2:cpuset:/
 // 1:name=systemd:/user.slice/user-1000.slice/[email protected]/gnome-terminal-server.service
 // 0::/user.slice/user-1000.slice/[email protected]/gnome-terminal-server.service
-static CString getCgroupController(const char* controllerName)
+static CString getCgroupControllerPath(const char* controllerName)
 {
-    CString memoryControllerName;
+    CString memoryControllerPath;
     FILE* file = fopen(s_cgroupController, "r");
     if (!file)
         return CString();
@@ -240,13 +244,17 @@
         token = strtok(nullptr, ":");
         if (!strcmp(token, controllerName)) {
             token = strtok(nullptr, ":");
-            memoryControllerName = CString(token);
+            memoryControllerPath = CString(token);
             fclose(file);
-            return memoryControllerName;
+            return memoryControllerPath;
         }
+        if (!strncmp(token, "name=systemd", 12)) {
+            token = strtok(nullptr, ":");
+            memoryControllerPath = CString(token);
+        }
     }
     fclose(file);
-    return CString();
+    return memoryControllerPath;
 }
 
 
@@ -261,39 +269,52 @@
     char buffer[128];
     while (char* line = fgets(buffer, 128, file)) {
         char* token = strtok(line, " ");
+        bool ok = true;
         if (!token)
             break;
 
         if (!strcmp(token, "MemAvailable:")) {
             if ((token = strtok(nullptr, " "))) {
-                memoryAvailable = atoll(token);
+                memoryAvailable = toIntegralType<size_t>(token, strlen(token), &ok);
+                if (!ok)
+                    memoryAvailable = notSet;
                 if (memoryTotal != notSet)
                     break;
             }
         } else if (!strcmp(token, "MemTotal:")) {
-            if ((token = strtok(nullptr, " ")))
-                memoryTotal = atoll(token);
-            else
+            if ((token = strtok(nullptr, " "))) {
+                memoryTotal = toIntegralType<size_t>(token, strlen(token), &ok);
+                if (!ok)
+                    memoryTotal = notSet;
+            } else
                 break;
         } else if (!strcmp(token, "MemFree:")) {
-            if ((token = strtok(nullptr, " ")))
-                memoryFree = atoll(token);
-            else
+            if ((token = strtok(nullptr, " "))) {
+                memoryFree = toIntegralType<size_t>(token, strlen(token), &ok);
+                if (!ok)
+                    memoryFree = notSet;
+            } else
                 break;
         } else if (!strcmp(token, "Active(file):")) {
-            if ((token = strtok(nullptr, " ")))
-                activeFile = atoll(token);
-            else
+            if ((token = strtok(nullptr, " "))) {
+                activeFile = toIntegralType<size_t>(token, strlen(token), &ok);
+                if (!ok)
+                    activeFile = notSet;
+            } else
                 break;
         } else if (!strcmp(token, "Inactive(file):")) {
-            if ((token = strtok(nullptr, " ")))
-                inactiveFile = atoll(token);
-            else
+            if ((token = strtok(nullptr, " "))) {
+                inactiveFile = toIntegralType<size_t>(token, strlen(token), &ok);
+                if (!ok)
+                    inactiveFile = notSet;
+            } else
                 break;
         } else if (!strcmp(token, "SReclaimable:")) {
-            if ((token = strtok(nullptr, " ")))
-                slabReclaimable = atoll(token);
-            else
+            if ((token = strtok(nullptr, " "))) {
+                slabReclaimable = toIntegralType<size_t>(token, strlen(token), &ok);
+                if (!ok)
+                    slabReclaimable = notSet;
+            } else
                 break;
         }
 
@@ -315,11 +336,11 @@
         return -1;
 
     int memoryUsagePercentage = ((memoryTotal - memoryAvailable) * 100) / memoryTotal;
-    CString memoryControllerName = getCgroupController("memory");
-    if (!memoryControllerName.isNull()) {
-        memoryTotal = getMemoryTotalWithCgroup(memoryControllerName);
-        size_t memoryUsage = getMemoryUsageWithCgroup(memoryControllerName);
-        if (memoryTotal) {
+    CString memoryControllerPath = getCgroupControllerPath("memory");
+    if (!memoryControllerPath.isNull()) {
+        memoryTotal = getMemoryTotalWithCgroup(memoryControllerPath);
+        size_t memoryUsage = getMemoryUsageWithCgroup(memoryControllerPath);
+        if (memoryTotal != notSet && memoryUsage != notSet) {
             int memoryUsagePercentageWithCgroup = 100 * ((float) memoryUsage / (float) memoryTotal);
             if (memoryUsagePercentageWithCgroup > memoryUsagePercentage)
                 memoryUsagePercentage = memoryUsagePercentageWithCgroup;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to