From 2f4aca36607990b3fc9b2ff06d69b49e580c2fd3 Mon Sep 17 00:00:00 2001 From: Jason Feng Date: Mon, 16 May 2022 19:28:50 -0400 Subject: [PATCH] CRIU j9time_nano_time skips the elapsed time between Checkpoint/Restore Added a field checkpointRestoreTimeDelta within J9PortLibrary, which is to be set the time delta between Checkpoint and Restore of j9time_nano_time() return values; Updated trace points to record the actual j9time_nano_time() values; Add a test to verify the elapsed time. Signed-off-by: Jason Feng --- runtime/criusupport/criusupport.cpp | 10 +++- runtime/criusupport/j9criu.tdf | 4 +- runtime/oti/j9port_generated.h | 16 +++++- test/functional/cmdLineTests/criu/criu.xml | 9 ++-- .../cmdLineTests/criu/criuRandomScript.sh | 2 +- .../cmdLineTests/criu/criuScript.sh | 6 +-- .../cmdLineTests/criu/criuSecurityScript.sh | 2 +- .../cmdLineTests/criu/criu_nonPortable.xml | 17 ++++++- .../{ => org/openj9/criu}/CRIURandomTest.java | 1 + .../openj9/criu}/CRIUSecurityTest.java | 1 + .../{ => org/openj9/criu}/CRIUSimpleTest.java | 2 + .../{ => org/openj9/criu}/CRIUTestUtils.java | 2 + .../src/org/openj9/criu/TimeChangeTest.java | 49 +++++++++++++++++++ 13 files changed, 104 insertions(+), 17 deletions(-) rename test/functional/cmdLineTests/criu/src/{ => org/openj9/criu}/CRIURandomTest.java (99%) rename test/functional/cmdLineTests/criu/src/{ => org/openj9/criu}/CRIUSecurityTest.java (99%) rename test/functional/cmdLineTests/criu/src/{ => org/openj9/criu}/CRIUSimpleTest.java (98%) rename test/functional/cmdLineTests/criu/src/{ => org/openj9/criu}/CRIUTestUtils.java (98%) create mode 100644 test/functional/cmdLineTests/criu/src/org/openj9/criu/TimeChangeTest.java diff --git a/runtime/criusupport/criusupport.cpp b/runtime/criusupport/criusupport.cpp index 9bb7768aad9..31375f32b99 100644 --- a/runtime/criusupport/criusupport.cpp +++ b/runtime/criusupport/criusupport.cpp @@ -259,6 +259,8 @@ Java_org_eclipse_openj9_criu_CRIUSupport_checkpointJVMImpl(JNIEnv *env, char workDirBuf[STRING_BUFFER_SIZE]; char *workDirChars = workDirBuf; BOOLEAN isAfterCheckpoint = FALSE; + I_64 beforeCheckpoint = 0; + I_64 afterRestore = 0; vmFuncs->internalEnterVMFromJNI(currentThread); @@ -399,9 +401,13 @@ Java_org_eclipse_openj9_criu_CRIUSupport_checkpointJVMImpl(JNIEnv *env, goto wakeJavaThreadsWithExclusiveVMAccess; } - Trc_CRIU_before_checkpoint(currentThread); + vm->portLibrary->checkpointRestoreTimeDelta = 0; + beforeCheckpoint = j9time_nano_time(); + Trc_CRIU_before_checkpoint(currentThread, beforeCheckpoint); systemReturnCode = criu_dump(); - Trc_CRIU_after_checkpoint(currentThread); + afterRestore = j9time_nano_time(); + vm->portLibrary->checkpointRestoreTimeDelta = afterRestore - beforeCheckpoint; + Trc_CRIU_after_checkpoint(currentThread, afterRestore, vm->portLibrary->checkpointRestoreTimeDelta); if (systemReturnCode < 0) { currentExceptionClass = vm->criuSystemCheckpointExceptionClass; nlsMsgFormat = j9nls_lookup_message(J9NLS_DO_NOT_PRINT_MESSAGE_TAG | J9NLS_DO_NOT_APPEND_NEWLINE, J9NLS_JCL_CRIU_DUMP_FAILED, NULL); diff --git a/runtime/criusupport/j9criu.tdf b/runtime/criusupport/j9criu.tdf index 7842d15fd02..6d2ac493091 100644 --- a/runtime/criusupport/j9criu.tdf +++ b/runtime/criusupport/j9criu.tdf @@ -33,7 +33,7 @@ TraceAssert=Assert_CRIU_mustNotHaveVMAccess noEnv Overhead=1 Level=1 Assert="0 = TraceException=Trc_CRIU_getNativeString_getStringSizeFail Overhead=1 Level=1 Template="Failed to get Java string size: mutf8String=%s mutf8StringSize=%zu" TraceException=Trc_CRIU_getNativeString_convertFail Overhead=1 Level=1 Template="Failed to convert Java string: mutf8String=%s mutf8StringSize=%zu requiredConvertedStringSize=%zd" -TraceEvent=Trc_CRIU_before_checkpoint Overhead=1 Level=2 Template="Before checkpoint criu_dump()" -TraceEvent=Trc_CRIU_after_checkpoint Overhead=1 Level=2 Template="After checkpoint criu_dump()" +TraceEvent=Trc_CRIU_before_checkpoint Overhead=1 Level=2 Template="Before checkpoint criu_dump(), beforeCheckpoint = %lld" +TraceEvent=Trc_CRIU_after_checkpoint Overhead=1 Level=2 Template="After checkpoint criu_dump(), afterRestore = %lld, checkpointRestoreTimeDelta = %lld" TraceEntry=Trc_CRIU_checkpointJVMImpl_Entry Overhead=1 Level=2 Template="Java_org_eclipse_openj9_criu_CRIUSupport_checkpointJVMImpl" TraceExit=Trc_CRIU_checkpointJVMImpl_Exit Overhead=1 Level=2 Template="Java_org_eclipse_openj9_criu_CRIUSupport_checkpointJVMImpl" diff --git a/runtime/oti/j9port_generated.h b/runtime/oti/j9port_generated.h index 102400726d3..b7a44f5e920 100644 --- a/runtime/oti/j9port_generated.h +++ b/runtime/oti/j9port_generated.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 1991, 2021 IBM Corp. and others + * Copyright (c) 1991, 2022 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -387,6 +387,13 @@ typedef struct J9PortLibrary { #endif /* OMR_GC_CONCURRENT_SCAVENGER */ /** see @ref j9portcontrol.c::j9port_control "j9port_control"*/ int32_t (*port_control)(struct J9PortLibrary *portLibrary, const char *key, uintptr_t value) ; +#if defined(J9VM_OPT_CRIU_SUPPORT) + /* The delta between Checkpoint and Restore of j9time_nano_time() return values. + * It is initialized to 0 before Checkpoint, and set after restore. + * Only supports one Checkpoint, could be restored multiple times. + */ + int64_t checkpointRestoreTimeDelta; +#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */ } J9PortLibrary; #if defined(OMR_PORT_CAN_RESERVE_SPECIFIC_ADDRESS) @@ -467,7 +474,12 @@ extern J9_CFUNC int32_t j9port_isCompatible(struct J9PortLibraryVersion *expecte #define j9time_usec_clock() OMRPORT_FROM_J9PORT(privatePortLibrary)->time_usec_clock(OMRPORT_FROM_J9PORT(privatePortLibrary)) #define j9time_current_time_nanos(param1) OMRPORT_FROM_J9PORT(privatePortLibrary)->time_current_time_nanos(OMRPORT_FROM_J9PORT(privatePortLibrary),param1) #define j9time_current_time_millis() OMRPORT_FROM_J9PORT(privatePortLibrary)->time_current_time_millis(OMRPORT_FROM_J9PORT(privatePortLibrary)) -#define j9time_nano_time() OMRPORT_FROM_J9PORT(privatePortLibrary)->time_nano_time(OMRPORT_FROM_J9PORT(privatePortLibrary)) +#if defined(J9VM_OPT_CRIU_SUPPORT) +#define NANO_TIME_ADJUSTMENT privatePortLibrary->checkpointRestoreTimeDelta +#else /* defined(J9VM_OPT_CRIU_SUPPORT) */ +#define NANO_TIME_ADJUSTMENT 0 +#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */ +#define j9time_nano_time() (OMRPORT_FROM_J9PORT(privatePortLibrary)->time_nano_time(OMRPORT_FROM_J9PORT(privatePortLibrary)) - NANO_TIME_ADJUSTMENT) #define j9time_hires_clock() OMRPORT_FROM_J9PORT(privatePortLibrary)->time_hires_clock(OMRPORT_FROM_J9PORT(privatePortLibrary)) #define j9time_hires_frequency() OMRPORT_FROM_J9PORT(privatePortLibrary)->time_hires_frequency(OMRPORT_FROM_J9PORT(privatePortLibrary)) #define j9time_hires_delta(param1,param2,param3) OMRPORT_FROM_J9PORT(privatePortLibrary)->time_hires_delta(OMRPORT_FROM_J9PORT(privatePortLibrary),param1,param2,param3) diff --git a/test/functional/cmdLineTests/criu/criu.xml b/test/functional/cmdLineTests/criu/criu.xml index a43de8f6171..d855d5e884e 100644 --- a/test/functional/cmdLineTests/criu/criu.xml +++ b/test/functional/cmdLineTests/criu/criu.xml @@ -25,9 +25,10 @@ + - bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ $JVM_OPTIONS$ "SingleCheckpoint" + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ $JVM_OPTIONS$ $MAINCLASS_SIMPLE$ SingleCheckpoint Killed Pre-checkpoint Post-checkpoint @@ -37,7 +38,7 @@ - bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ $JVM_OPTIONS$ TwoCheckpoints + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ $JVM_OPTIONS$ $MAINCLASS_SIMPLE$ TwoCheckpoints Killed Pre-checkpoint Post-checkpoint 1 @@ -47,8 +48,8 @@ ERR - - bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ $JVM_OPTIONS$ ThreeCheckpoints + + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ $JVM_OPTIONS$ $MAINCLASS_SIMPLE$ ThreeCheckpoints Killed Pre-checkpoint Post-checkpoint 1 diff --git a/test/functional/cmdLineTests/criu/criuRandomScript.sh b/test/functional/cmdLineTests/criu/criuRandomScript.sh index 5c4f73fd47a..85dc6da928e 100644 --- a/test/functional/cmdLineTests/criu/criuRandomScript.sh +++ b/test/functional/cmdLineTests/criu/criuRandomScript.sh @@ -31,7 +31,7 @@ echo "start running script" if [ "$4" = "Checkpoint" ] then # append to the file to capture the output before checkpoint and after both restores - $2 $3 -XX:+EnableCRIUSupport -cp $1/criu.jar CRIURandomTest >>testOutput 2>&1 + $2 $3 -XX:+EnableCRIUSupport -cp $1/criu.jar org.openj9.criu.CRIURandomTest >>testOutput 2>&1 fi if [ "$4" = "FirstRestore" ] || [ "$4" = "SecondRestore" ] then diff --git a/test/functional/cmdLineTests/criu/criuScript.sh b/test/functional/cmdLineTests/criu/criuScript.sh index 7a95ebc5215..eec921c52ff 100644 --- a/test/functional/cmdLineTests/criu/criuScript.sh +++ b/test/functional/cmdLineTests/criu/criuScript.sh @@ -23,15 +23,15 @@ # echo "start running script"; -$2 -XX:+EnableCRIUSupport $3 -cp "$1/criu.jar" CRIUSimpleTest $4 >testOutput 2>&1; +$2 -XX:+EnableCRIUSupport $3 -cp "$1/criu.jar" $4 $5 >testOutput 2>&1; sleep 2; criu restore -D ./cpData --shell-job; -if [ "$4" == "TwoCheckpoints" ] || [ "$4" == "ThreeCheckpoints" ] +if [ "$5" == "TwoCheckpoints" ] || [ "$5" == "ThreeCheckpoints" ] then sleep 2; criu restore -D ./cpData --shell-job; fi -if [ "$4" == "ThreeCheckpoints" ] +if [ "$5" == "ThreeCheckpoints" ] then sleep 2; criu restore -D ./cpData --shell-job; diff --git a/test/functional/cmdLineTests/criu/criuSecurityScript.sh b/test/functional/cmdLineTests/criu/criuSecurityScript.sh index d73609e316c..ce5a825f36b 100644 --- a/test/functional/cmdLineTests/criu/criuSecurityScript.sh +++ b/test/functional/cmdLineTests/criu/criuSecurityScript.sh @@ -27,7 +27,7 @@ echo "start running script" # $1 is the TEST_ROOT # $2 is the JAVA_COMMAND # $3 is the JVM_OPTIONS -$2 $3 -XX:+EnableCRIUSupport -cp $1/criu.jar CRIUSecurityTest >testOutput 2>&1 +$2 $3 -XX:+EnableCRIUSupport -cp $1/criu.jar org.openj9.criu.CRIUSecurityTest >testOutput 2>&1 criu restore -D cpData --shell-job cat testOutput rm -rf testOutput diff --git a/test/functional/cmdLineTests/criu/criu_nonPortable.xml b/test/functional/cmdLineTests/criu/criu_nonPortable.xml index c1ab5df792c..5b96027b702 100644 --- a/test/functional/cmdLineTests/criu/criu_nonPortable.xml +++ b/test/functional/cmdLineTests/criu/criu_nonPortable.xml @@ -25,9 +25,11 @@ + + - bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$" "SingleCheckpoint" + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$" $MAINCLASS_SIMPLE$ SingleCheckpoint Killed Pre-checkpoint Post-checkpoint @@ -37,7 +39,7 @@ - bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$" TwoCheckpoints + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$" $MAINCLASS_SIMPLE$ TwoCheckpoints Killed Pre-checkpoint Post-checkpoint 1 @@ -48,4 +50,15 @@ Error + + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$" $MAINCLASS_TIMECHANGE$ ThreeCheckpoints + Killed + System.nanoTime() before CRIU checkpoint: + PASSED: System.nanoTime() after CRIU restore: + CRIU is not enabled + Operation not permitted + FAILED: System.nanoTime() after CRIU restore: + Error + + diff --git a/test/functional/cmdLineTests/criu/src/CRIURandomTest.java b/test/functional/cmdLineTests/criu/src/org/openj9/criu/CRIURandomTest.java similarity index 99% rename from test/functional/cmdLineTests/criu/src/CRIURandomTest.java rename to test/functional/cmdLineTests/criu/src/org/openj9/criu/CRIURandomTest.java index d7d3821a2ee..bac0a7d296b 100644 --- a/test/functional/cmdLineTests/criu/src/CRIURandomTest.java +++ b/test/functional/cmdLineTests/criu/src/org/openj9/criu/CRIURandomTest.java @@ -19,6 +19,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception *******************************************************************************/ +package org.openj9.criu; import java.io.BufferedReader; import java.io.FileReader; diff --git a/test/functional/cmdLineTests/criu/src/CRIUSecurityTest.java b/test/functional/cmdLineTests/criu/src/org/openj9/criu/CRIUSecurityTest.java similarity index 99% rename from test/functional/cmdLineTests/criu/src/CRIUSecurityTest.java rename to test/functional/cmdLineTests/criu/src/org/openj9/criu/CRIUSecurityTest.java index 09e034716a4..71bb8f2334a 100644 --- a/test/functional/cmdLineTests/criu/src/CRIUSecurityTest.java +++ b/test/functional/cmdLineTests/criu/src/org/openj9/criu/CRIUSecurityTest.java @@ -19,6 +19,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception *******************************************************************************/ +package org.openj9.criu; import java.io.File; import java.io.PrintStream; diff --git a/test/functional/cmdLineTests/criu/src/CRIUSimpleTest.java b/test/functional/cmdLineTests/criu/src/org/openj9/criu/CRIUSimpleTest.java similarity index 98% rename from test/functional/cmdLineTests/criu/src/CRIUSimpleTest.java rename to test/functional/cmdLineTests/criu/src/org/openj9/criu/CRIUSimpleTest.java index 37a697f44fc..6c9cd82eb1a 100644 --- a/test/functional/cmdLineTests/criu/src/CRIUSimpleTest.java +++ b/test/functional/cmdLineTests/criu/src/org/openj9/criu/CRIUSimpleTest.java @@ -20,6 +20,8 @@ * * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception *******************************************************************************/ +package org.openj9.criu; + import java.nio.file.Paths; import java.nio.file.Path; diff --git a/test/functional/cmdLineTests/criu/src/CRIUTestUtils.java b/test/functional/cmdLineTests/criu/src/org/openj9/criu/CRIUTestUtils.java similarity index 98% rename from test/functional/cmdLineTests/criu/src/CRIUTestUtils.java rename to test/functional/cmdLineTests/criu/src/org/openj9/criu/CRIUTestUtils.java index 33dafff2c69..d6f7d3e218e 100644 --- a/test/functional/cmdLineTests/criu/src/CRIUTestUtils.java +++ b/test/functional/cmdLineTests/criu/src/org/openj9/criu/CRIUTestUtils.java @@ -19,6 +19,8 @@ * * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception *******************************************************************************/ +package org.openj9.criu; + import java.nio.file.Paths; import java.nio.file.Path; import java.nio.file.Files; diff --git a/test/functional/cmdLineTests/criu/src/org/openj9/criu/TimeChangeTest.java b/test/functional/cmdLineTests/criu/src/org/openj9/criu/TimeChangeTest.java new file mode 100644 index 00000000000..b3811145f34 --- /dev/null +++ b/test/functional/cmdLineTests/criu/src/org/openj9/criu/TimeChangeTest.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2022, 2022 IBM Corp. and others + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] http://openjdk.java.net/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception + *******************************************************************************/ +package org.openj9.criu; + +import java.nio.file.Paths; +import java.nio.file.Path; + +public class TimeChangeTest { + + // The elapsed time is expected less than 2 second. + private static long MAX_ELAPSED_TIME = 2000 * 1000 * 1000; + private static Path imagePath = Paths.get("cpData"); + + public static void main(String args[]) { + new TimeChangeTest().testSystemNanoTime(); + } + + public void testSystemNanoTime() { + final long beforeCheckpoint = System.nanoTime(); + System.out.println("System.nanoTime() before CRIU checkpoint: " + beforeCheckpoint); + CRIUTestUtils.checkPointJVM(imagePath); + final long afterRestore = System.nanoTime(); + final long elapsedTime = afterRestore - beforeCheckpoint; + if (elapsedTime < MAX_ELAPSED_TIME) { + System.out.println("PASSED: System.nanoTime() after CRIU restore: " + afterRestore + ", the elapse time is: " + elapsedTime); + } else { + System.out.println("FAILED: System.nanoTime() after CRIU restore: " + afterRestore + ", the elapse time is: " + elapsedTime); + } + } +}