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

Bug fixes for PowerPC targets #35988

Closed
wants to merge 2 commits into from
Closed

Bug fixes for PowerPC targets #35988

wants to merge 2 commits into from

Conversation

jhamby
Copy link

@jhamby jhamby commented Nov 6, 2020

Fixes for Node.js (V8) for older PowerPC targets. I'm testing with
Gentoo Linux on ppc64 (big-endian) on a PowerMac Quad G5, so this
code needs testing on other systems, especially POWER9, which I believe
should have some CPU flags enabled that aren't currently being enabled.
Currently, POWER9 is setting MODULO but not the other feature flags, so
I refactored the code to a switch statement with fallthrough assuming that
the newer POWER CPUs have all the feature flags of the earlier ones.
Please let me know if that assumption is incorrect. Other changes:

  • PPC64 big-endian ELFv1 ABI uses function descriptors, like AIX.

  • Tell the code generator when we don't have the FP to int rounding
    instructions (added in Power ISA v2.03) by not enabling them in the
    MachineOperatorBuilder::Flags if we don't have a new enough CPU.
    My first patch tried to emit the equivalent rounding behavior inline,
    but then I realized I could set the flags to not emit frim/frin/friz/frip
    if the CPU doesn't support those instructions.

  • Change minimum page size to 4KB for PPC. 64KB physical pages are a
    newer feature that breaks some software, such as the nouveau driver.

  • Change PPC CPU detection to use getauxval() for glibc 2.16 and newer,
    and to correctly recognize all known Linux PowerPC platform types.
    Cell BE is identified as PPC_G5; other CPUs with AltiVec as PPC_G4.
    The new PPC_G3 type is used for all other CPUs without VMX/AltiVec.

  • Add VMX feature for future VMX/AltiVec code generation. VMX is a
    subset of VSX that's available on POWER6, G5, Cell, G4, and PA6T.
    The newer VSX feature is only available on POWER7 and newer CPUs.

I need to continue testing, as I'm seeing one strange failure in cctest now,
only with a release build. But I think the patches I have so far are basically
correct and ready for review and feedback. Thanks!

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

* Change minimum page size to 4KB for PPC. 64KB physical pages are a
  newer feature that breaks some software, such as the nouveau driver.

* Change PPC CPU detection to use getauxval() for glibc 2.16 and newer,
  and to correctly recognize all known Linux PowerPC platform types.
  Cell BE is identified as PPC_G5; other CPUs with AltiVec as PPC_G4.
  The new PPC_G3 type is used for all other CPUs without VMX/AltiVec.

* Add VMX feature for future VMX/AltiVec code generation. VMX is a
  subset of VSX that's available on POWER6, G5, Cell, G4, and PA6T.
  The newer VSX feature is only available on POWER7 and newer CPUs.

* Add codegen support for older CPUs that lack the FP to integer
  rounding instructions added in Power ISA v2.03 (e.g. POWER5+, PA6T).
  Renamed the feature from FPU to the more descriptive FP_ROUND_TO_INT.
  Original patch written by A. Wilcox <[email protected]>.
  Updated to handle -0.0 and NaN cases, and it should work on PPC32.
* PPC64 big-endian ELFv1 ABI uses function descriptors, like AIX.

* Tell the code generator when we don't have the FP to int rounding
  instructions (added in Power ISA v2.03) by not enabling them in the
  MachineOperatorBuilder::Flags if we don't have a new enough CPU.

* Revert the previous patch to generate a complicated branching code
  sequence to substitute for the FP to int rounding instructions not
  present on POWER5 and older CPUs. We will no longer call the code to
  emit these instructions if the feature isn't detected at runtime.

* In the code that sets MachineOperatorBuilder::Flags, modify to
  only set kWord64Popcnt if we're compiling for PPC64. We always set
  kWord32Popcnt. This may not matter in practice for 32-bit builds.
@mscdex
Copy link
Contributor

mscdex commented Nov 6, 2020

Have these changes been submitted upstream to V8?

@targos
Copy link
Member

targos commented Nov 6, 2020

@nodejs/platform-ppc

@john-yan
Copy link

john-yan commented Nov 6, 2020

