# HG changeset patch # User gromero # Date 1526483463 14400 # Node ID e2d9b38630c33c291177619d02c8223c277228f2 # Parent dc18db6716515fe4dc80f1234b631b5023837444 8203305: PPC64: Improve TM detection for enabling RTM on Linux / POWER9 Reviewed-by: mdoerr diff -r dc18db671651 -r e2d9b38630c3 src/hotspot/cpu/ppc/vm_version_ppc.cpp --- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp Thu May 17 14:16:49 2018 +0200 +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp Wed May 16 11:11:03 2018 -0400 @@ -37,7 +37,15 @@ #include "utilities/globalDefinitions.hpp" #include "vm_version_ppc.hpp" -# include +#include + +#if defined(LINUX) && defined(VM_LITTLE_ENDIAN) +#include + +#ifndef PPC_FEATURE2_HTM_NOSC +#define PPC_FEATURE2_HTM_NOSC (1 << 24) +#endif +#endif bool VM_Version::_is_determine_features_test_running = false; uint64_t VM_Version::_dscr_val = 0; @@ -123,7 +131,7 @@ // Create and print feature-string. char buf[(num_features+1) * 16]; // Max 16 chars per feature. jio_snprintf(buf, sizeof(buf), - "ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + "ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", (has_fsqrt() ? " fsqrt" : ""), (has_isel() ? " isel" : ""), (has_lxarxeh() ? " lxarxeh" : ""), @@ -136,7 +144,6 @@ (has_lqarx() ? " lqarx" : ""), (has_vcipher() ? " aes" : ""), (has_vpmsumb() ? " vpmsumb" : ""), - (has_tcheck() ? " tcheck" : ""), (has_mfdscr() ? " mfdscr" : ""), (has_vsx() ? " vsx" : ""), (has_ldbrx() ? " ldbrx" : ""), @@ -304,15 +311,15 @@ // Adjust RTM (Restricted Transactional Memory) flags. if (UseRTMLocking) { - // If CPU or OS are too old: + // If CPU or OS do not support TM: // Can't continue because UseRTMLocking affects UseBiasedLocking flag // setting during arguments processing. See use_biased_locking(). // VM_Version_init() is executed after UseBiasedLocking is used // in Thread::allocate(). - if (!has_tcheck()) { - vm_exit_during_initialization("RTM instructions are not available on this CPU"); + if (PowerArchitecturePPC64 < 8) { + vm_exit_during_initialization("RTM instructions are not available on this CPU."); } - bool os_too_old = true; + bool os_support_tm = false; #ifdef AIX // Actually, this is supported since AIX 7.1.. Unfortunately, this first // contained bugs, so that it can only be enabled after AIX 7.1.3.30. @@ -322,22 +329,25 @@ // So the tests can not check on subversion 3.30, and we only enable RTM // with AIX 7.2. if (os::Aix::os_version() >= 0x07020000) { // At least AIX 7.2. - os_too_old = false; + os_support_tm = true; } #endif -#ifdef LINUX - // At least Linux kernel 4.2, as the problematic behavior of syscalls - // being called in the middle of a transaction has been addressed. - // Please, refer to commit b4b56f9ecab40f3b4ef53e130c9f6663be491894 - // in Linux kernel source tree: https://goo.gl/Kc5i7A - if (os::Linux::os_version_is_known()) { - if (os::Linux::os_version() >= 0x040200) - os_too_old = false; - } else { - vm_exit_during_initialization("RTM can not be enabled: kernel version is unknown."); +#if defined(LINUX) && defined(VM_LITTLE_ENDIAN) + unsigned long auxv = getauxval(AT_HWCAP2); + + if (auxv & PPC_FEATURE2_HTM_NOSC) { + if (auxv & PPC_FEATURE2_HAS_HTM) { + // TM on POWER8 and POWER9 in compat mode (VM) is supported by the JVM. + // TM on POWER9 DD2.1 NV (baremetal) is not supported by the JVM (TM on + // POWER9 DD2.1 NV has a few issues that need a couple of firmware + // and kernel workarounds, so there is a new mode only supported + // on non-virtualized P9 machines called HTM with no Suspend Mode). + // TM on POWER9 D2.2+ NV is not supported at all by Linux. + os_support_tm = true; + } } #endif - if (os_too_old) { + if (!os_support_tm) { vm_exit_during_initialization("RTM is not supported on this OS version."); } } @@ -680,12 +690,11 @@ a->lqarx_unchecked(R6, R3_ARG1, R4_ARG2, 1); // code[9] -> lqarx_m a->vcipher(VR0, VR1, VR2); // code[10] -> vcipher a->vpmsumb(VR0, VR1, VR2); // code[11] -> vpmsumb - a->tcheck(0); // code[12] -> tcheck - a->mfdscr(R0); // code[13] -> mfdscr - a->lxvd2x(VSR0, R3_ARG1); // code[14] -> vsx - a->ldbrx(R7, R3_ARG1, R4_ARG2); // code[15] -> ldbrx - a->stdbrx(R7, R3_ARG1, R4_ARG2); // code[16] -> stdbrx - a->vshasigmaw(VR0, VR1, 1, 0xF); // code[17] -> vshasig + a->mfdscr(R0); // code[12] -> mfdscr + a->lxvd2x(VSR0, R3_ARG1); // code[13] -> vsx + a->ldbrx(R7, R3_ARG1, R4_ARG2); // code[14] -> ldbrx + a->stdbrx(R7, R3_ARG1, R4_ARG2); // code[15] -> stdbrx + a->vshasigmaw(VR0, VR1, 1, 0xF); // code[16] -> vshasig a->blr(); // Emit function to set one cache line to zero. Emit function descriptor and get pointer to it. @@ -732,7 +741,6 @@ if (code[feature_cntr++]) features |= lqarx_m; if (code[feature_cntr++]) features |= vcipher_m; if (code[feature_cntr++]) features |= vpmsumb_m; - if (code[feature_cntr++]) features |= tcheck_m; if (code[feature_cntr++]) features |= mfdscr_m; if (code[feature_cntr++]) features |= vsx_m; if (code[feature_cntr++]) features |= ldbrx_m; diff -r dc18db671651 -r e2d9b38630c3 src/hotspot/cpu/ppc/vm_version_ppc.hpp --- a/src/hotspot/cpu/ppc/vm_version_ppc.hpp Thu May 17 14:16:49 2018 +0200 +++ b/src/hotspot/cpu/ppc/vm_version_ppc.hpp Wed May 16 11:11:03 2018 -0400 @@ -44,7 +44,6 @@ lqarx, vcipher, vpmsumb, - tcheck, mfdscr, vsx, ldbrx, @@ -67,7 +66,6 @@ vcipher_m = (1 << vcipher), vshasig_m = (1 << vshasig), vpmsumb_m = (1 << vpmsumb), - tcheck_m = (1 << tcheck ), mfdscr_m = (1 << mfdscr ), vsx_m = (1 << vsx ), ldbrx_m = (1 << ldbrx ), @@ -103,7 +101,6 @@ static bool has_lqarx() { return (_features & lqarx_m) != 0; } static bool has_vcipher() { return (_features & vcipher_m) != 0; } static bool has_vpmsumb() { return (_features & vpmsumb_m) != 0; } - static bool has_tcheck() { return (_features & tcheck_m) != 0; } static bool has_mfdscr() { return (_features & mfdscr_m) != 0; } static bool has_vsx() { return (_features & vsx_m) != 0; } static bool has_ldbrx() { return (_features & ldbrx_m) != 0; }