Skip to content

Commit

Permalink
8287011: Improve container information
Browse files Browse the repository at this point in the history
Backport-of: e60939850e5328b9c0f2002ac5ed7744375bf18b
  • Loading branch information
MBaesken committed Dec 15, 2022
1 parent 12eca2f commit 01f5a19
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 21 deletions.
3 changes: 3 additions & 0 deletions src/hotspot/os/linux/cgroupSubsystem_linux.hpp
Expand Up @@ -252,12 +252,15 @@ class CgroupSubsystem: public CHeapObj<mtInternal> {
virtual jlong memory_and_swap_limit_in_bytes() = 0;
virtual jlong memory_soft_limit_in_bytes() = 0;
virtual jlong memory_max_usage_in_bytes() = 0;

virtual char * cpu_cpuset_cpus() = 0;
virtual char * cpu_cpuset_memory_nodes() = 0;
virtual jlong read_memory_limit_in_bytes() = 0;
virtual const char * container_type() = 0;
virtual CachingCgroupController* memory_controller() = 0;
virtual CachingCgroupController* cpu_controller() = 0;

virtual void print_version_specific_info(outputStream* st) = 0;
};

// Utility class for storing info retrieved from /proc/cgroups,
Expand Down
34 changes: 33 additions & 1 deletion src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -212,6 +212,38 @@ jlong CgroupV1Subsystem::memory_max_usage_in_bytes() {
return memmaxusage;
}


jlong CgroupV1Subsystem::kernel_memory_usage_in_bytes() {
GET_CONTAINER_INFO(jlong, _memory->controller(), "/memory.kmem.usage_in_bytes",
"Kernel Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, kmem_usage);
return kmem_usage;
}

jlong CgroupV1Subsystem::kernel_memory_limit_in_bytes() {
GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.kmem.limit_in_bytes",
"Kernel Memory Limit is: " JULONG_FORMAT, JULONG_FORMAT, kmem_limit);
if (kmem_limit >= os::Linux::physical_memory()) {
return (jlong)-1;
}
return (jlong)kmem_limit;
}