Hello @jhamby, thank for your hard work for supporting G5. Do you have plans to continuous supporting this arch in the near term or longer term? If you don't, your work is likely to falling apart very soon when we move foreward, because we don't have HW for testing. Also, v8 changes need to be made on v8 upstream first before floating to node.js. Please follow the Google guildlines to contribute this to V8: here

// PPC has large (64KB) physical pages.
const int kPageSizeBits = 19;
#else
// Use 4KB for all targets. Not all PPC Linux kernels use 64KB pages.
const int kPageSizeBits = 18;
Copy link
Contributor

Choose a reason for hiding this comment

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

On newer versions of P Linux, page size needs to remain as 64KB as it's the default size of the OS.
AIX and older Linux versions use 4KB by default. This is causing some V8 test failures on P Linux.

Copy link

@q66 q66 Nov 7, 2020

Choose a reason for hiding this comment

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

modern Linux allows both 4k and 64k page sizes (and there are modern distros for modern POWER processors that do use 4k pages) but the constant name is misleading - using 64k there will work on both 4k and 64k hosts, while using 4k there will break 64k hosts

@@ -33,7 +33,7 @@ asm(
// At anytime, SP (r1) needs to be multiple of 16 (i.e. 16-aligned).
" mflr 0 \n"
" std 0, 16(1) \n"
#if defined(_AIX)
#if ABI_USES_FUNCTION_DESCRIPTORS
Copy link
Contributor

Choose a reason for hiding this comment

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

ABI_USES_FUNCTION_DESCRIPTORS is not defined in this file, no V8 headers are included here, it's raw assembly, hence defined(_AIX) is used to rely on gcc.

Copy link

@q66 q66 Nov 7, 2020

Choose a reason for hiding this comment

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

could use defined(__powerpc64__) && (!defined(_CALL_ELF) || (_CALL_ELF == 1)) for a generic check

@@ -203,7 +203,7 @@ constexpr bool kPlatformRequiresCodeRange = true;
#if (V8_HOST_ARCH_PPC || V8_HOST_ARCH_PPC64) && \
(V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64) && V8_OS_LINUX
constexpr size_t kMaximalCodeRangeSize = 512 * MB;
constexpr size_t kMinExpectedOSPageSize = 64 * KB; // OS page on PPC Linux
constexpr size_t kMinExpectedOSPageSize = 4 * KB; // min OS page size
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment regarding P linux page size applies here.

@q66
Copy link

q66 commented Nov 7, 2020

the pagesize changes shouldn't be included; 64k-assuming code works fine on 4k page hosts (it's just a little bit wasteful, but the only fix for that is checking pagesize at runtime and that would need way bigger changes), but it does not apply the other way around - this is because 64k is a multiple of 4k

also, what's the point of using getauxval there - parsing /proc is effectively equivalent, and this assumption is also incorrect, since getauxval is not a glibc-only feature

@@ -676,8 +676,14 @@ CPU::CPU()

#ifndef USE_SIMULATOR
#if V8_OS_LINUX
#if V8_GLIBC_PREREQ(2, 16)
Copy link

Choose a reason for hiding this comment

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

getauxval is available on musl and other libc's, so this check is wrong, and there is no reasonable way to check it - i just wouldn't bother, the other path is directly equivalent already

@q66
Copy link

q66 commented Nov 7, 2020

also, i believe v8 is currently generally broken on 32-bit PowerPC and will need much more extensive changes in the codegen to fix that; so anything 32-bit relevant here is partial, and it's mostly just fixes for older 64-bit CPUs

@awilfox
Copy link
Contributor

awilfox commented Nov 14, 2020

Hello @jhamby, thank for your hard work for supporting G5. Do you have plans to continuous supporting this arch in the near term or longer term? If you don't, your work is likely to falling apart very soon when we move foreward, because we don't have HW for testing. Also, v8 changes need to be made on v8 upstream first before floating to node.js. Please follow the Google guildlines to contribute this to V8: here

We at Adélie Linux would be more than happy to maintain this support in perpetuity. Supporting G5/P5/P6 is a core focus of ours. We will be using it every time we bump Node and/or Firefox (since Firefox uses Node in the build).

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v8 engine Issues and PRs related to the V8 dependency.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants