Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8287011: Improve container information #844

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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);
MBaesken marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -91,6 +91,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 @@ -130,3 +135,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 @@ -2278,19 +2278,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");
}
}

bool os::Linux::print_container_info(outputStream* st) {
if (!OSContainer::is_containerized()) {
st->print_cr("container information not found.");
Expand Down Expand Up @@ -2346,11 +2333,13 @@ bool os::Linux::print_container_info(outputStream* st) {
st->print_cr("%s", 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");
}
}
}

}