2828#include " cgroupSubsystem_linux.hpp"
2929#include " cgroupV1Subsystem_linux.hpp"
3030#include " cgroupV2Subsystem_linux.hpp"
31+ #include " cgroupUtil_linux.hpp"
3132#include " logging/log.hpp"
3233#include " memory/allocation.hpp"
3334#include " os_linux.hpp"
@@ -41,7 +42,7 @@ static const char* cg_controller_name[] = { "cpu", "cpuset", "cpuacct", "memory"
4142CgroupSubsystem* CgroupSubsystemFactory::create () {
4243 CgroupV1MemoryController* memory = nullptr ;
4344 CgroupV1Controller* cpuset = nullptr ;
44- CgroupV1Controller * cpu = nullptr ;
45+ CgroupV1CpuController * cpu = nullptr ;
4546 CgroupV1Controller* cpuacct = nullptr ;
4647 CgroupV1Controller* pids = nullptr ;
4748 CgroupInfo cg_infos[CG_INFO_LENGTH];
@@ -61,14 +62,18 @@ CgroupSubsystem* CgroupSubsystemFactory::create() {
6162 if (is_cgroup_v2 (&cg_type_flags)) {
6263 // Cgroups v2 case, we have all the info we need.
6364 // Construct the subsystem, free resources and return
64- // Note: any index in cg_infos will do as the path is the same for
65- // all controllers.
66- CgroupController* unified = new CgroupV2Controller (cg_infos[MEMORY_IDX]._mount_path ,
67- cg_infos[MEMORY_IDX]._cgroup_path ,
68- cg_infos[MEMORY_IDX]._read_only );
65+ // Note: We use the memory for non-cpu non-memory controller look-ups.
66+ // Perhaps we ought to have separate controllers for all.
67+ CgroupV2Controller mem_other = CgroupV2Controller (cg_infos[MEMORY_IDX]._mount_path ,
68+ cg_infos[MEMORY_IDX]._cgroup_path ,
69+ cg_infos[MEMORY_IDX]._read_only );
70+ CgroupV2MemoryController* memory = new CgroupV2MemoryController (mem_other);
71+ CgroupV2CpuController* cpu = new CgroupV2CpuController (CgroupV2Controller (cg_infos[CPU_IDX]._mount_path ,
72+ cg_infos[CPU_IDX]._cgroup_path ,
73+ cg_infos[CPU_IDX]._read_only ));
6974 log_debug (os, container)(" Detected cgroups v2 unified hierarchy" );
7075 cleanup (cg_infos);
71- return new CgroupV2Subsystem (unified );
76+ return new CgroupV2Subsystem (memory, cpu, mem_other );
7277 }
7378
7479 /*
@@ -102,13 +107,13 @@ CgroupSubsystem* CgroupSubsystemFactory::create() {
102107 CgroupInfo info = cg_infos[i];
103108 if (info._data_complete ) { // pids controller might have incomplete data
104109 if (strcmp (info._name , " memory" ) == 0 ) {
105- memory = new CgroupV1MemoryController (info._root_mount_path , info._mount_path , info._read_only );
110+ memory = new CgroupV1MemoryController (CgroupV1Controller ( info._root_mount_path , info._mount_path , info._read_only ) );
106111 memory->set_subsystem_path (info._cgroup_path );
107112 } else if (strcmp (info._name , " cpuset" ) == 0 ) {
108113 cpuset = new CgroupV1Controller (info._root_mount_path , info._mount_path , info._read_only );
109114 cpuset->set_subsystem_path (info._cgroup_path );
110115 } else if (strcmp (info._name , " cpu" ) == 0 ) {
111- cpu = new CgroupV1Controller (info._root_mount_path , info._mount_path , info._read_only );
116+ cpu = new CgroupV1CpuController ( CgroupV1Controller (info._root_mount_path , info._mount_path , info._read_only ) );
112117 cpu->set_subsystem_path (info._cgroup_path );
113118 } else if (strcmp (info._name , " cpuacct" ) == 0 ) {
114119 cpuacct = new CgroupV1Controller (info._root_mount_path , info._mount_path , info._read_only );
@@ -556,37 +561,22 @@ void CgroupSubsystemFactory::cleanup(CgroupInfo* cg_infos) {
556561 */
557562int CgroupSubsystem::active_processor_count () {
558563 int quota_count = 0 ;
559- int cpu_count, limit_count ;
564+ int cpu_count;
560565 int result;
561566
562567 // We use a cache with a timeout to avoid performing expensive
563568 // computations in the event this function is called frequently.
564569 // [See 8227006].
565- CachingCgroupController* contrl = cpu_controller ();
570+ CachingCgroupController<CgroupCpuController> * contrl = cpu_controller ();
566571 CachedMetric* cpu_limit = contrl->metrics_cache ();
567572 if (!cpu_limit->should_check_metric ()) {
568573 int val = (int )cpu_limit->value ();
569574 log_trace (os, container)(" CgroupSubsystem::active_processor_count (cached): %d" , val);
570575 return val;
571576 }
572577
573- cpu_count = limit_count = os::Linux::active_processor_count ();
574- int quota = cpu_quota ();
575- int period = cpu_period ();
576-
577- if (quota > -1 && period > 0 ) {
578- quota_count = ceilf ((float )quota / (float )period);
579- log_trace (os, container)(" CPU Quota count based on quota/period: %d" , quota_count);
580- }
581-
582- // Use quotas
583- if (quota_count != 0 ) {
584- limit_count = quota_count;
585- }
586-
587- result = MIN2 (cpu_count, limit_count);
588- log_trace (os, container)(" OSContainer::active_processor_count: %d" , result);
589-
578+ cpu_count = os::Linux::active_processor_count ();
579+ result = CgroupUtil::processor_count (contrl->controller (), cpu_count);
590580 // Update cached metric to avoid re-reading container settings too often
591581 cpu_limit->set_value (result, OSCONTAINER_CACHE_TIMEOUT);
592582
@@ -603,35 +593,14 @@ int CgroupSubsystem::active_processor_count() {
603593 * OSCONTAINER_ERROR for not supported
604594 */
605595jlong CgroupSubsystem::memory_limit_in_bytes () {
606- CachingCgroupController* contrl = memory_controller ();
596+ CachingCgroupController<CgroupMemoryController> * contrl = memory_controller ();
607597 CachedMetric* memory_limit = contrl->metrics_cache ();
608598 if (!memory_limit->should_check_metric ()) {
609599 return memory_limit->value ();
610600 }
611601 jlong phys_mem = os::Linux::physical_memory ();
612602 log_trace (os, container)(" total physical memory: " JLONG_FORMAT, phys_mem);
613- jlong mem_limit = read_memory_limit_in_bytes ();
614-
615- if (mem_limit <= 0 || mem_limit >= phys_mem) {
616- jlong read_mem_limit = mem_limit;
617- const char *reason;
618- if (mem_limit >= phys_mem) {
619- // Exceeding physical memory is treated as unlimited. Cg v1's implementation
620- // of read_memory_limit_in_bytes() caps this at phys_mem since Cg v1 has no
621- // value to represent 'max'. Cg v2 may return a value >= phys_mem if e.g. the
622- // container engine was started with a memory flag exceeding it.
623- reason = " ignored" ;
624- mem_limit = -1 ;
625- } else if (OSCONTAINER_ERROR == mem_limit) {
626- reason = " failed" ;
627- } else {
628- assert (mem_limit == -1 , " Expected unlimited" );
629- reason = " unlimited" ;
630- }
631- log_debug (os, container)(" container memory limit %s: " JLONG_FORMAT " , using host value " JLONG_FORMAT,
632- reason, read_mem_limit, phys_mem);
633- }
634-
603+ jlong mem_limit = contrl->controller ()->read_memory_limit_in_bytes (phys_mem);
635604 // Update cached metric to avoid re-reading container settings too often
636605 memory_limit->set_value (mem_limit, OSCONTAINER_CACHE_TIMEOUT);
637606 return mem_limit;
@@ -796,3 +765,55 @@ jlong CgroupController::limit_from_str(char* limit_str) {
796765 }
797766 return (jlong)limit;
798767}
768+
769+ // CgroupSubsystem implementations
770+
771+ jlong CgroupSubsystem::memory_and_swap_limit_in_bytes () {
772+ julong phys_mem = os::Linux::physical_memory ();
773+ julong host_swap = os::Linux::host_swap ();
774+ return memory_controller ()->controller ()->memory_and_swap_limit_in_bytes (phys_mem, host_swap);
775+ }
776+
777+ jlong CgroupSubsystem::memory_and_swap_usage_in_bytes () {
778+ julong phys_mem = os::Linux::physical_memory ();
779+ julong host_swap = os::Linux::host_swap ();
780+ return memory_controller ()->controller ()->memory_and_swap_usage_in_bytes (phys_mem, host_swap);
781+ }
782+
783+ jlong CgroupSubsystem::memory_soft_limit_in_bytes () {
784+ julong phys_mem = os::Linux::physical_memory ();
785+ return memory_controller ()->controller ()->memory_soft_limit_in_bytes (phys_mem);
786+ }
787+
788+ jlong CgroupSubsystem::memory_usage_in_bytes () {
789+ return memory_controller ()->controller ()->memory_usage_in_bytes ();
790+ }
791+
792+ jlong CgroupSubsystem::memory_max_usage_in_bytes () {
793+ return memory_controller ()->controller ()->memory_max_usage_in_bytes ();
794+ }
795+
796+ jlong CgroupSubsystem::rss_usage_in_bytes () {
797+ return memory_controller ()->controller ()->rss_usage_in_bytes ();
798+ }
799+
800+ jlong CgroupSubsystem::cache_usage_in_bytes () {
801+ return memory_controller ()->controller ()->cache_usage_in_bytes ();
802+ }
803+
804+ int CgroupSubsystem::cpu_quota () {
805+ return cpu_controller ()->controller ()->cpu_quota ();
806+ }
807+
808+ int CgroupSubsystem::cpu_period () {
809+ return cpu_controller ()->controller ()->cpu_period ();
810+ }
811+
812+ int CgroupSubsystem::cpu_shares () {
813+ return cpu_controller ()->controller ()->cpu_shares ();
814+ }
815+
816+ void CgroupSubsystem::print_version_specific_info (outputStream* st) {
817+ julong phys_mem = os::Linux::physical_memory ();
818+ memory_controller ()->controller ()->print_version_specific_info (st, phys_mem);
819+ }
0 commit comments