Skip to content

Commit

Permalink
Update omrsysinfo_cgroup_subsystem_iterator functions for cgroup v2
Browse files Browse the repository at this point in the history
Update cgroup iterator functions to retrieve metrics from cgroup v2
files.

Issue: #1281
Signed-off-by: Eric Yang <[email protected]>
  • Loading branch information
EricYangIBM committed Apr 28, 2022
1 parent bc9bf63 commit 99958d9
Showing 1 changed file with 54 additions and 5 deletions.
59 changes: 54 additions & 5 deletions port/unix/omrsysinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,16 @@ static struct OMRCgroupMetricInfoElement oomControlMetricElementList[] = {
{ "Under OOM", "under_oom", NULL, FALSE }
};

static struct OMRCgroupMetricInfoElement memEventsMetricElementList[] = {
{ "Approached memory limit count", "max", NULL, FALSE },
{ "Reached memory limit count", "oom", NULL, FALSE }
};

static struct OMRCgroupMetricInfoElement swapEventsMetricElementList[] = {
{ "Approached swap limit count", "max", NULL, FALSE },
{ "Swap alloc failed count", "fail", NULL, FALSE }
};

static struct OMRCgroupMetricInfoElement cpuStatMetricElementList[] = {
{ "Period intervals elapsed count", "nr_periods", NULL, FALSE },
{ "Throttled count", "nr_throttled", NULL, FALSE },
Expand All @@ -442,7 +452,9 @@ typedef struct OMRCgroupSubsystemMetricMap {
int32_t metricElementsCount;
} OMRCgroupSubsystemMetricMap;

static struct OMRCgroupSubsystemMetricMap omrCgroupMemoryMetricMap[] = {
static OMRCgroupSubsystemMetricMap *omrCgroupMemoryMetricMap;

static struct OMRCgroupSubsystemMetricMap omrCgroupMemoryMetricMapV1[] = {
{ "memory.limit_in_bytes", &(OMRCgroupMetricInfoElement){ "Memory Limit", NULL, "bytes", TRUE }, SINGLE_CGROUP_METRIC },
{ "memory.memsw.limit_in_bytes", &(OMRCgroupMetricInfoElement){ "Memory + Swap Limit", NULL, "bytes", TRUE }, SINGLE_CGROUP_METRIC },
{ "memory.usage_in_bytes", &(OMRCgroupMetricInfoElement){ "Memory Usage", NULL, "bytes", FALSE }, SINGLE_CGROUP_METRIC },
Expand All @@ -453,6 +465,17 @@ static struct OMRCgroupSubsystemMetricMap omrCgroupMemoryMetricMap[] = {
{ "memory.memsw.failcnt", &(OMRCgroupMetricInfoElement){ "Memory + Swap limit exceeded count", NULL, NULL, FALSE }, SINGLE_CGROUP_METRIC },
{ "memory.oom_control", &oomControlMetricElementList[0], sizeof(oomControlMetricElementList)/sizeof(oomControlMetricElementList[0]) }
};
#define OMR_CGROUP_MEMORY_METRIC_MAP_V1_SIZE sizeof(omrCgroupMemoryMetricMapV1) / sizeof(omrCgroupMemoryMetricMapV1[0])

static struct OMRCgroupSubsystemMetricMap omrCgroupMemoryMetricMapV2[] = {
{ "memory.max", &(OMRCgroupMetricInfoElement){ "Memory Limit", NULL, "bytes", TRUE }, SINGLE_CGROUP_METRIC },
{ "memory.swap.max", &(OMRCgroupMetricInfoElement){ "Memory + Swap Limit", NULL, "bytes", TRUE }, SINGLE_CGROUP_METRIC },
{ "memory.current", &(OMRCgroupMetricInfoElement){ "Memory Usage", NULL, "bytes", FALSE }, SINGLE_CGROUP_METRIC },
{ "memory.swap.current", &(OMRCgroupMetricInfoElement){ "Memory + Swap Usage", NULL, "bytes", FALSE }, SINGLE_CGROUP_METRIC },
{ "memory.events", &memEventsMetricElementList[0], sizeof(memEventsMetricElementList)/sizeof(swapEventsMetricElementList[0]) },
{ "memory.swap.events", &swapEventsMetricElementList[0], sizeof(swapEventsMetricElementList)/sizeof(swapEventsMetricElementList[0]) }
};
#define OMR_CGROUP_MEMORY_METRIC_MAP_V2_SIZE sizeof(omrCgroupMemoryMetricMapV2) / sizeof(omrCgroupMemoryMetricMapV2[0])

static struct OMRCgroupSubsystemMetricMap omrCgroupCpuMetricMap[] = {
{ "cpu.cfs_period_us", &(OMRCgroupMetricInfoElement){ "CPU Period", NULL, "microseconds", FALSE }, SINGLE_CGROUP_METRIC },
Expand Down Expand Up @@ -6569,12 +6592,23 @@ omrsysinfo_cgroup_subsystem_iterator_init(struct OMRPortLibrary *portLibrary, ui
Assert_PRT_true(NULL != state);
int32_t rc = OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM;
#if defined(LINUX) && !defined(OMRZTPF)
size_t omrCgroupMemoryMetricMapSize = 0;
state->count = 0;
state->subsystemid = subsystem;
state->fileMetricCounter = 0;
if (OMR_ARE_ANY_BITS_SET(PPG_sysinfoControlFlags, OMRPORT_SYSINFO_CGROUP_V1_AVAILABLE)) {
omrCgroupMemoryMetricMap = omrCgroupMemoryMetricMapV1;
omrCgroupMemoryMetricMapSize = OMR_CGROUP_MEMORY_METRIC_MAP_V1_SIZE;
} else if (OMR_ARE_ANY_BITS_SET(PPG_sysinfoControlFlags, OMRPORT_SYSINFO_CGROUP_V2_AVAILABLE)) {
omrCgroupMemoryMetricMap = omrCgroupMemoryMetricMapV2;
omrCgroupMemoryMetricMapSize = OMR_CGROUP_MEMORY_METRIC_MAP_V2_SIZE;
} else {
Trc_PRT_Assert_ShouldNeverHappen();
}

switch (subsystem) {
case OMR_CGROUP_SUBSYSTEM_MEMORY :
state->numElements = sizeof(omrCgroupMemoryMetricMap) / sizeof(omrCgroupMemoryMetricMap[0]);
state->numElements = omrCgroupMemoryMetricMapSize;
break;
case OMR_CGROUP_SUBSYSTEM_CPU :
state->numElements = sizeof(omrCgroupCpuMetricMap) / sizeof(omrCgroupCpuMetricMap[0]);
Expand Down Expand Up @@ -6664,6 +6698,7 @@ omrsysinfo_cgroup_subsystem_iterator_next(struct OMRPortLibrary *portLibrary, st
subsystemMetricMapElement = &subsystemMetricMap[state->count];
currentElement = subsystemMetricMapElement->metricInfoElementList;
if (NULL == state->fileContent) {
Assert_PRT_true(0 == state->fileMetricCounter);
rc = readCgroupMetricFromFile(portLibrary, state->subsystemid, subsystemMetricMapElement->metricFileName, currentElement->metricKeyInFile, &(state->fileContent), metricElement->value);

/* In error condition or single metric condition we increment the counter to continue to next metric */
Expand All @@ -6672,8 +6707,6 @@ omrsysinfo_cgroup_subsystem_iterator_next(struct OMRPortLibrary *portLibrary, st
state->count += 1;
goto _end;
}

state->fileMetricCounter = 0;
}

if (state->fileMetricCounter < subsystemMetricMapElement->metricElementsCount) {
Expand Down Expand Up @@ -6718,6 +6751,9 @@ omrsysinfo_cgroup_subsystem_iterator_next(struct OMRPortLibrary *portLibrary, st
state->fileContent = NULL;
}
state->count += 1;
/* Reset fileMetricCounter here so that a call to omrsysinfo_cgroup_subsystem_iterator_metricKey
* immediately after won't fail. */
state->fileMetricCounter = 0;
}

_end:
Expand All @@ -6733,7 +6769,20 @@ omrsysinfo_cgroup_subsystem_iterator_next(struct OMRPortLibrary *portLibrary, st
}
if (currentElement->isValueToBeChecked) {
int64_t result = 0;
sscanf(metricElement->value, "%" PRId64, &result);
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;
scanCgroupIntOrMax(portLibrary, metricElement->value, &uresult);
if (UINT_MAX == uresult) {
result = -1;
} else {
result = (int64_t)uresult;
}
} else {
Trc_PRT_Assert_ShouldNeverHappen();
}
/* Check that the limit metric is set (not -1) and that it is a reasonable value */
if ((result > (MAX_DEFAULT_VALUE_CHECK)) || (result < 0)) {
metricElement->units = NULL;
strcpy(metricElement->value, "Not Set");
Expand Down

0 comments on commit 99958d9

Please sign in to comment.