Skip to content

Add guarded virtual memory support for z/OS#8279

Open
VermaSh wants to merge 1 commit into
eclipse-omr:masterfrom
VermaSh:zos_off-heap_memlimit
Open

Add guarded virtual memory support for z/OS#8279
VermaSh wants to merge 1 commit into
eclipse-omr:masterfrom
VermaSh:zos_off-heap_memlimit

Conversation

@VermaSh

@VermaSh VermaSh commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Add guarded virtual memory support to the z/OS vmem path so that object heap and sparse virtual memory reservations can use guarded storage for Balanced GC. This reduces MEMLIMIT pressure by keeping reserved regions guarded until they are committed for use.

Introduce the OMRPORT_VMEM_MEMORY_MODE_GUARDED flag (currently supported only for Balanced GC) to indicate guarding of VLHGC heap and sparse virtual memory reservations. Guarded 1 MB pageable and 4 KB above-the-bar allocations are supported. Guard and unguard operations are implemented using IARV64 guarded storage support.

Signed-off-by: Shubham Verma shubhamv.sv@gmail.com

@VermaSh VermaSh force-pushed the zos_off-heap_memlimit branch from 2bc7269 to e2cdcb2 Compare June 9, 2026 18:27
@VermaSh

VermaSh commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Waiting for my test builds to finish before removing WIP tag.

@VermaSh

VermaSh commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

Almost all test jobs failed because they were unable to find needed jars. While they don't look related but will try running them locally to confirm.

@VermaSh

VermaSh commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Don't see any relevant failures in my local tests. Sanity (minus native lib tests) bucket ran without failures. Doing another run of sanity bucket with native lib tests. I'll set the PR ready for review once my local tests finish.

Opened an issue to investigate why previous build failed.

@VermaSh VermaSh force-pushed the zos_off-heap_memlimit branch from e2cdcb2 to 2343772 Compare June 19, 2026 16:29
@VermaSh VermaSh changed the title WIP Add guarded virtual memory support for z/OS Add guarded virtual memory support for z/OS Jun 19, 2026
@VermaSh

VermaSh commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

My local sanity tests for functional code didn’t have any failures related to this PR. This is ready for review. @dmitripivkine, @joransiu / @r30shah

@VermaSh VermaSh marked this pull request as ready for review June 19, 2026 16:32
Comment thread port/zos390/omrvmem.c Outdated
rc = omrremove_guard((void *)alignedAddress, numSegments);
}

if (0 == rc || ( 4 == rc && identifier->pageSize == FOUR_K)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Would it be better to define return codes? As minimum we should add comment to explain what code 4 means.
  • Please put brackets around logical conditions, do not rely on operations order. Also put FOUR_K at the left:
if ((0 == rc) || ((4 == rc) && (FOUR_K == Identifier->pageSize))) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not mention adding extra brackets to the code below to not pollute it too much, please review.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I have updated the method comment with return code description

Comment thread port/zos390/omrvmem.c Outdated
}

