Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/hotspot/os/aix/os_aix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,18 @@ bool os::free_memory(physical_memory_size_type& value) {
return Aix::available_memory(value);
}

bool os::machine_free_memory(physical_memory_size_type& value) {
return Aix::available_memory(value);
}

bool os::available_memory(physical_memory_size_type& value) {
return Aix::available_memory(value);
}

bool os::machine_available_memory(physical_memory_size_type& value) {
return Aix::available_memory(value);
}

bool os::Aix::available_memory(physical_memory_size_type& value) {
os::Aix::meminfo_t mi;
if (os::Aix::get_meminfo(&mi)) {
Expand All @@ -273,6 +281,10 @@ bool os::Aix::available_memory(physical_memory_size_type& value) {
}

bool os::total_swap_space(physical_memory_size_type& value) {
return machine_total_swap_space(value);
}

bool os::machine_total_swap_space(physical_memory_size_type& value) {
perfstat_memory_total_t memory_info;
if (libperfstat::perfstat_memory_total(nullptr, &memory_info, sizeof(perfstat_memory_total_t), 1) == -1) {
return false;
Expand All @@ -282,6 +294,10 @@ bool os::total_swap_space(physical_memory_size_type& value) {
}

bool os::free_swap_space(physical_memory_size_type& value) {
return machine_free_swap_space(value);
}

bool os::machine_free_swap_space(physical_memory_size_type& value) {
perfstat_memory_total_t memory_info;
if (libperfstat::perfstat_memory_total(nullptr, &memory_info, sizeof(perfstat_memory_total_t), 1) == -1) {
return false;
Expand All @@ -294,6 +310,10 @@ physical_memory_size_type os::physical_memory() {
return Aix::physical_memory();
}

physical_memory_size_type os::machine_physical_memory() {
return Aix::physical_memory();
}

size_t os::rss() { return (size_t)0; }

// Cpu architecture string
Expand Down Expand Up @@ -2259,6 +2279,10 @@ int os::active_processor_count() {
return ActiveProcessorCount;
}

return machine_active_processor_count();
}

int os::machine_active_processor_count() {
int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
return online_cpus;
Expand Down
24 changes: 24 additions & 0 deletions src/hotspot/os/bsd/os_bsd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,18 @@ bool os::available_memory(physical_memory_size_type& value) {
return Bsd::available_memory(value);
}

bool os::machine_available_memory(physical_memory_size_type& value) {
return Bsd::available_memory(value);
}

bool os::free_memory(physical_memory_size_type& value) {
return Bsd::available_memory(value);
}

bool os::machine_free_memory(physical_memory_size_type& value) {
return Bsd::available_memory(value);
}

// Available here means free. Note that this number is of no much use. As an estimate
// for future memory pressure it is far too conservative, since MacOS will use a lot
// of unused memory for caches, and return it willingly in case of needs.
Expand Down Expand Up @@ -181,6 +189,10 @@ void os::Bsd::print_uptime_info(outputStream* st) {
}

bool os::total_swap_space(physical_memory_size_type& value) {
return machine_total_swap_space(value);
}

bool os::machine_total_swap_space(physical_memory_size_type& value) {
#if defined(__APPLE__)
struct xsw_usage vmusage;
size_t size = sizeof(vmusage);
Expand All @@ -195,6 +207,10 @@ bool os::total_swap_space(physical_memory_size_type& value) {
}

bool os::free_swap_space(physical_memory_size_type& value) {
return machine_free_swap_space(value);
}

bool os::machine_free_swap_space(physical_memory_size_type& value) {
#if defined(__APPLE__)
struct xsw_usage vmusage;
size_t size = sizeof(vmusage);
Expand All @@ -212,6 +228,10 @@ physical_memory_size_type os::physical_memory() {
return Bsd::physical_memory();
}

physical_memory_size_type os::machine_physical_memory() {
return Bsd::physical_memory();
}

size_t os::rss() {
size_t rss = 0;
#ifdef __APPLE__
Expand Down Expand Up @@ -2112,6 +2132,10 @@ int os::active_processor_count() {
return ActiveProcessorCount;
}

return machine_active_processor_count();
}

int os::machine_active_processor_count() {
return _processor_count;
}

Expand Down
22 changes: 9 additions & 13 deletions src/hotspot/os/linux/cgroupSubsystem_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,24 +632,20 @@ void CgroupSubsystemFactory::cleanup(CgroupInfo* cg_infos) {
* return:
* number of CPUs
*/
int CgroupSubsystem::active_processor_count() {
int quota_count = 0;
int cpu_count;
int result;

double CgroupSubsystem::active_processor_count() {
// We use a cache with a timeout to avoid performing expensive
// computations in the event this function is called frequently.
// [See 8227006].
CachingCgroupController<CgroupCpuController>* contrl = cpu_controller();
CachedMetric* cpu_limit = contrl->metrics_cache();
CachingCgroupController<CgroupCpuController, double>* contrl = cpu_controller();
CachedMetric<double>* cpu_limit = contrl->metrics_cache();
if (!cpu_limit->should_check_metric()) {
int val = (int)cpu_limit->value();
log_trace(os, container)("CgroupSubsystem::active_processor_count (cached): %d", val);
double val = cpu_limit->value();
log_trace(os, container)("CgroupSubsystem::active_processor_count (cached): %.2f", val);
return val;
}

cpu_count = os::Linux::active_processor_count();
result = CgroupUtil::processor_count(contrl->controller(), cpu_count);
int cpu_count = os::Linux::active_processor_count();
double result = CgroupUtil::processor_count(contrl->controller(), cpu_count);
// Update cached metric to avoid re-reading container settings too often
cpu_limit->set_value(result, OSCONTAINER_CACHE_TIMEOUT);

Expand All @@ -666,8 +662,8 @@ int CgroupSubsystem::active_processor_count() {
* OSCONTAINER_ERROR for not supported
*/
jlong CgroupSubsystem::memory_limit_in_bytes(julong upper_bound) {
CachingCgroupController<CgroupMemoryController>* contrl = memory_controller();
CachedMetric* memory_limit = contrl->metrics_cache();
CachingCgroupController<CgroupMemoryController, jlong>* contrl = memory_controller();
CachedMetric<jlong>* memory_limit = contrl->metrics_cache();
if (!memory_limit->should_check_metric()) {
return memory_limit->value();
}
Expand Down
21 changes: 11 additions & 10 deletions src/hotspot/os/linux/cgroupSubsystem_linux.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,10 @@ class CgroupController: public CHeapObj<mtInternal> {
static jlong limit_from_str(char* limit_str);
};

template <typename MetricType>
class CachedMetric : public CHeapObj<mtInternal>{
private:
volatile jlong _metric;
volatile MetricType _metric;
volatile jlong _next_check_counter;
public:
CachedMetric() {
Expand All @@ -174,8 +175,8 @@ class CachedMetric : public CHeapObj<mtInternal>{
bool should_check_metric() {
return os::elapsed_counter() > _next_check_counter;
}
jlong value() { return _metric; }
void set_value(jlong value, jlong timeout) {
MetricType value() { return _metric; }
void set_value(MetricType value, jlong timeout) {
_metric = value;
// Metric is unlikely to change, but we want to remain
// responsive to configuration changes. A very short grace time
Expand All @@ -186,19 +187,19 @@ class CachedMetric : public CHeapObj<mtInternal>{
}
};

template <class T>
template <class T, typename MetricType>
class CachingCgroupController : public CHeapObj<mtInternal> {
private:
T* _controller;
CachedMetric* _metrics_cache;
CachedMetric<MetricType>* _metrics_cache;

public:
CachingCgroupController(T* cont) {
_controller = cont;
_metrics_cache = new CachedMetric();
_metrics_cache = new CachedMetric<MetricType>();
}

CachedMetric* metrics_cache() { return _metrics_cache; }
CachedMetric<MetricType>* metrics_cache() { return _metrics_cache; }
T* controller() { return _controller; }
};

Expand Down Expand Up @@ -252,7 +253,7 @@ class CgroupMemoryController: public CHeapObj<mtInternal> {
class CgroupSubsystem: public CHeapObj<mtInternal> {
public:
jlong memory_limit_in_bytes(julong upper_bound);
int active_processor_count();
double active_processor_count();

virtual jlong pids_max() = 0;
virtual jlong pids_current() = 0;
Expand All @@ -261,8 +262,8 @@ class CgroupSubsystem: public CHeapObj<mtInternal> {
virtual char * cpu_cpuset_cpus() = 0;
virtual char * cpu_cpuset_memory_nodes() = 0;
virtual const char * container_type() = 0;
virtual CachingCgroupController<CgroupMemoryController>* memory_controller() = 0;
virtual CachingCgroupController<CgroupCpuController>* cpu_controller() = 0;
virtual CachingCgroupController<CgroupMemoryController, jlong>* memory_controller() = 0;
virtual CachingCgroupController<CgroupCpuController, double>* cpu_controller() = 0;
virtual CgroupCpuacctController* cpuacct_controller() = 0;

int cpu_quota();
Expand Down
21 changes: 7 additions & 14 deletions src/hotspot/os/linux/cgroupUtil_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,19 @@
#include "cgroupUtil_linux.hpp"
#include "os_linux.hpp"

int CgroupUtil::processor_count(CgroupCpuController* cpu_ctrl, int host_cpus) {
double CgroupUtil::processor_count(CgroupCpuController* cpu_ctrl, int host_cpus) {
assert(host_cpus > 0, "physical host cpus must be positive");
int limit_count = host_cpus;
int quota = cpu_ctrl->cpu_quota();
int period = cpu_ctrl->cpu_period();
int quota_count = 0;
int result = 0;
double result = static_cast<double>(host_cpus);

if (quota > -1 && period > 0) {
quota_count = ceilf((float)quota / (float)period);
log_trace(os, container)("CPU Quota count based on quota/period: %d", quota_count);
if (quota > 0 && period > 0) { // Use quotas
double cpu_quota = static_cast<double>(quota) / period;
log_trace(os, container)("CPU Quota based on quota/period: %.2f", cpu_quota);
result = MIN2(result, cpu_quota);
}

// Use quotas
if (quota_count != 0) {
limit_count = quota_count;
}

result = MIN2(host_cpus, limit_count);
log_trace(os, container)("OSContainer::active_processor_count: %d", result);
log_trace(os, container)("OSContainer::active_processor_count: %.2f", result);
return result;
}

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/os/linux/cgroupUtil_linux.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
class CgroupUtil: AllStatic {

public:
static int processor_count(CgroupCpuController* cpu, int host_cpus);
static double processor_count(CgroupCpuController* cpu, int host_cpus);
// Given a memory controller, adjust its path to a point in the hierarchy
// that represents the closest memory limit.
static void adjust_controller(CgroupMemoryController* m);
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,8 @@ CgroupV1Subsystem::CgroupV1Subsystem(CgroupV1Controller* cpuset,
_pids(pids) {
CgroupUtil::adjust_controller(memory);
CgroupUtil::adjust_controller(cpu);
_memory = new CachingCgroupController<CgroupMemoryController>(memory);
_cpu = new CachingCgroupController<CgroupCpuController>(cpu);
_memory = new CachingCgroupController<CgroupMemoryController, jlong>(memory);
_cpu = new CachingCgroupController<CgroupCpuController, double>(cpu);
}

bool CgroupV1Subsystem::is_containerized() {
Expand Down
8 changes: 4 additions & 4 deletions src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,15 +193,15 @@ class CgroupV1Subsystem: public CgroupSubsystem {
const char * container_type() {
return "cgroupv1";
}
CachingCgroupController<CgroupMemoryController>* memory_controller() { return _memory; }
CachingCgroupController<CgroupCpuController>* cpu_controller() { return _cpu; }
CachingCgroupController<CgroupMemoryController, jlong>* memory_controller() { return _memory; }
CachingCgroupController<CgroupCpuController, double>* cpu_controller() { return _cpu; }
CgroupCpuacctController* cpuacct_controller() { return _cpuacct; }

private:
/* controllers */
CachingCgroupController<CgroupMemoryController>* _memory = nullptr;
CachingCgroupController<CgroupMemoryController, jlong>* _memory = nullptr;
CgroupV1Controller* _cpuset = nullptr;
CachingCgroupController<CgroupCpuController>* _cpu = nullptr;
CachingCgroupController<CgroupCpuController, double>* _cpu = nullptr;
CgroupV1CpuacctController* _cpuacct = nullptr;
CgroupV1Controller* _pids = nullptr;

Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ CgroupV2Subsystem::CgroupV2Subsystem(CgroupV2MemoryController * memory,
_unified(unified) {
CgroupUtil::adjust_controller(memory);
CgroupUtil::adjust_controller(cpu);
_memory = new CachingCgroupController<CgroupMemoryController>(memory);
_cpu = new CachingCgroupController<CgroupCpuController>(cpu);
_memory = new CachingCgroupController<CgroupMemoryController, jlong>(memory);
_cpu = new CachingCgroupController<CgroupCpuController, double>(cpu);
_cpuacct = cpuacct;
}

Expand Down
8 changes: 4 additions & 4 deletions src/hotspot/os/linux/cgroupV2Subsystem_linux.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ class CgroupV2Subsystem: public CgroupSubsystem {
/* One unified controller */
CgroupV2Controller _unified;
/* Caching wrappers for cpu/memory metrics */
CachingCgroupController<CgroupMemoryController>* _memory = nullptr;
CachingCgroupController<CgroupCpuController>* _cpu = nullptr;
CachingCgroupController<CgroupMemoryController, jlong>* _memory = nullptr;
CachingCgroupController<CgroupCpuController, double>* _cpu = nullptr;

CgroupCpuacctController* _cpuacct = nullptr;

Expand All @@ -168,8 +168,8 @@ class CgroupV2Subsystem: public CgroupSubsystem {
const char * container_type() override {
return "cgroupv2";
}
CachingCgroupController<CgroupMemoryController>* memory_controller() override { return _memory; }
CachingCgroupController<CgroupCpuController>* cpu_controller() override { return _cpu; }
CachingCgroupController<CgroupMemoryController, jlong>* memory_controller() override { return _memory; }
CachingCgroupController<CgroupCpuController, double>* cpu_controller() override { return _cpu; }
CgroupCpuacctController* cpuacct_controller() override { return _cpuacct; };
};

Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/os/linux/osContainer_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void OSContainer::init() {
// 1.) On a physical Linux system without any limit
// 2.) On a physical Linux system with a limit enforced by other means (like systemd slice)
any_mem_cpu_limit_present = memory_limit_in_bytes() > 0 ||
os::Linux::active_processor_count() != active_processor_count();
os::Linux::active_processor_count() != ceilf(active_processor_count());
if (any_mem_cpu_limit_present) {
reason = " because either a cpu or a memory limit is present";
} else {
Expand Down Expand Up @@ -122,7 +122,7 @@ bool OSContainer::available_memory_in_container(julong& value) {

jlong OSContainer::memory_limit_in_bytes() {
assert(cgroup_subsystem != nullptr, "cgroup subsystem not available");
julong phys_mem = static_cast<julong>(os::Linux::physical_memory());
julong phys_mem = static_cast<julong>(os::machine_physical_memory());
return cgroup_subsystem->memory_limit_in_bytes(phys_mem);
}

Expand Down Expand Up @@ -187,7 +187,7 @@ char * OSContainer::cpu_cpuset_memory_nodes() {
return cgroup_subsystem->cpu_cpuset_memory_nodes();
}

int OSContainer::active_processor_count() {
double OSContainer::active_processor_count() {
assert(cgroup_subsystem != nullptr, "cgroup subsystem not available");
return cgroup_subsystem->active_processor_count();
}
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/os/linux/osContainer_linux.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class OSContainer: AllStatic {
static jlong rss_usage_in_bytes();
static jlong cache_usage_in_bytes();

static int active_processor_count();
static double active_processor_count();

static char * cpu_cpuset_cpus();
static char * cpu_cpuset_memory_nodes();
Expand Down
Loading