< prev index next >

src/java.base/linux/classes/jdk/internal/platform/cgroupv1/Metrics.java

Print this page
@  rev 54202 : 8217338: [Containers] Improve systemd slice memory limit support
|  Summary: Use hierachical memory limit in addition to memory_limits_in_bytes
~  Reviewed-by: duke

@@ -23,19 +23,20 @@
  * questions.
  */
 
 package jdk.internal.platform.cgroupv1;
 
-import java.io.BufferedReader;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.stream.Stream;
 
+import jdk.internal.platform.cgroupv1.SubSystem.MemorySubSystem;
+
 public class Metrics implements jdk.internal.platform.Metrics {
-    private SubSystem memory;
+    private MemorySubSystem memory;
     private SubSystem cpu;
     private SubSystem cpuacct;
     private SubSystem cpuset;
     private SubSystem blkio;
     private boolean activeSubSystems;

@@ -131,11 +132,11 @@
         String[] subsystemNames = p.getFileName().toString().split(",");
 
         for (String subsystemName: subsystemNames) {
             switch (subsystemName) {
                 case "memory":
-                    metric.setMemorySubSystem(new SubSystem(mountentry[3], mountentry[4]));
+                    metric.setMemorySubSystem(new MemorySubSystem(mountentry[3], mountentry[4]));
                     break;
                 case "cpuset":
                     metric.setCpuSetSubSystem(new SubSystem(mountentry[3], mountentry[4]));
                     break;
                 case "cpuacct":

@@ -193,27 +194,37 @@
             }
         }
 
         if (subsystem != null) {
             subsystem.setPath(base);
+            if (subsystem instanceof MemorySubSystem) {
+                MemorySubSystem memorySubSystem = (MemorySubSystem)subsystem;
+                boolean isHierarchial = getHierarchical(memorySubSystem);
+                memorySubSystem.setHierarchical(isHierarchial);
+            }
             metric.setActiveSubSystems();
         }
         if (subsystem2 != null) {
             subsystem2.setPath(base);
         }
     }
 
 
+    private static boolean getHierarchical(MemorySubSystem subsystem) {
+        long hierarchical = SubSystem.getLongValue(subsystem, "memory.use_hierarchy");
+        return hierarchical > 0;
+    }
+
     private void setActiveSubSystems() {
         activeSubSystems = true;
     }
 
     private boolean activeSubSystems() {
         return activeSubSystems;
     }
 
-    private void setMemorySubSystem(SubSystem memory) {
+    private void setMemorySubSystem(MemorySubSystem memory) {
         this.memory = memory;
     }
 
     private void setCpuSubSystem(SubSystem cpu) {
         this.cpu = cpu;

@@ -364,13 +375,33 @@
         return SubSystem.getLongValue(memory, "memory.failcnt");
     }
 
     public long getMemoryLimit() {
         long retval = SubSystem.getLongValue(memory, "memory.limit_in_bytes");
+        if (retval > unlimited_minimum) {
+            if (memory.isHierarchical()) {
+                // memory.limit_in_bytes returned unlimited, attempt
+                // hierarchical memory limit
+                String match = "hierarchical_memory_limit";
+                retval = SubSystem.getLongValueMatchingLine(memory,
+                                                            "memory.stat",
+                                                            match,
+                                                            Metrics::convertHierachicalLimitLine);
+            }
+        }
         return retval > unlimited_minimum ? -1L : retval;
     }
 
+    public static long convertHierachicalLimitLine(String line) {
+        String[] tokens = line.split("\\s");
+        if (tokens.length == 2) {
+            String strVal = tokens[1];
+            return SubSystem.convertStringToLong(strVal);
+        }
+        return unlimited_minimum + 1; // unlimited
+    }
+
     public long getMemoryMaxUsage() {
         return SubSystem.getLongValue(memory, "memory.max_usage_in_bytes");
     }
 
     public long getMemoryUsage() {

@@ -415,10 +446,21 @@
         return SubSystem.getLongValue(memory, "memory.memsw.failcnt");
     }
 
     public long getMemoryAndSwapLimit() {
         long retval = SubSystem.getLongValue(memory, "memory.memsw.limit_in_bytes");
+        if (retval > unlimited_minimum) {
+            if (memory.isHierarchical()) {
+                // memory.memsw.limit_in_bytes returned unlimited, attempt
+                // hierarchical memory limit
+                String match = "hierarchical_memsw_limit";
+                retval = SubSystem.getLongValueMatchingLine(memory,
+                                                            "memory.stat",
+                                                            match,
+                                                            Metrics::convertHierachicalLimitLine);
+            }
+        }
         return retval > unlimited_minimum ? -1L : retval;
     }
 
     public long getMemoryAndSwapMaxUsage() {
         return SubSystem.getLongValue(memory, "memory.memsw.max_usage_in_bytes");
< prev index next >