Skip to content

Commit

Permalink
Provide APIs for enabling cgroup subsystems
Browse files Browse the repository at this point in the history
Instead of providing APIs that enable cgroup limits for all
subsystems, a new set of APIs is added which allows to query
which subsystems are available and enable subsystems individually.
This would allow runtimes to enable cgroup subsystems based on their
requirements.
Note that there is another subtle change in the design of the
port library APIs related to cgroup system.
Enabling a cgroup subsystem in portlibrary (by calling
omrsysinfo_cgroup_enable_subsystems) would make the port library APIs
to use cgroup limits internally.
Any port library API that directly returns cgroup limits,
eg omrsysinfo_cgroup_get_memlimit(), does not check whether the
corresponding subsystem (eg memory) is enabled or not.
Therefore, when using omrsysinfo_cgroup_* APIs,
the caller doesn't need to explicitly enable the corresponding
subsystem in the port library.

Consider the case of omrsysinfo_get_physical_memory() which returns
physical memory of the system.
If the system is running in a cgroup, and the cgroup's "memory"
subsystem is enabled, then omrsysinfo_get_physical_memory()
would internally call omrsysinfo_cgroup_get_memlimit(), and
return memory limit imposed by the cgroup.
However, if the user wants to just get the memory limit imposed by the
cgroup, it can directly call omrsysinfo_cgroup_get_memlimit(),
without enabling the "memory" subsystem.

Issue: #1281
Signed-off-by: Ashutosh Mehra <asmehra1@in.ibm.com>
  • Loading branch information
Ashutosh Mehra committed Aug 14, 2017
1 parent 4b395f8 commit 36753bb
Show file tree
Hide file tree
Showing 9 changed files with 252 additions and 92 deletions.
32 changes: 8 additions & 24 deletions fvtest/porttest/si.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2109,33 +2109,25 @@ TEST(PortSysinfoTest, sysinfo_cgroup_get_memlimit)
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
const char *testName = "omrsysinfo_cgroup_get_memlimit";
uint64_t cgroupMemLimit = 0;
int32_t cgroupLimitEnabled = 0;
int32_t rc = 0;

reportTestEntry(OMRPORTLIB, testName);

/* Call omrsysinfo_cgroup_get_memlimit without enabling cgroup limits */
rc = omrsysinfo_cgroup_get_memlimit(&cgroupMemLimit);

#if defined(LINUX)
if (OMRPORT_ERROR_SYSINFO_CGROUP_LIMITS_DISABLED != rc) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_cgroup_get_memlimit returned %d, expected %d\n", rc, OMRPORT_ERROR_SYSINFO_CGROUP_LIMITS_DISABLED);
}
#else
#if !defined(LINUX)
if (OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM != rc) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_cgroup_get_memlimit returned %d, exptected %d on platform that does not support cgroups\n", rc, OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM);
}
#endif

/* Call omrsysinfo_cgroup_get_memlimit after enabling cgroup limits */
cgroupLimitEnabled = omrsysinfo_cgroup_enable_limits();
/* Compare sysinfo_get_physical_memory and sysinfo_cgroup_get_memlimit after enabling memory subsystem */
if (omrsysinfo_cgroup_is_subsystem_available(OMR_CGROUP_SUBSYSTEM_MEMORY)) {
omrsysinfo_cgroup_enable_subsystems(OMR_CGROUP_SUBSYSTEM_MEMORY);

rc = omrsysinfo_cgroup_get_memlimit(&cgroupMemLimit);

#if defined(LINUX)
if (0 == cgroupLimitEnabled) {
if (OMRPORT_ERROR_SYSINFO_CGROUP_LIMITS_DISABLED == rc) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_cgroup_get_memlimit returned %d when cgroup limits was enabled successfully\n", rc);
rc = omrsysinfo_cgroup_get_memlimit(&cgroupMemLimit);
if (0 != rc) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_cgroup_get_memlimit failed with error code %d\n", rc);
} else if (0 == rc) {
uint64_t physicalMemLimit = 0;

Expand All @@ -2144,16 +2136,8 @@ TEST(PortSysinfoTest, sysinfo_cgroup_get_memlimit)
outputErrorMessage(PORTTEST_ERROR_ARGS, "Expected omrsysinfo_cgroup_get_memlimit and omrsysinfo_get_physical_memory to return same value, but omrsysinfo_cgroup_get_memlimit returned %ld and omrsysinfo_get_physical_memory returned %ld\n");
}
}
} else {
if (OMRPORT_ERROR_SYSINFO_CGROUP_LIMITS_DISABLED != rc) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_cgroup_get_memlimit returned %d, expected %d\n", rc, OMRPORT_ERROR_SYSINFO_CGROUP_LIMITS_DISABLED);
}
}
#else
if (OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM != rc) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_cgroup_get_memlimit returned %d, exptected %d on platform that does not support cgroups\n", rc, OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM);
}
#endif

reportTestExit(OMRPORTLIB, testName);
return;
}
29 changes: 20 additions & 9 deletions include_core/omrport.h
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,11 @@ typedef struct OMROSKernelInfo {
uint32_t minorRevision;
} OMROSKernelInfo;

/* bitwise flags indicating cgroup subsystems supported by portlibrary */
#define OMR_CGROUP_SUBSYSTEM_CPU ((uint64_t)0x1)
#define OMR_CGROUP_SUBSYSTEM_MEMORY ((uint64_t)0x2)
#define OMR_CGROUP_SUBSYSTEM_ALL (OMR_CGROUP_SUBSYSTEM_CPU | OMR_CGROUP_SUBSYSTEM_MEMORY)

struct OMRPortLibrary;
typedef struct J9Heap J9Heap;

Expand Down Expand Up @@ -1438,12 +1443,16 @@ typedef struct OMRPortLibrary {
BOOLEAN ( *sysinfo_os_has_feature)(struct OMRPortLibrary *portLibrary, struct OMROSDesc *desc, uint32_t feature) ;
/** see @ref omrsysinfo.c::omrsysinfo_os_kernel_info "omrsysinfo_os_kernel_info"*/
BOOLEAN ( *sysinfo_os_kernel_info)(struct OMRPortLibrary *portLibrary, struct OMROSKernelInfo *kernelInfo) ;
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_is_limits_supported "omrsysinfo_cgroup_is_limits_supported"*/
int32_t ( *sysinfo_cgroup_is_limits_supported)(struct OMRPortLibrary *portLibrary);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_is_limits_enabled "omrsysinfo_cgroup_is_limits_enabled"*/
BOOLEAN ( *sysinfo_cgroup_is_limits_enabled)(struct OMRPortLibrary *portLibrary);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_enable_limits "omrsysinfo_cgroup_enable_limits"*/
int32_t ( *sysinfo_cgroup_enable_limits)(struct OMRPortLibrary *portLibrary);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_is_system_available "omrsysinfo_cgroup_is_system_available"*/
int32_t ( *sysinfo_cgroup_is_system_available)(struct OMRPortLibrary *portLibrary) ;
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_get_available_subsystems "omrsysinfo_cgroup_get_available_subsystems"*/
uint64_t ( *sysinfo_cgroup_get_available_subsystems)(struct OMRPortLibrary *portLibrary);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_is_subsystem_available "omrsysinfo_cgroup_is_subsystem_available"*/
BOOLEAN ( *sysinfo_cgroup_is_subsystem_available)(struct OMRPortLibrary *portLibrary, uint64_t subsystem);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_get_enabled_subsystems "omrsysinfo_cgroup_get_enabled_subsystems"*/
uint64_t ( *sysinfo_cgroup_get_enabled_subsystems)(struct OMRPortLibrary *portLibrary);
/** see @ref omrsysinfo_cgroup_enable_subsystems "omrsysinfo_cgroup_enable_subsystems"*/
uint64_t ( *sysinfo_cgroup_enable_subsystems)(struct OMRPortLibrary *portLibrary, uint64_t requestedSubsystems);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_get_memlimit "omrsysinfo_cgroup_get_memlimit"*/
int32_t (*sysinfo_cgroup_get_memlimit)(struct OMRPortLibrary *portLibrary, uint64_t *limit);
/** see @ref omrport.c::omrport_init_library "omrport_init_library"*/
Expand Down Expand Up @@ -1886,9 +1895,11 @@ extern J9_CFUNC int32_t omrport_getVersion(struct OMRPortLibrary *portLibrary);
#define omrsysinfo_get_os_description(param1) privateOmrPortLibrary->sysinfo_get_os_description(privateOmrPortLibrary, (param1))
#define omrsysinfo_os_has_feature(param1,param2) privateOmrPortLibrary->sysinfo_os_has_feature(privateOmrPortLibrary, (param1), (param2))
#define omrsysinfo_os_kernel_info(param1) privateOmrPortLibrary->sysinfo_os_kernel_info(privateOmrPortLibrary, (param1))
#define omrsysinfo_cgroup_is_limits_supported() privateOmrPortLibrary->sysinfo_cgroup_is_limits_supported(privateOmrPortLibrary)
#define omrsysinfo_cgroup_is_limits_enabled() privateOmrPortLibrary->sysinfo_cgroup_is_limits_enabled(privateOmrPortLibrary)
#define omrsysinfo_cgroup_enable_limits() privateOmrPortLibrary->sysinfo_cgroup_enable_limits(privateOmrPortLibrary)
#define omrsysinfo_cgroup_is_system_available() privateOmrPortLibrary->sysinfo_cgroup_is_system_available(privateOmrPortLibrary)
#define omrsysinfo_cgroup_get_available_subsystems() privateOmrPortLibrary->sysinfo_cgroup_get_available_subsystems(privateOmrPortLibrary)
#define omrsysinfo_cgroup_is_subsystem_available(param1) privateOmrPortLibrary->sysinfo_cgroup_is_subsystem_available(privateOmrPortLibrary, param1)
#define omrsysinfo_cgroup_get_enabled_subsystems() privateOmrPortLibrary->sysinfo_cgroup_get_enabled_subsystems(privateOmrPortLibrary)
#define omrsysinfo_cgroup_enable_subsystems(param1) privateOmrPortLibrary->sysinfo_cgroup_enable_subsystems(privateOmrPortLibrary, param1)
#define omrsysinfo_cgroup_get_memlimit(param1) privateOmrPortLibrary->sysinfo_cgroup_get_memlimit(privateOmrPortLibrary, param1)
#define omrintrospect_startup() privateOmrPortLibrary->introspect_startup(privateOmrPortLibrary)
#define omrintrospect_shutdown() privateOmrPortLibrary->introspect_shutdown(privateOmrPortLibrary)
Expand Down
2 changes: 1 addition & 1 deletion include_core/omrporterror.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@
#define OMRPORT_ERROR_SYSINFO_PROCESS_CGROUP_FILE_DUPLICATE_SUBSYSTEM_ENTRIES (OMRPORT_ERROR_SYSINFO_BASE-20)
#define OMRPORT_ERROR_SYSINFO_SYS_FS_CGROUP_STATFS_FAILED (OMRPORT_ERROR_SYSINFO_BASE-21)
#define OMRPORT_ERROR_SYSINFO_SYS_FS_CGROUP_TMPFS_NOT_MOUNTED (OMRPORT_ERROR_SYSINFO_BASE-22)
#define OMRPORT_ERROR_SYSINFO_CGROUP_LIMITS_DISABLED (OMRPORT_ERROR_SYSINFO_BASE-23)
#define OMRPORT_ERROR_SYSINFO_CGROUP_SUBSYSTEM_UNAVAILABLE (OMRPORT_ERROR_SYSINFO_BASE-23)
#define OMRPORT_ERROR_SYSINFO_CGROUP_NAME_NOT_AVAILABLE (OMRPORT_ERROR_SYSINFO_BASE-24)
#define OMRPORT_ERROR_SYSINFO_CGROUP_MEMLIMIT_FILE_FOPEN_FAILED (OMRPORT_ERROR_SYSINFO_BASE-25)

Expand Down
8 changes: 5 additions & 3 deletions port/common/omrport.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,11 @@ static OMRPortLibrary MasterPortLibraryTable = {
omrsysinfo_get_os_description, /* sysinfo_get_os_description */
omrsysinfo_os_has_feature, /* sysinfo_os_has_feature */
omrsysinfo_os_kernel_info, /* sysinfo_os_kernel_info */
omrsysinfo_cgroup_is_limits_supported, /* sysinfo_cgroup_is_limits_supported */
omrsysinfo_cgroup_is_limits_enabled, /* sysinfo_cgroup_is_limits_enabled */
omrsysinfo_cgroup_enable_limits, /* sysinfo_cgroup_enable_limits */
omrsysinfo_cgroup_is_system_available, /* sysinfo_cgroup_is_system_available */
omrsysinfo_cgroup_get_available_subsystems, /* sysinfo_cgroup_get_available_subsystems */
omrsysinfo_cgroup_is_subsystem_available, /* sysinfo_cgroup_is_subsystem_available */
omrsysinfo_cgroup_get_enabled_subsystems, /* sysinfo_cgroup_get_enabled_subsystems */
omrsysinfo_cgroup_enable_subsystems, /* sysinfo_cgroup_enable_subsystems */
omrsysinfo_cgroup_get_memlimit, /* sysinfo_cgroup_get_memlimit */
omrport_init_library, /* port_init_library */
omrport_startup_library, /* port_startup_library */
Expand Down
60 changes: 46 additions & 14 deletions port/common/omrsysinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -808,42 +808,74 @@ omrsysinfo_os_kernel_info(struct OMRPortLibrary *portLibrary, struct OMROSKernel
}

/**
* Checks if the port library can use cgroup limits
* Returns TRUE if the platform supports cgroup system and
* the port library can use it
*
* @param[in] portLibrary pointer to OMRPortLibrary
*
* @return 0 if the port library can use cgroup limits, otherwise negative error code
* @return 0 if the the cgroup system is available, otherwise negative error code
*/
int32_t
omrsysinfo_cgroup_is_limits_supported(struct OMRPortLibrary *portLibrary)
int32_t
omrsysinfo_cgroup_is_system_available(struct OMRPortLibrary *portLibrary)
{
return OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM;
}

/**
* Returns TRUE if port library is using cgroup limits, FALSE otherwise
* Returns cgroup subsystems available for port library to use
*
* @param[in] portLibrary pointer to OMRPortLibrary
*
* @return TRUE if port library has been enabled to use cgroup limits, FALSE otherwise
* @return bitwise-OR of flags of type OMR_CGROUP_SUBSYSTEMS_* indicating the
* subsystems that are available
*/
BOOLEAN
omrsysinfo_cgroup_is_limits_enabled(struct OMRPortLibrary *portLibrary)
uint64_t
omrsysinfo_cgroup_get_available_subsystems(struct OMRPortLibrary *portLibrary)
{
return 0;
}

/**
* Returns TRUE if specified cgroup subsystem is available for port library to use, FALSE otherwise
*
* @param[in] portLibrary pointer to OMRPortLibrary
* @param[in] subsystem one of the flags of type OMR_CGROUP_SUBSYSTEMS_*
*
* @return TRUE if specified cgroup subsystem is available for port library to use, FALSE otherwise
*/
BOOLEAN
omrsysinfo_cgroup_is_subsystem_available(struct OMRPortLibrary *portLibrary, uint64_t subsystem)
{
return FALSE;
}

/**
* Enable port library to use cgroup limits
* Returns cgroup subsystems enabled for port library to use
*
* @param[in] portLibrary pointer to OMRPortLibrary
* @param[in] portLibrary pointer to OMRPortLibrary
*
* @return 0 if the port library can use cgroup limits, otherwise negative error code
* @return bitwise-OR of flags of type OMR_CGROUP_SUBSYSTEMS_* indicating the
* subsystems that are enbaled
*/
int32_t
omrsysinfo_cgroup_enable_limits(struct OMRPortLibrary *portLibrary)
uint64_t
omrsysinfo_cgroup_get_enabled_subsystems(struct OMRPortLibrary *portLibrary)
{
return OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM;
return 0;
}

/**
* Enable port library to use specified cgroup subsystems
*
* @param[in] portLibrary pointer to OMRPortLibrary
* @param[in] subsystems bitwise-OR of flags of type OMR_CGROUP_SUBSYSTEMS_*
* indicating the subsystems to be enabled
*
* @return bitwise-OR of flags of type OMR_CGROUP_SUBSYSTEMS_* indicating the subsystems that are enabled
*/
uint64_t
omrsysinfo_cgroup_enable_subsystems(struct OMRPortLibrary *portLibrary, uint64_t requestedSubsystems)
{
return 0;
}

/**
Expand Down
16 changes: 10 additions & 6 deletions port/omrportpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -511,12 +511,16 @@ extern J9_CFUNC BOOLEAN
omrsysinfo_os_has_feature(struct OMRPortLibrary *portLibrary, struct OMROSDesc *desc, uint32_t feature);
extern J9_CFUNC BOOLEAN
omrsysinfo_os_kernel_info(struct OMRPortLibrary *portLibrary, struct OMROSKernelInfo *kernelInfo);
extern J9_CFUNC int32_t
omrsysinfo_cgroup_is_limits_supported(struct OMRPortLibrary *portLibrary);
extern J9_CFUNC BOOLEAN
omrsysinfo_cgroup_is_limits_enabled(struct OMRPortLibrary *portLibrary);
extern J9_CFUNC int32_t
omrsysinfo_cgroup_enable_limits(struct OMRPortLibrary *portLibrary);
extern J9_CFUNC int32_t
omrsysinfo_cgroup_is_system_available(struct OMRPortLibrary *portLibrary);
extern J9_CFUNC uint64_t
omrsysinfo_cgroup_get_available_subsystems(struct OMRPortLibrary *portLibrary);
extern J9_CFUNC BOOLEAN
omrsysinfo_cgroup_is_subsystem_available(struct OMRPortLibrary *portLibrary, uint64_t subsystem);
extern J9_CFUNC uint64_t
omrsysinfo_cgroup_get_enabled_subsystems(struct OMRPortLibrary *portLibrary);
extern J9_CFUNC uint64_t
omrsysinfo_cgroup_enable_subsystems(struct OMRPortLibrary *portLibrary, uint64_t requestedSubsystems);
extern J9_CFUNC int32_t
omrsysinfo_cgroup_get_memlimit(struct OMRPortLibrary *portLibrary, uint64_t *limit);

Expand Down
Loading

0 comments on commit 36753bb

Please sign in to comment.