jlong CgroupV1Subsystem::kernel_memory_max_usage_in_bytes() {
GET_CONTAINER_INFO(jlong, _memory->controller(), "/memory.kmem.max_usage_in_bytes",
"Maximum Kernel Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, kmem_max_usage);
return kmem_max_usage;
}

void CgroupV1Subsystem::print_version_specific_info(outputStream* st) {
jlong kmem_usage = kernel_memory_usage_in_bytes();
jlong kmem_limit = kernel_memory_limit_in_bytes();
jlong kmem_max_usage = kernel_memory_max_usage_in_bytes();

OSContainer::print_container_helper(st, kmem_usage, "kernel_memory_usage_in_bytes");
OSContainer::print_container_helper(st, kmem_limit, "kernel_memory_max_usage_in_bytes");
OSContainer::print_container_helper(st, kmem_max_usage, "kernel_memory_limit_in_bytes");
}

char * CgroupV1Subsystem::cpu_cpuset_cpus() {
GET_CONTAINER_INFO_CPTR(cptr, _cpuset, "/cpuset.cpus",
"cpuset.cpus is: %s", "%1023s", cpus, 1024);
Expand Down
7 changes: 7 additions & 0 deletions src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp
Expand Up @@ -79,6 +79,11 @@ class CgroupV1Subsystem: public CgroupSubsystem {
jlong memory_soft_limit_in_bytes();
jlong memory_usage_in_bytes();
jlong memory_max_usage_in_bytes();

jlong kernel_memory_usage_in_bytes();
jlong kernel_memory_limit_in_bytes();
jlong kernel_memory_max_usage_in_bytes();

char * cpu_cpuset_cpus();
char * cpu_cpuset_memory_nodes();

Expand All @@ -90,6 +95,8 @@ class CgroupV1Subsystem: public CgroupSubsystem {
jlong pids_max();
jlong pids_current();

void print_version_specific_info(outputStream* st);

const char * container_type() {
return "cgroupv1";
}
Expand Down
21 changes: 21 additions & 0 deletions src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp
Expand Up @@ -182,6 +182,16 @@ char* CgroupV2Subsystem::mem_swp_limit_val() {
return os::strdup(mem_swp_limit_str);
}

// memory.swap.current : total amount of swap currently used by the cgroup and its descendants
char* CgroupV2Subsystem::mem_swp_current_val() {
GET_CONTAINER_INFO_CPTR(cptr, _unified, "/memory.swap.current",
"Swap currently used is: %s", "%s", mem_swp_current_str, 1024);
if (mem_swp_current_str == NULL) {
return NULL;
}
return os::strdup(mem_swp_current_str);
}

/* memory_limit_in_bytes
*
* Return the limit of available memory for this process.
Expand Down Expand Up @@ -212,6 +222,17 @@ char* CgroupV2Subsystem::mem_limit_val() {
return os::strdup(mem_limit_str);
}

void CgroupV2Subsystem::print_version_specific_info(outputStream* st) {
char* mem_swp_current_str = mem_swp_current_val();
jlong swap_current = limit_from_str(mem_swp_current_str);

char* mem_swp_limit_str = mem_swp_limit_val();
jlong swap_limit = limit_from_str(mem_swp_limit_str);

OSContainer::print_container_helper(st, swap_current, "memory_swap_current_in_bytes");
OSContainer::print_container_helper(st, swap_limit, "memory_swap_max_limit_in_bytes");
}

char* CgroupV2Controller::construct_path(char* mount_path, char *cgroup_path) {
char buf[MAXPATHLEN+1];
int buflen;
Expand Down
6 changes: 5 additions & 1 deletion src/hotspot/os/linux/cgroupV2Subsystem_linux.hpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Red Hat Inc.
* Copyright (c) 2020, 2022, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -58,6 +58,7 @@ class CgroupV2Subsystem: public CgroupSubsystem {

char *mem_limit_val();
char *mem_swp_limit_val();
char *mem_swp_current_val();
char *mem_soft_limit_val();
char *cpu_quota_val();
char *pids_max_val();
Expand All @@ -77,11 +78,14 @@ class CgroupV2Subsystem: public CgroupSubsystem {
jlong memory_soft_limit_in_bytes();
jlong memory_usage_in_bytes();
jlong memory_max_usage_in_bytes();

char * cpu_cpuset_cpus();
char * cpu_cpuset_memory_nodes();
jlong pids_max();
jlong pids_current();

void print_version_specific_info(outputStream* st);

const char * container_type() {
return "cgroupv2";
}
Expand Down
20 changes: 19 additions & 1 deletion src/hotspot/os/linux/osContainer_linux.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -100,6 +100,11 @@ jlong OSContainer::memory_max_usage_in_bytes() {
return cgroup_subsystem->memory_max_usage_in_bytes();
}

void OSContainer::print_version_specific_info(outputStream* st) {
assert(cgroup_subsystem != NULL, "cgroup subsystem not available");
cgroup_subsystem->print_version_specific_info(st);
}

char * OSContainer::cpu_cpuset_cpus() {
assert(cgroup_subsystem != NULL, "cgroup subsystem not available");
return cgroup_subsystem->cpu_cpuset_cpus();
Expand Down Expand Up @@ -139,3 +144,16 @@ jlong OSContainer::pids_current() {
assert(cgroup_subsystem != NULL, "cgroup subsystem not available");
return cgroup_subsystem->pids_current();
}

void OSContainer::print_container_helper(outputStream* st, jlong j, const char* metrics) {
st->print("%s: ", metrics);
if (j > 0) {
if (j >= 1024) {
st->print_cr(UINT64_FORMAT " k", uint64_t(j) / 1024);
} else {
st->print_cr(UINT64_FORMAT, uint64_t(j));
}
} else {
st->print_cr("%s", j == OSCONTAINER_ERROR ? "not supported" : "unlimited");
}
}
4 changes: 4 additions & 0 deletions src/hotspot/os/linux/osContainer_linux.hpp
Expand Up @@ -27,6 +27,7 @@

#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
#include "memory/allocation.hpp"

#define OSCONTAINER_ERROR (-2)
Expand All @@ -43,6 +44,9 @@ class OSContainer: AllStatic {

public:
static void init();
static void print_version_specific_info(outputStream* st);
static void print_container_helper(outputStream* st, jlong j, const char* metrics);

static inline bool is_containerized();
static const char * container_type();

Expand Down
25 changes: 7 additions & 18 deletions src/hotspot/os/linux/os_linux.cpp
Expand Up @@ -2460,19 +2460,6 @@ void os::Linux::print_uptime_info(outputStream* st) {
}
}

static void print_container_helper(outputStream* st, jlong j, const char* metrics) {
st->print("%s: ", metrics);
if (j > 0) {
if (j >= 1024) {
st->print_cr(UINT64_FORMAT " k", uint64_t(j) / 1024);
} else {
st->print_cr(UINT64_FORMAT, uint64_t(j));
}
} else {
st->print_cr("%s", j == OSCONTAINER_ERROR ? "not supported" : "unlimited");
}
}

void os::Linux::print_container_info(outputStream* st) {
if (!OSContainer::is_containerized()) {
st->print_cr("container information not found.");
Expand Down Expand Up @@ -2528,11 +2515,13 @@ void os::Linux::print_container_info(outputStream* st) {
st->print("%s\n", i == OSCONTAINER_ERROR ? "not supported" : "no shares");
}

print_container_helper(st, OSContainer::memory_limit_in_bytes(), "memory_limit_in_bytes");
print_container_helper(st, OSContainer::memory_and_swap_limit_in_bytes(), "memory_and_swap_limit_in_bytes");
print_container_helper(st, OSContainer::memory_soft_limit_in_bytes(), "memory_soft_limit_in_bytes");
print_container_helper(st, OSContainer::memory_usage_in_bytes(), "memory_usage_in_bytes");
print_container_helper(st, OSContainer::memory_max_usage_in_bytes(), "memory_max_usage_in_bytes");
OSContainer::print_container_helper(st, OSContainer::memory_limit_in_bytes(), "memory_limit_in_bytes");
OSContainer::print_container_helper(st, OSContainer::memory_and_swap_limit_in_bytes(), "memory_and_swap_limit_in_bytes");
OSContainer::print_container_helper(st, OSContainer::memory_soft_limit_in_bytes(), "memory_soft_limit_in_bytes");
OSContainer::print_container_helper(st, OSContainer::memory_usage_in_bytes(), "memory_usage_in_bytes");
OSContainer::print_container_helper(st, OSContainer::memory_max_usage_in_bytes(), "memory_max_usage_in_bytes");

OSContainer::print_version_specific_info(st);

jlong j = OSContainer::pids_max();
st->print("maximum number of tasks: ");
Expand Down
13 changes: 13 additions & 0 deletions test/hotspot/jtreg/containers/docker/TestMisc.java
Expand Up @@ -123,6 +123,19 @@ private static void checkContainerInfo(OutputAnalyzer out) throws Exception {
for (String s : expectedToContain) {
out.shouldContain(s);
}
String str = out.getOutput();
if (str.contains("cgroupv1")) {
out.shouldContain("kernel_memory_usage_in_bytes");
out.shouldContain("kernel_memory_max_usage_in_bytes");
out.shouldContain("kernel_memory_limit_in_bytes");
} else {
if (str.contains("cgroupv2")) {
out.shouldContain("memory_swap_current_in_bytes");
out.shouldContain("memory_swap_max_limit_in_bytes");
} else {
throw new RuntimeException("Output has to contain information about cgroupv1 or cgroupv2");
}
}
}

}

1 comment on commit 01f5a19

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.