diff --git a/port/unix/omrsysinfo.c b/port/unix/omrsysinfo.c index 2473130c2a6..3fcde1d5670 100644 --- a/port/unix/omrsysinfo.c +++ b/port/unix/omrsysinfo.c @@ -503,12 +503,24 @@ static struct OMRCgroupSubsystemMetricMap omrCgroupCpuMetricMapV2[] = { }; #define OMR_CGROUP_CPU_METRIC_MAP_V2_SIZE sizeof(omrCgroupCpuMetricMapV2) / sizeof(omrCgroupCpuMetricMapV2[0]) -static struct OMRCgroupSubsystemMetricMap omrCgroupCpusetMetricMap[] = { +static struct OMRCgroupSubsystemMetricMap omrCgroupCpusetMetricMapV1[] = { { "cpuset.cpu_exclusive", &(OMRCgroupMetricInfoElement){ "CPU exclusive", NULL, NULL, FALSE }, SINGLE_CGROUP_METRIC }, { "cpuset.mem_exclusive", &(OMRCgroupMetricInfoElement){ "Mem exclusive", NULL, NULL, FALSE }, SINGLE_CGROUP_METRIC }, { "cpuset.cpus", &(OMRCgroupMetricInfoElement){ "CPUs", NULL, NULL, FALSE }, SINGLE_CGROUP_METRIC }, { "cpuset.mems", &(OMRCgroupMetricInfoElement){ "Mems", NULL, NULL, FALSE }, SINGLE_CGROUP_METRIC } }; +#define OMR_CGROUP_CPUSET_METRIC_MAP_V1_SIZE sizeof(omrCgroupCpusetMetricMapV1) / sizeof(omrCgroupCpusetMetricMapV1[0]) + +/* cpuset.cpus and cpuset.mems files may be empty, which indicates the same settings + * as parent cgroup, or that all cpus are available. + */ +static struct OMRCgroupSubsystemMetricMap omrCgroupCpusetMetricMapV2[] = { + { "cpuset.cpus", &(OMRCgroupMetricInfoElement){ "CPUs", NULL, NULL, TRUE }, SINGLE_CGROUP_METRIC }, + { "cpuset.mems", &(OMRCgroupMetricInfoElement){ "Mems", NULL, NULL, TRUE }, SINGLE_CGROUP_METRIC }, + { "cpuset.cpus.effective", &(OMRCgroupMetricInfoElement){ "Effective CPUs", NULL, NULL, FALSE }, SINGLE_CGROUP_METRIC }, + { "cpuset.mems.effective", &(OMRCgroupMetricInfoElement){ "Effective Mems", NULL, NULL, FALSE }, SINGLE_CGROUP_METRIC } +}; +#define OMR_CGROUP_CPUSET_METRIC_MAP_V2_SIZE sizeof(omrCgroupCpusetMetricMapV2) / sizeof(omrCgroupCpusetMetricMapV2[0]) static uint32_t attachedPortLibraries; static omrthread_monitor_t cgroupEntryListMonitor; @@ -6449,7 +6461,7 @@ getCgroupSubsystemMetricMap(struct OMRPortLibrary *portLibrary, uint64_t subsyst *subsystemMetricMap = omrCgroupCpuMetricMapV1; break; case OMR_CGROUP_SUBSYSTEM_CPUSET : - *subsystemMetricMap = omrCgroupCpusetMetricMap; + *subsystemMetricMap = omrCgroupCpusetMetricMapV1; break; default : rc = OMRPORT_ERROR_SYSINFO_CGROUP_SUBSYSTEM_UNAVAILABLE; @@ -6463,7 +6475,7 @@ getCgroupSubsystemMetricMap(struct OMRPortLibrary *portLibrary, uint64_t subsyst *subsystemMetricMap = omrCgroupCpuMetricMapV2; break; case OMR_CGROUP_SUBSYSTEM_CPUSET : - *subsystemMetricMap = omrCgroupCpusetMetricMap; + *subsystemMetricMap = omrCgroupCpusetMetricMapV2; break; default : rc = OMRPORT_ERROR_SYSINFO_CGROUP_SUBSYSTEM_UNAVAILABLE; @@ -6665,7 +6677,7 @@ omrsysinfo_cgroup_subsystem_iterator_init(struct OMRPortLibrary *portLibrary, ui state->numElements = OMR_CGROUP_CPU_METRIC_MAP_V1_SIZE; break; case OMR_CGROUP_SUBSYSTEM_CPUSET : - state->numElements = sizeof(omrCgroupCpusetMetricMap) / sizeof(omrCgroupCpusetMetricMap[0]); + state->numElements = OMR_CGROUP_CPUSET_METRIC_MAP_V1_SIZE; break; default : goto _end; @@ -6679,7 +6691,7 @@ omrsysinfo_cgroup_subsystem_iterator_init(struct OMRPortLibrary *portLibrary, ui state->numElements = OMR_CGROUP_CPU_METRIC_MAP_V2_SIZE; break; case OMR_CGROUP_SUBSYSTEM_CPUSET : - state->numElements = sizeof(omrCgroupCpusetMetricMap) / sizeof(omrCgroupCpusetMetricMap[0]); + state->numElements = OMR_CGROUP_CPUSET_METRIC_MAP_V2_SIZE; break; default : goto _end; @@ -6773,7 +6785,7 @@ omrsysinfo_cgroup_subsystem_iterator_next(struct OMRPortLibrary *portLibrary, st current += 1; } valueEnd = current; - /* Find the last char of the value. Last character of file is always a newline. */ + /* Find the last char of the value. */ while ((' ' != *valueEnd) && ('\n' != *valueEnd)) { valueEnd += 1; } @@ -6835,12 +6847,15 @@ omrsysinfo_cgroup_subsystem_iterator_next(struct OMRPortLibrary *portLibrary, st */ size_t len = strlen(metricElement->value); metricElement->units = currentElement->metricUnit; - if ((len > 0) && (metricElement->value[len-1] == '\n')) { + if ((len > 1) && (metricElement->value[len-1] == '\n')) { metricElement->value[len-1] = '\0'; } if (currentElement->isValueToBeChecked) { int64_t result = 0; - if (OMR_ARE_ANY_BITS_SET(PPG_sysinfoControlFlags, OMRPORT_SYSINFO_CGROUP_V1_AVAILABLE)) { + if ('\n' == metricElement->value[0]) { + /* Empty file, see cpuset.cpus and cpuset.mems in omrCgroupCpusetMetricMapV2. */ + result = -1; + } else if (OMR_ARE_ANY_BITS_SET(PPG_sysinfoControlFlags, OMRPORT_SYSINFO_CGROUP_V1_AVAILABLE)) { sscanf(metricElement->value, "%" PRId64, &result); } else if (OMR_ARE_ANY_BITS_SET(PPG_sysinfoControlFlags, OMRPORT_SYSINFO_CGROUP_V2_AVAILABLE)) { uint64_t uresult = 0; @@ -6853,7 +6868,7 @@ omrsysinfo_cgroup_subsystem_iterator_next(struct OMRPortLibrary *portLibrary, st } else { Trc_PRT_Assert_ShouldNeverHappen(); } - /* Check that the limit metric is set (not -1) and that it is a reasonable value. */ + /* Check that the metric is set and that it is a reasonable value. */ if ((result > (MAX_DEFAULT_VALUE_CHECK)) || (result < 0)) { metricElement->units = NULL; strcpy(metricElement->value, "Not Set");