Skip to content

Commit

Permalink
Read system swappiness in omrsysinfo_get_memory_info()
Browse files Browse the repository at this point in the history
The code read swappiness value on Linux and sets
OMRPORT_MEMINFO_NOT_AVAILABLE if the value is not available.
The system wide swappiness value specified at
/proc/sys/vm/swappiness for vm.swappiness is read.

Closes: eclipse-omr#5237

Signed-off-by: SajinaKandy <[email protected]>
  • Loading branch information
SajinaKandy committed Oct 11, 2023
1 parent 612cde0 commit ba1e956
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 0 deletions.
3 changes: 3 additions & 0 deletions fvtest/porttest/si.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,9 @@ TEST(PortSysinfoTest, sysinfo_testMemoryInfo)
#else /* defined (OSX) */
|| (OMRPORT_MEMINFO_NOT_AVAILABLE == memInfo.cached)
#endif /* defined(OSX) */
#if defined (LINUX)
|| (OMRPORT_MEMINFO_NOT_AVAILABLE == memInfo.swappiness)
#endif /* defined(LINUX) */
) {

/* Fail pltest if one of these memory usage parameters were found inconsistent. */
Expand Down
5 changes: 5 additions & 0 deletions include_core/omrport.h
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,11 @@ typedef struct J9MemoryInfo {
* When not in a cgroup, this will be identical to 'buffered' field above.
*/
uint64_t hostBuffered;
/* The default setting for this kernel parameter of swappiness is 60. Value of 0 disables swap.
* Lower swappiness values would keep more pages in memory instead of putting them in swap space.
* Higher values will provide more I/O cache and lower values will wait longer to swap out idle application.
*/
uint64_t swappiness;
} J9MemoryInfo;

#define OMRPORT_MEMINFO_NOT_AVAILABLE ((uint64_t) -1)
Expand Down
2 changes: 2 additions & 0 deletions include_core/omrporterror.h
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,8 @@
#define OMRPORT_ERROR_SYSINFO_CGROUP_VERSION_NOT_AVAILABLE (OMRPORT_ERROR_SYSINFO_BASE-28)
#define OMRPORT_ERROR_SYSINFO_CGROUP_FILENAME_INVALID (OMRPORT_ERROR_SYSINFO_BASE-29)
#define OMRPORT_ERROR_SYSINFO_CGROUP_NULL_PARAM (OMRPORT_ERROR_SYSINFO_BASE-30)
#define OMRPORT_ERROR_SYSINFO_ERROR_SWAPPINESS_OPEN_FAILED (OMRPORT_ERROR_SYSINFO_BASE-31)
#define OMRPORT_ERROR_SYSINFO_ERROR_READING_SWAPPINESS (OMRPORT_ERROR_SYSINFO_BASE-32)

/**
* @name Port library initialization return codes
Expand Down
4 changes: 4 additions & 0 deletions port/common/omrport.tdf
Original file line number Diff line number Diff line change
Expand Up @@ -1626,3 +1626,7 @@ TraceExit-Exception=Trc_PRT_mmap_map_file_unix_filestatfailed_exit Group=mmap Ov
TraceExit-Exception=Trc_PRT_mmap_map_file_cannotallocatehandle_exit Group=mmap Overhead=1 Level=1 NoEnv Template="omrmmap_map_file: Could not allocate memory for handle"

TraceEvent=Trc_PRT_sl_open_shared_library_noload Group=sl Overhead=1 Level=3 NoEnv Template="omrsl_open_shared_library tests if a library is already loaded, returns handle=%p"

TraceException=Trc_PRT_retrieveLinuxMemoryStats_failedOpeningSwappinessFs Group=sysinfo Overhead=1 Level=1 NoEnv Template="retrieveLinuxMemoryStats: Failed to open /proc/sys/vm/swappiness. Error code = %d."
TraceException=Trc_PRT_retrieveLinuxMemoryStats_failedReadingSwappiness Group=sysinfo Overhead=1 Level=1 NoEnv Template="retrieveLinuxMemoryStats: Failed to read /proc/sys/vm/swappiness. Error code = %d."
TraceException=Trc_PRT_retrieveLinuxMemoryStats_unexpectedSwappinessFormat Group=sysinfo Overhead=1 Level=1 NoEnv Template="retrieveLinuxMemoryStats: Expected %d items to read, but read %d items."
33 changes: 33 additions & 0 deletions port/unix/omrsysinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ struct {

/* Cgroup v1 and v2 memory files */
#define CGROUP_MEMORY_STAT_FILE "memory.stat"
#define CGROUP_MEMORY_SWAPPINESS "memory.swappiness"

/* Cgroup v1 memory files */
#define CGROUP_MEMORY_LIMIT_IN_BYTES_FILE "memory.limit_in_bytes"
Expand Down Expand Up @@ -3257,6 +3258,8 @@ omrsysinfo_get_number_CPUs_by_type(struct OMRPortLibrary *portLibrary, uintptr_t
#define BUFFERS_PREFIX "Buffers:"
#define BUFFERS_PREFIX_SZ (sizeof(BUFFERS_PREFIX) - 1)

#define PROC_SYS_VM_SWAPPINESS "/proc/sys/vm/swappiness"

/**
* Function collects memory usage statistics by reading /proc/meminfo on Linux platforms.
*
Expand All @@ -3269,7 +3272,9 @@ static int32_t
retrieveLinuxMemoryStatsFromProcFS(struct OMRPortLibrary *portLibrary, struct J9MemoryInfo *memInfo)
{
int32_t rc = 0;
int32_t rcSwappiness = 0;
FILE *memStatFs = NULL;
FILE *swappinessFs = NULL;
char lineString[MAX_LINE_LENGTH] = {0};

/* Open the memstat file on Linux for reading; this is readonly. */
Expand Down Expand Up @@ -3380,6 +3385,24 @@ retrieveLinuxMemoryStatsFromProcFS(struct OMRPortLibrary *portLibrary, struct J9
} /* end if else-if */
} /* end while() */

swappinessFs = fopen(PROC_SYS_VM_SWAPPINESS, "r");
if (NULL == swappinessFs) {
Trc_PRT_retrieveLinuxMemoryStats_failedOpeningSwappinessFs(errno);
rc = OMRPORT_ERROR_SYSINFO_ERROR_SWAPPINESS_OPEN_FAILED;
goto _cleanup;
}

rcSwappiness = fscanf(swappinessFs, "%" SCNu64, &memInfo->swappiness);
if (1 != rcSwappiness) {
if (EOF == rcSwappiness) {
Trc_PRT_retrieveLinuxMemoryStats_failedReadingSwappiness(errno);
} else {
Trc_PRT_retrieveLinuxMemoryStats_unexpectedSwappinessFormat(1, rcSwappiness);
}
rc = OMRPORT_ERROR_SYSINFO_ERROR_READING_SWAPPINESS;
goto _cleanup;
}

/* Set hostXXX fields with memory stats from proc fs.
* These may be used for calculating available physical memory on the host.
*/
Expand All @@ -3391,6 +3414,9 @@ retrieveLinuxMemoryStatsFromProcFS(struct OMRPortLibrary *portLibrary, struct J9
if (NULL != memStatFs) {
fclose(memStatFs);
}
if (NULL != swappinessFs) {
fclose(swappinessFs);
}

return rc;
}
Expand Down Expand Up @@ -3482,6 +3508,11 @@ retrieveLinuxCgroupMemoryStats(struct OMRPortLibrary *portLibrary, struct OMRCgr
cgroupMemInfo->memoryAndSwapUsage += cgroupMemInfo->memoryUsage;
}

rc = readCgroupSubsystemFile(portLibrary, OMR_CGROUP_SUBSYSTEM_MEMORY, CGROUP_MEMORY_SWAPPINESS, numItemsToRead, "%" SCNu64, &cgroupMemInfo->swappiness);
if (0 != rc) {
goto _exit;
}

/* Read value of page cache memory from memory.stat file */
rc = getHandleOfCgroupSubsystemFile(portLibrary, OMR_CGROUP_SUBSYSTEM_MEMORY, CGROUP_MEMORY_STAT_FILE, &memStatFs);
if (0 != rc) {
Expand Down Expand Up @@ -3607,6 +3638,7 @@ retrieveLinuxMemoryStats(struct OMRPortLibrary *portLibrary, struct J9MemoryInfo
}
}

memInfo->swappiness = cgroupMemInfo.swappiness;
memInfo->cached = cgroupMemInfo.cached;
/* Buffered value is not available when running in a cgroup.
* See https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt
Expand Down Expand Up @@ -3771,6 +3803,7 @@ omrsysinfo_get_memory_info(struct OMRPortLibrary *portLibrary, struct J9MemoryIn
memInfo->availSwap = OMRPORT_MEMINFO_NOT_AVAILABLE;
memInfo->cached = OMRPORT_MEMINFO_NOT_AVAILABLE;
memInfo->buffered = OMRPORT_MEMINFO_NOT_AVAILABLE;
memInfo->swappiness = OMRPORT_MEMINFO_NOT_AVAILABLE;

memInfo->hostAvailPhysical = OMRPORT_MEMINFO_NOT_AVAILABLE;
memInfo->hostCached = OMRPORT_MEMINFO_NOT_AVAILABLE;
Expand Down
1 change: 1 addition & 0 deletions port/unix_include/omrcgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ typedef struct OMRCgroupMemoryInfo {
uint64_t memoryUsage; /**< current memory usage in bytes (as in memory.usage_in_bytes file)*/
uint64_t memoryAndSwapLimit; /**< memory + swap limit in bytes (as in memory.memsw.limit_in_bytes file)*/
uint64_t memoryAndSwapUsage; /**< current memory + swap usage in bytes (as in memory.memsw.usage_in_bytes file) */
uint64_t swappiness; /**< indicates kernel aggressiveness (0-100) in swapping memory pages for cgroups, and is not supported on cgroups V2 */
uint64_t cached; /**< page cache memory (as in memory.stat file)*/
} OMRCgroupMemoryInfo;

Expand Down
1 change: 1 addition & 0 deletions port/win32/omrsysinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,7 @@ omrsysinfo_get_memory_info(struct OMRPortLibrary *portLibrary, struct J9MemoryIn
memInfo->availSwap = OMRPORT_MEMINFO_NOT_AVAILABLE;
memInfo->cached = OMRPORT_MEMINFO_NOT_AVAILABLE;
memInfo->buffered = OMRPORT_MEMINFO_NOT_AVAILABLE;
memInfo->swappiness = OMRPORT_MEMINFO_NOT_AVAILABLE;

aMemStatusEx.dwLength = sizeof(aMemStatusEx);
rc = GlobalMemoryStatusEx(&aMemStatusEx);
Expand Down

0 comments on commit ba1e956

Please sign in to comment.