Skip to content

Conversation

@MBaesken
Copy link
Member

@MBaesken MBaesken commented Feb 3, 2023

Enhance os::pd_print_cpu_info on macOS and Windows by information about CPU frequency and caches.
On Windows , this info can be obtained by the Processor Power Information API or "powerbase" (CallNtPowerInformation , see https://learn.microsoft.com/en-us/windows/win32/api/powerbase/nf-powerbase-callntpowerinformation ); this is available since Windows Server 2003/XP.
On macOS, sysctlbyname can be used.


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed (2 reviews required, with at least 1 Reviewer, 1 Author)

Issue

  • JDK-8301661: Enhance os::pd_print_cpu_info on macOS and Windows

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/12403/head:pull/12403
$ git checkout pull/12403

Update a local copy of the PR:
$ git checkout pull/12403
$ git pull https://git.openjdk.org/jdk pull/12403/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 12403

View PR using the GUI difftool:
$ git pr show -t 12403

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/12403.diff

@bridgekeeper
Copy link

bridgekeeper bot commented Feb 3, 2023

👋 Welcome back mbaesken! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk openjdk bot added the rfr Pull request is ready for review label Feb 3, 2023
@openjdk
Copy link

openjdk bot commented Feb 3, 2023

@MBaesken The following label will be automatically applied to this pull request:

  • hotspot-runtime

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the hotspot-runtime hotspot-runtime-dev@openjdk.org label Feb 3, 2023
@mlbridge
Copy link

mlbridge bot commented Feb 3, 2023

Webrevs

@dholmes-ora
Copy link
Member

Okay the usual question when we augment the information that will appear in hs_err file: how safe is this going to be to call from a signal handler?

@MBaesken
Copy link
Member Author

MBaesken commented Feb 3, 2023

Okay the usual question when we augment the information that will appear in hs_err file: how safe is this going to be to call from a signal handler?

Hi David , I think the sysctl / sysctlbyname calls on macOS are rather safe (and we use this already for some time for other entries e.g. in os::print_summary_info in vm error reporting, so nothing really new. Not so sure about the Windows powerprof / powerbase API, this was not used before to my knowledge in OpenJDK. However we use both macOS and Windows APIs for some time in our internal JVM, no issues seen so far.

ULONG MhzLimit; // max specified processor clock frequency mult. by current processor thermal throttle limit
ULONG MaxIdleState;
ULONG CurrentIdleState;
} PROCESSOR_POWER_INFORMATION, *PTR_PROCESSOR_POWER_INFORMATION;
Copy link
Member

Choose a reason for hiding this comment

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

We don't need the *PTR_PROCESSOR_POWER_INFORMATION

#include <shlobj.h>

#include <malloc.h>
#include <powrprof.h>
Copy link
Member

Choose a reason for hiding this comment

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

The header should be powerbase.h

Comment on lines 1890 to 1891
// additional lib needed for PowerProf functionality
#pragma comment(lib, "Powrprof.lib")
Copy link
Member

Choose a reason for hiding this comment

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

Not sure about this mechanism versus adding it to Makefile ??

Comment on lines 1894 to 1898
SYSTEM_INFO si;
GetSystemInfo(&si);

PROCESSOR_POWER_INFORMATION ppi;
size_t sz_check = sizeof(ppi) * (size_t)si.dwNumberOfProcessors;
Copy link
Member

Choose a reason for hiding this comment

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

We already have dwNumberOfProcessors available in processor_count() - though we may have to zero-initialize it and check for zero in case we crash before we've done os::init

Copy link
Member

Choose a reason for hiding this comment

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

That said from what I'm reading if systems have more than 64 processors they will be divided into processor groups and the max number will be 64. However IIUC CallNtPowerInformation will expect a buffer big enough for the true number of logical processors >64.

@MBaesken
Copy link
Member Author

MBaesken commented Feb 6, 2023

Hi David, thanks for the comments. I did a few adjustments following your comments. Regarding

Not sure about this mechanism versus adding it to Makefile ??

Both works. From what I see, currently we use the Makefile to set the lib deps, should I remove the pragma and use the Makefile ?
Regarding the processor count , probably we do not want to malloc anyway in pd_print_cpu_info so we have to live with the space buf provides.
Btw what you think about shortening the info, e.g. check if all processors have the same (M)Hz values and if it is the case just print once, this might look better and much less redundant in the output ?

@dholmes-ora
Copy link
Member

From what I see, currently we use the Makefile to set the lib deps, should I remove the pragma and use the Makefile ?

I'm asking the build folk if they have any preference/concerns.

Regarding the processor count , probably we do not want to malloc anyway in pd_print_cpu_info so we have to live with the space buf provides.

True. I still think we might reuse processor_count(). Showing zero very early during VM init is not really an issue.

Btw what you think about shortening the info, e.g. check if all processors have the same (M)Hz values and if it is the case just print once, this might look better and much less redundant in the output ?

As this is intended as fairly general information shortening would be good - especially if the values reported are the same. Do we need to report all processors, or can we just use one as representative?

@MBaesken
Copy link
Member Author

MBaesken commented Feb 8, 2023

Hi David , I did another small adjustment. Reused os::processor_count if it delivers a value larger than 0. And adjusted the output a bit.

especially if the values reported are the same

On my notebook I noticed that the current idle state sometimes differs among processors. So it is not always the same.
Maybe it makes sense to print the current idle state separately for all processors and if possible, output the other values just once .

ProcessorInformation for all processors: Max Mhz: 2611, Current Mhz: 2611, Mhz Limit: 2611 MaxIdleState: 2 CurrentIdleState for processors 0 - 15: 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2

@dholmes-ora
Copy link
Member

With regards to the pragma I had the following response from @magicus :

Oh, please don't do that. We could perhaps have gone down that route, but we didn't. If you do that, there won't be a single source of truth on where to look for library linkage. We had a bug a year or two ago that ended up in us loading a library which nobody expected or realized due to a windows pragma. So, basically, there's nothing inherently wrong with this (just a bit non-standard from an old-school unix point of view), but it does not fit with the current model of the JDK

@dholmes-ora
Copy link
Member

On my notebook I noticed that the current idle state sometimes differs among processors. So it is not always the same.
Maybe it makes sense to print the current idle state separately for all processors and if possible, output the other values just once .

I have no idea what possible use the "idle state" information would be in any case. We don't have that per-processor info on non-Windows.

@magicus
Copy link
Member

magicus commented Feb 9, 2023

/label build

Copy link
Member

@magicus magicus left a comment

Choose a reason for hiding this comment

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

Build changes look good now. Thanks for removing the pragma.

/reviewers 2

@openjdk openjdk bot added the build build-dev@openjdk.org label Feb 9, 2023
@openjdk
Copy link

openjdk bot commented Feb 9, 2023

@magicus
The build label was successfully added.

@openjdk
Copy link

openjdk bot commented Feb 9, 2023

@MBaesken This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8301661: Enhance os::pd_print_cpu_info on macOS and Windows

Reviewed-by: ihse, lucy, dholmes

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 274 new commits pushed to the master branch:

  • bb3dfd6: 8302879: doc/building.md update link to jtreg builds
  • 36a0822: 8302369: Reduce the stack size of the C1 compiler
  • 0bf3a53: 8302599: Extend ASan support to Microsoft Visual C++
  • c7517b3: 8302525: Write a test to check various components send Events while mouse and key are used simultaneously
  • 9a79722: 8299234: JMX Repository.query performance
  • e47e9ec: 8300658: memory_and_swap_limit() reporting wrong values on systems with swapaccount=0
  • 7cf7e0a: 8302070: Factor null-check into load_klass() calls
  • e731695: 8302882: Newly added test javax/swing/JFileChooser/JFileChooserFontReset.java fails with HeadlessException
  • b5a7426: 8301749: Tracking malloc pooled memory size
  • 6ac5e05: 8302068: Serial: Refactor oop closures used in Young GC
  • ... and 264 more: https://git.openjdk.org/jdk/compare/af474ce35997315774e408f2e8a1beecf8349c75...master

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Feb 9, 2023
@openjdk
Copy link

openjdk bot commented Feb 9, 2023

@magicus
The total number of required reviews for this PR (including the jcheck configuration and the last /reviewers command) is now set to 2 (with at least 1 Reviewer, 1 Author).

@openjdk openjdk bot removed the ready Pull request is ready to be integrated label Feb 9, 2023
@MBaesken
Copy link
Member Author

MBaesken commented Feb 10, 2023

I have no idea what possible use the "idle state" information would be in any case. We don't have that per-processor info on non-Windows.

Hi David, there is some info about the idle states at https://learn.microsoft.com/en-us/windows-hardware/test/wpt/cpu-analysis ; if you think that currently, with the info only available on Windows, it makes not that much sense to add, it I can omit it for now. Would probably make it easier to scan through the cpu-infos and observe same MHz numbers for all and then print the same info for all processors (as I said, where I tested the MHz values were the same for all CPUs only the current idle states varied).

@MBaesken
Copy link
Member Author

Hi Magnus, thanks for the review !

Copy link
Contributor

@RealLucy RealLucy left a comment

Choose a reason for hiding this comment

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

Changes look good to me

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Feb 14, 2023
@MBaesken
Copy link
Member Author

Hi David are you okay with the latest version ?

@dholmes-ora
Copy link
Member

Hi David are you okay with the latest version ?

I thought you were looking at reducing the output:

Maybe it makes sense to print the current idle state separately for all processors and if possible, output the other values just once .

I don't think idle states are particularly useful, so I'd prefer to see similar output to non-Windows rather than per-processor info that is the same for everything of interest.

Copy link
Member

@dholmes-ora dholmes-ora left a comment

Choose a reason for hiding this comment

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

General approach seems okay. A couple of queries and nits.

Thanks.

if (MaxMhz != (int) pppi->MaxMhz ||
CurrentMhz != (int) pppi->CurrentMhz ||
MhzLimit != (int) pppi->MhzLimit) {
same_vals_for_all_cpus = false;
Copy link
Member

Choose a reason for hiding this comment

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

You could break once this is false.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added a break.

}

size_t sz_check = sizeof(PROCESSOR_POWER_INFORMATION) * (size_t)proc_count;
NTSTATUS status = ::CallNtPowerInformation(ProcessorInformation, NULL, 0, buf, (ULONG) buflen);
Copy link
Member

Choose a reason for hiding this comment

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

How is the caller supposed to know what size buffer to pass? Are they just supposed to guess and hope it is big enough??

}
}
// avoid iteration in case buf is too small to hold all proc infos
if (sz_check > buflen) break;
Copy link
Member

Choose a reason for hiding this comment

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

In this case shouldn't the function have returned STATUS_BUFFER_TOO_SMALL?

@MBaesken
Copy link
Member Author

Hi David I adjusted the output, renamed some variables and added a break where you suggested.

In this case shouldn't the function have returned STATUS_BUFFER_TOO_SMALL

I think this would be the case, but I was not sure so I added the check.

How is the caller supposed to know what size buffer to pass? Are they just supposed to guess and hope it is big enough??

I think this is the same for most of the print_ functions from
src/hotspot/share/runtime/os.hpp
getting a buffer 'buf' and a buf-length value, they are unfortunately not very specific on the size passed.

https://github.com/openjdk/jdk/blob/master/src/hotspot/share/runtime/os.hpp#L754

// Print out system information; they are called by fatal error handler.
// Output format may be different on different platforms.

Copy link
Member

@dholmes-ora dholmes-ora left a comment

Choose a reason for hiding this comment

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

I'm still a little dubious about the buffer size check but lets see how this goes.

Thanks.

@MBaesken
Copy link
Member Author

Hi David and Lutz, thanks for the reviews.

/integrate

@openjdk
Copy link

openjdk bot commented Feb 21, 2023

Going to push as commit 9145670.
Since your change was applied there have been 280 commits pushed to the master branch:

  • aa10f0d: 8302151: BMPImageReader throws an exception reading BMP images
  • 16a4f02: 8302150: Speed up compiler/codegen/Test7100757.java
  • 17274c7: 8302146: Move TestOverloadCompileQueues.java to tier3
  • 29f392e: 8299522: Incorrect size of Approve button in custom JFileChooser
  • 43c71dd: 8302453: RISC-V: Add support for small width vector operations
  • 91a2b5e: 8302905: arm32 Raspberry Pi OS build broken by JDK-8301494
  • bb3dfd6: 8302879: doc/building.md update link to jtreg builds
  • 36a0822: 8302369: Reduce the stack size of the C1 compiler
  • 0bf3a53: 8302599: Extend ASan support to Microsoft Visual C++
  • c7517b3: 8302525: Write a test to check various components send Events while mouse and key are used simultaneously
  • ... and 270 more: https://git.openjdk.org/jdk/compare/af474ce35997315774e408f2e8a1beecf8349c75...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Feb 21, 2023
@openjdk openjdk bot closed this Feb 21, 2023
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Feb 21, 2023
@openjdk
Copy link

openjdk bot commented Feb 21, 2023

@MBaesken Pushed as commit 9145670.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

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

Labels

build build-dev@openjdk.org hotspot-runtime hotspot-runtime-dev@openjdk.org integrated Pull request has been integrated

Development

Successfully merging this pull request may close these issues.

4 participants