Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trust maps file parser if no errors occur #4600

Merged
merged 1 commit into from
Nov 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include_core/omrport.h
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,7 @@ typedef struct J9ProcessorInfos {
#define OMRPORT_CTLDATA_VECTOR_REGS_SUPPORT_ON "VECTOR_REGS_SUPPORT_ON"
#define OMRPORT_CTLDATA_NLS_DISABLE "NLS_DISABLE"
#define OMRPORT_CTLDATA_VMEM_ADVISE_HUGEPAGE "VMEM_ADVISE_HUGEPAGE"
#define OMRPORT_CTLDATA_VMEM_PERFORM_FULL_MEMORY_SEARCH "VMEM_PERFORM_FULL_SEARCH"

#define OMRPORT_FILE_READ_LOCK 1
#define OMRPORT_FILE_WRITE_LOCK 2
Expand Down
8 changes: 8 additions & 0 deletions port/common/omrport.tdf
Original file line number Diff line number Diff line change
Expand Up @@ -1093,3 +1093,11 @@ TraceException=Trc_PRT_sysinfo_get_open_file_count_memAllocFailed Group=sysinfo
TraceException=Trc_PRT_sysinfo_gethostname_error Group=sysinfo Overhead=1 Level=1 NoEnv Template="gethostname failed: errno=%d"

TraceExit-Exception=Trc_PRT_omrsig_ambiguous_signal_flag_failed_exiting Group=signal Overhead=1 Level=1 NoEnv Template="%s failed: Ambiguous port library signal flag(s) received, flags=0x%X."

TraceException=Trc_PRT_vmem_omrvmem_findAvailableMemoryBlockNoMalloc_fileOpenFailed Group=mem Overhead=1 Level=1 NoEnv Template="findAvailableMemoryBlockNoMalloc failed to open file %s, portable error code %d"
TraceException=Trc_PRT_vmem_omrvmem_findAvailableMemoryBlockNoMalloc_fileReadFailed Group=mem Overhead=1 Level=1 NoEnv Template="findAvailableMemoryBlockNoMalloc failed to read from file %s, portable error code %d"

TraceException=Trc_PRT_vmem_omrvmem_findAvailableMemoryBlockNoMalloc_parseFirstAddressFailed Group=mem Overhead=1 Level=5 NoEnv Template="findAvailableMemoryBlockNoMalloc parser failed to get first address from line (%s)"
TraceException=Trc_PRT_vmem_omrvmem_findAvailableMemoryBlockNoMalloc_parseDashFailed Group=mem Overhead=1 Level=5 NoEnv Template="findAvailableMemoryBlockNoMalloc parser failed to get dash from line (%s)"
TraceException=Trc_PRT_vmem_omrvmem_findAvailableMemoryBlockNoMalloc_parseSecondAddressFailed Group=mem Overhead=1 Level=5 NoEnv Template="findAvailableMemoryBlockNoMalloc parser failed to get second address from line (%s)"
TraceException=Trc_PRT_vmem_omrvmem_findAvailableMemoryBlockNoMalloc_addressesMismatch Group=mem Overhead=1 Level=5 NoEnv Template="findAvailableMemoryBlockNoMalloc parser found addresses mismatch from line (%s)"
10 changes: 10 additions & 0 deletions port/common/omrportcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,16 @@ omrport_control(struct OMRPortLibrary *portLibrary, const char *key, uintptr_t v
#endif
return 0;
}

/* work around for case if smart address feature still be not reliable enough */
if (0 == strcmp(OMRPORT_CTLDATA_VMEM_PERFORM_FULL_MEMORY_SEARCH, key)) {
#if defined(PPG_performFullMemorySearch)
Assert_PRT_true((0 == value) || (1 == value));
PPG_performFullMemorySearch = value;
#endif /* PPG_performFullMemorySearch */
return 0;
}

return 1;
}

Expand Down
47 changes: 37 additions & 10 deletions port/linux/omrvmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ static void addressRange_Init(AddressRange *range, ADDRESS start, ADDRESS end);
static BOOLEAN addressRange_Intersect(AddressRange *a, AddressRange *b, AddressRange *result);
static BOOLEAN addressRange_IsValid(AddressRange *range);
static uintptr_t addressRange_Width(AddressRange *range);
static ADDRESS findAvailableMemoryBlockNoMalloc(struct OMRPortLibrary *portLibrary, ADDRESS start, ADDRESS end, uintptr_t byteAmount, BOOLEAN reverse, BOOLEAN strictRange);
static ADDRESS findAvailableMemoryBlockNoMalloc(struct OMRPortLibrary *portLibrary, ADDRESS start, ADDRESS end, uintptr_t byteAmount, BOOLEAN reverse, BOOLEAN strictRange, BOOLEAN *error);

/*
* This structure captures the state of an iterator of addresses between minimum
Expand Down Expand Up @@ -358,7 +358,7 @@ addressRange_Width(AddressRange *range)
* returns the address available.
*/
static ADDRESS
findAvailableMemoryBlockNoMalloc(struct OMRPortLibrary *portLibrary, ADDRESS start, ADDRESS end, uintptr_t byteAmount, BOOLEAN reverse, BOOLEAN strictRange)
findAvailableMemoryBlockNoMalloc(struct OMRPortLibrary *portLibrary, ADDRESS start, ADDRESS end, uintptr_t byteAmount, BOOLEAN reverse, BOOLEAN strictRange, BOOLEAN *error)
{
BOOLEAN dataCorrupt = FALSE;
BOOLEAN matchFound = FALSE;
Expand All @@ -379,6 +379,9 @@ findAvailableMemoryBlockNoMalloc(struct OMRPortLibrary *portLibrary, ADDRESS sta
addressRange_Init(&lastAvailableRange, NULL, NULL);

int fd = -1;

*error = FALSE;

if ((fd = omrfile_open(portLibrary, VMEM_PROC_MAPS_FNAME, EsOpenRead, 0)) != -1) {
char readBuf[1024];
intptr_t bytesRead = 0;
Expand All @@ -401,7 +404,20 @@ findAvailableMemoryBlockNoMalloc(struct OMRPortLibrary *portLibrary, ADDRESS sta
BOOLEAN gotEOF = FALSE;
bytesRead = omrfile_read(portLibrary, fd, readBuf, sizeof(readBuf));
if (-1 == bytesRead) {
break;
int32_t lastErrorCode = omrerror_last_error_number(portLibrary);
/*
* In case of EOF (read() has returned 0) omrfile_read() returns -1
* recognize this case based on last error number stored in Port Library
*/
if (OMRPORT_ERROR_FILE_EOF == lastErrorCode) {
gotEOF = TRUE;
bytesRead = 0;
} else {
/* file read error occur */
dataCorrupt = TRUE;
Trc_PRT_vmem_omrvmem_findAvailableMemoryBlockNoMalloc_fileReadFailed(VMEM_PROC_MAPS_FNAME, lastErrorCode);
break;
}
}

intptr_t readCursor = 0;
Expand All @@ -412,8 +428,7 @@ findAvailableMemoryBlockNoMalloc(struct OMRPortLibrary *portLibrary, ADDRESS sta
* 1. End the line with '\0'.
* 2. Set lineEnd = TRUE when '\n' found.
*/
if (0 == bytesRead) {
gotEOF = TRUE;
if (gotEOF) {
ch = '\n';
} else {
ch = readBuf[readCursor];
Expand Down Expand Up @@ -449,17 +464,20 @@ findAvailableMemoryBlockNoMalloc(struct OMRPortLibrary *portLibrary, ADDRESS sta
start = (uintptr_t)strtoull(lineBuf, &next, 16);
if ((ULLONG_MAX == start) && (ERANGE == errno)) {
dataCorrupt = TRUE;
Trc_PRT_vmem_omrvmem_findAvailableMemoryBlockNoMalloc_parseFirstAddressFailed(lineBuf);
break;
}
/* skip the '-' */
next++;
if (next >= (lineBuf + lineCursor - 1)) {
dataCorrupt = TRUE;
Trc_PRT_vmem_omrvmem_findAvailableMemoryBlockNoMalloc_parseDashFailed(lineBuf);
break;
}
end = (uintptr_t)strtoull(next, &next, 16);
if ((ULLONG_MAX == end) && (ERANGE == errno)) {
dataCorrupt = TRUE;
Trc_PRT_vmem_omrvmem_findAvailableMemoryBlockNoMalloc_parseSecondAddressFailed(lineBuf);
break;
}

Expand All @@ -470,6 +488,7 @@ findAvailableMemoryBlockNoMalloc(struct OMRPortLibrary *portLibrary, ADDRESS sta
if ((currentMmapRange.start >= currentMmapRange.end) ||
(currentMmapRange.start < lastMmapRange.end)) {
dataCorrupt = TRUE;
Trc_PRT_vmem_omrvmem_findAvailableMemoryBlockNoMalloc_addressesMismatch(lineBuf);
break;
}
}
Expand Down Expand Up @@ -533,9 +552,12 @@ findAvailableMemoryBlockNoMalloc(struct OMRPortLibrary *portLibrary, ADDRESS sta
omrfile_close(portLibrary, fd);
} else {
dataCorrupt = TRUE;
Trc_PRT_vmem_omrvmem_findAvailableMemoryBlockNoMalloc_fileOpenFailed(VMEM_PROC_MAPS_FNAME, omrerror_last_error_number(portLibrary));
}

if (dataCorrupt) {
/* File can not be opened, read or parsed */
*error = TRUE;
return NULL;
}

Expand Down Expand Up @@ -1494,10 +1516,11 @@ getMemoryInRangeForDefaultPages(struct OMRPortLibrary *portLibrary, struct J9Por

/* check if we should use quick search for fast performance */
if (OMR_ARE_ANY_BITS_SET(vmemOptions, OMRPORT_VMEM_ALLOC_QUICK)) {
BOOLEAN error = FALSE;
void *smartAddress = findAvailableMemoryBlockNoMalloc(portLibrary,
startAddress, endAddress, byteAmount,
(1 == direction) ? FALSE : TRUE,
OMR_ARE_ANY_BITS_SET(vmemOptions, OMRPORT_VMEM_STRICT_ADDRESS) ? TRUE : FALSE);
OMR_ARE_ANY_BITS_SET(vmemOptions, OMRPORT_VMEM_STRICT_ADDRESS) ? TRUE : FALSE, &error);

if (NULL != smartAddress) {
/* smartAddress is not NULL: try to get memory there */
Expand All @@ -1517,11 +1540,15 @@ getMemoryInRangeForDefaultPages(struct OMRPortLibrary *portLibrary, struct J9Por
memoryPointer = NULL;
}
}
} else {
if ((FALSE == error) && (0 == PPG_performFullMemorySearch)) {
/*
* Memory range has not been found but maps file was parsed properly without errors
* so trust this result and fail allocation except such behavior is overwritten by option
*/
return NULL;
}
}
/*
* memoryPointer != NULL means that available address was found.
* Otherwise, the below logic will continue trying.
*/
}

if (NULL == memoryPointer) {
Expand Down
2 changes: 2 additions & 0 deletions port/unix_include/omrportpg.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ typedef struct OMRPortPlatformGlobals {
uint64_t cgroupSubsystemsAvailable; /**< cgroup subsystems available for port library to use; it is valid only when cgroupEntryList is non-null */
uint64_t cgroupSubsystemsEnabled; /**< cgroup subsystems enabled in port library; it is valid only when cgroupEntryList is non-null */
OMRCgroupEntry *cgroupEntryList; /**< head of the circular linked list, each element contains information about cgroup of the process for a subsystem */
uintptr_t performFullMemorySearch; /**< Always perform full range memory search even smart address can not be established */
BOOLEAN syscallNotAllowed; /**< Assigned True if the mempolicy syscall is failed due to security opts (Can be seen in case of docker) */
#endif /* defined(LINUX) */
} OMRPortPlatformGlobals;
Expand Down Expand Up @@ -136,6 +137,7 @@ typedef struct OMRPortPlatformGlobals {
#define PPG_cgroupSubsystemsEnabled (portLibrary->portGlobals->platformGlobals.cgroupSubsystemsEnabled)
#define PPG_cgroupEntryList (portLibrary->portGlobals->platformGlobals.cgroupEntryList)
#define PPG_numaSyscallNotAllowed (portLibrary->portGlobals->platformGlobals.syscallNotAllowed)
#define PPG_performFullMemorySearch (portLibrary->portGlobals->platformGlobals.performFullMemorySearch)
#endif /* defined(LINUX) */

#endif /* omrportpg_h */
Expand Down