if (0 == rc || ( 4 == rc && identifier->pageSize == FOUR_K)) {
ptr = (void*)alignedAddress;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add space between void and star.

Comment thread port/zos390/omrvmem.c Outdated
/* Skip low memory allocation (malloc31) when OMRPORT_VMEM_MEMORY_MODE_GUARDED flag */
/* is set to avoid MEMLIMIT issues. malloc31() cannot provide guarded memory and */
/* counts against MEMLIMIT. When OMRPORT_VMEM_MEMORY_MODE_GUARDED is set, route all */
/* allocations directly to above-the-bar allocation which avoids MEMLIMIT issues. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use multiline comment format:

/*
 * ...
 * ...
 */

@VermaSh VermaSh force-pushed the zos_off-heap_memlimit branch 2 times, most recently from 2b2a8b6 to ee6aa1f Compare June 23, 2026 15:23
Comment thread port/zos390/omrvmem.c Outdated
@@ -231,12 +251,42 @@ void *
omrvmem_commit_memory(struct OMRPortLibrary *portLibrary, void *address, uintptr_t byteAmount, struct J9PortVmemIdentifier *identifier)
{
void *ptr = NULL;
#if defined(OMR_ENV_DATA64)
uintptr_t numSegments = 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to define this variable for full function scope. It can be define inside if statement close to use.

@VermaSh VermaSh force-pushed the zos_off-heap_memlimit branch 2 times, most recently from f955b57 to 5c7ef76 Compare June 23, 2026 15:38
Comment thread port/zos390/omrvmem.c Outdated
intptr_t rc = -1;
uintptr_t alignedByteAmount = ROUND_UP_TO_POWEROF2(byteAmount, ONE_M);
uintptr_t alignedAddress = ROUND_DOWN_TO_POWEROF2((uintptr_t)address, ONE_M);
if (rangeIsValid(identifier, (void *)alignedAddress, alignedByteAmount)) {

@dmitripivkine dmitripivkine Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this check is not necessary. We can rely on guarded allocation pattern: actual allocation for guarded memory happen to be done in 1m pages. So rounding up to 1m should be valid regardless requested size. And yes, we need comment about this here explaining why rounding to 1m is necessary. The same point is applicable to decommit function as well.

@VermaSh VermaSh force-pushed the zos_off-heap_memlimit branch from 5c7ef76 to d9d4d5b Compare June 23, 2026 15:47
Comment thread port/zos390/omrvmem.c Outdated
if (0 == result && OMR_ARE_ANY_BITS_SET(identifier->mode, OMRPORT_VMEM_MEMORY_MODE_GUARDED)) {
uintptr_t alignedByteAmount = ROUND_DOWN_TO_POWEROF2(byteAmount, ONE_M);
uintptr_t alignedAddress = ROUND_UP_TO_POWEROF2((uintptr_t)address, ONE_M);
if (rangeIsValid(identifier, (void *)alignedAddress, alignedByteAmount)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as for commit above

Add guarded virtual memory support to the z/OS vmem path so that object
heap and sparse virtual memory reservations can use guarded storage for
Balanced GC. This reduces MEMLIMIT pressure by keeping reserved regions
guarded until they are committed for use.

Introduce the OMRPORT_VMEM_MEMORY_MODE_GUARDED flag (currently supported
only for Balanced GC) to indicate guarding of VLHGC heap and sparse
virtual memory reservations. Guarded 1 MB pageable and 4 KB
above-the-bar allocations are supported. Guard and unguard operations
are implemented using IARV64 guarded storage support.

Signed-off-by: Shubham Verma <shubhamv.sv@gmail.com>
@VermaSh VermaSh force-pushed the zos_off-heap_memlimit branch from d9d4d5b to eb891af Compare June 23, 2026 17:09
Comment thread port/zos390/omriarv64.c
__asm(" IARV64 PLISTVER=MAX,MF=(L,SGETSTOR)":"DS"(wgetstor));

segments = *numMBSegments;
wgetstor = ngetstor;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ngetstor should be referencing the sgetstor you declared globally for this function.

Comment thread port/zos390/omriarv64.c
*/
void *omrallocate_1M_pageable_pages_guarded_above_bar(int *numMBSegments, int *userExtendedPrivateAreaMemoryType, const char *ttkn) {
long segments;
long origin;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should initialize these variables with a default value.

Comment thread port/zos390/omriarv64.c

switch (useMemoryType) {
case ZOS64_VMEM_ABOVE_BAR_GENERAL:
break;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since iarv64_rc is initialized to 0, won't we return a potentially garbage (uninitialized) value of origin?

Comment thread port/zos390/omriarv64.c
*/
void *omrallocate_4K_pages_guarded_in_userExtendedPrivateArea(int *numMBSegments, int *userExtendedPrivateAreaMemoryType, const char *ttkn) {
long segments;
long origin;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These variables should be initialized.

Comment thread port/zos390/omriarv64.c
__asm(" IARV64 PLISTVER=MAX,MF=(L,EGETSTOR)":"DS"(wgetstor));

segments = *numMBSegments;
wgetstor = rgetstor;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rgetstor should be egetstor.

@VermaSh

VermaSh commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

@dmitripivkine I have updated the PR based on your feedback. It's ready for another review.

Comment thread port/zos390/omrvmem.c
@@ -534,7 +602,7 @@ reservePagesAboveBar(struct OMRPortLibrary *portLibrary, J9PortVmemIdentifier *i
uintptr_t userExtendedPrivateAreaMemoryType = ZOS64_VMEM_ABOVE_BAR_GENERAL;
uintptr_t userExtendedPrivateAreaMemoryMax = 0;

if (OMRPORT_VMEM_ZOS_USE2TO32G_AREA == (OMRPORT_VMEM_ZOS_USE2TO32G_AREA & options)) {
if (OMR_ARE_ANY_BITS_SET(mode, OMRPORT_VMEM_MEMORY_MODE_GUARDED) || OMRPORT_VMEM_ZOS_USE2TO32G_AREA == (OMRPORT_VMEM_ZOS_USE2TO32G_AREA & options)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use OMR_ARE_ANY_BITS_SET for OMRPORT_VMEM_ZOS_USE2TO32G_AREA flag in options as well for consistency

Comment thread port/zos390/omrvmem.c
/* omrvmem_support_above_bar.s */
#pragma linkage(omrallocate_4K_pages_in_userExtendedPrivateArea,OS_NOSTACK)
void * omrallocate_4K_pages_in_userExtendedPrivateArea(int numMBSegments, int userExtendedPrivateAreaMemoryType, const char * ttkn);

/* omrvmem_support_above_bar.s */
#pragma linkage(omrallocate_4K_pages_guarded_in_userExtendedPrivateArea,OS_NOSTACK)
void * omrallocate_4K_pages_guarded_in_userExtendedPrivateArea(int numMBSegments, int userExtendedPrivateAreaMemoryType, const char * ttkn);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to have extra space after star (two occurrences). You can fix formatting in the previous pragma as well if you like.

Comment thread port/zos390/omrvmem.c
@@ -280,6 +328,26 @@ omrvmem_decommit_memory(struct OMRPortLibrary *portLibrary, void *address, uintp
case OMRPORT_VMEM_RESERVE_USED_J9ALLOCATE_4K_PAGES_ABOVE_BAR: /* FALLTHROUGH */
case OMRPORT_VMEM_RESERVE_USED_MOSERVICES:
result = omrdiscard_data((void *)address, byteAmount >> ZOS_REAL_FRAME_SIZE_SHIFT);
if (0 == result && OMR_ARE_ANY_BITS_SET(identifier->mode, OMRPORT_VMEM_MEMORY_MODE_GUARDED)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add extra brackets around logical conditions

Comment thread port/zos390/omrvmem.c
/* determine number of 1MB segments required */
uintptr_t numSegments = alignedByteAmount / ONE_M;
result = omradd_guard((void *)address, numSegments);
if (4 == result && FOUR_K == identifier->pageSize) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add extra brackets around logical conditions

Comment thread port/zos390/omrvmem.c
uintptr_t numSegments = alignedByteAmount / ONE_M;
rc = omrremove_guard((void *)alignedAddress, numSegments);

if (0 == rc || (4 == rc && FOUR_K == identifier->pageSize)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add extra brackets around logical conditions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants