RFR: 8346123: [REDO] NMT should not use ThreadCritical [v3]

David Holmes dholmes at openjdk.org
Wed Dec 18 04:39:37 UTC 2024


On Tue, 17 Dec 2024 15:46:01 GMT, Robert Toyonaga <duke at openjdk.org> wrote:

>> This is a redo of [JDK-8304824](https://bugs.openjdk.org/browse/JDK-8304824) which was backed out by [JDK-8343726](https://bugs.openjdk.org/browse/JDK-8343726) due to problems documented in [JDK-8343244](https://bugs.openjdk.org/browse/JDK-8343244).
>> 
>> The problem was that `NmtVirtualMemoryLocker` was not locking when the current thread is not attached by checking `Thread::current_or_null_safe() != nullptr`. This is necessary during VM init, but should not be allowed afterward. NMT may be used in `attach_current_thread` before the current thread is set. The lock was not being acquired in that case, which intermittently caused NMT accounting to become corrupted, triggering various assertions when future NMT operations are done.  To fix this, I've adopted [Thomas' suggestion](https://github.com/openjdk/jdk/pull/21928#issuecomment-2460238057) to reverse the order of 
>> 
>> 
>> thread->register_thread_stack_with_NMT();
>> thread->initialize_thread_current();
>> 
>> 
>> in `attach_current_thread`.  This allows `NmtVirtualMemoryLocker` to be locked after current thread is set. 
>> 
>> To allow for `NmtVirtualMemoryLocker` to be used during VM init, I've replaced the `ConditionalMutexLocker` check `Thread::current_or_null_safe() != nullptr` with a new flag: `_done_bootstrap`. This flag prevents the lock from being used during VM init, at which point we are single threaded anyway. This avoids errors due to Hotspot mutexes and current thread not yet being ready. 
>> 
>> I also added new asserts in `virtualMemoryTracker.cpp` to catch future bugs like this where the lock is not held when it should be. I updated the appropriate VMT tests to also lock (there were a few cases where locking was being bypassed) so they can pass the new asserts.
>> 
>> I also removed the unused `_query_lock` variable in `MemTracker`.
>> 
>> Testing: 
>> 
>> - On Linux amd64, I was able to consistently reproduce the errors described in [JDK-8343244](https://bugs.openjdk.org/browse/JDK-8343244) by increasing the number of test threads in `java/lang/Thread/jni/AttachCurrentThread/AttachTest.java`. The test consistently passes with the new changes in this PR.
>> - hotspot_nmt , gtest:VirtualSpace, tier1
>
> Robert Toyonaga has updated the pull request incrementally with one additional commit since the last revision:
> 
>   updates tests and remove old class

The direct use of CML is functionally correct but requires leaking knowledge to all the use-sites that should not need to know about the actual condition for locking. This really needs to be encapsulated which means we need to be able to subclass CML.

@kbarrett what is needed to make `ConditionalMutexLocker` subclassable?

src/hotspot/os/windows/os_windows.cpp line 3624:

> 3622: #ifdef ASSERT
> 3623:       fileStream fs(stdout);
> 3624:       os::print_memory_mappings((char*)start, bytes, &fs);

Why was this change made? tty could be stdout or stderr depending on VM flag settings.

src/hotspot/share/runtime/threads.cpp line 530:

> 528: 
> 529:   // Once mutexes are ready, we can use NMT locks.
> 530:   MemTracker::set_done_bootstrap();

This should be done after the main thread has attached and set the current thread, otherwise if we hit any NMT code that needs the lock it would crash trying to acquire it.

src/hotspot/share/utilities/vmError.cpp line 720:

> 718: 
> 719:   BEGIN
> 720:   if (MemTracker::enabled() && NmtVirtualMemory_lock != nullptr && NmtVirtualMemory_lock->owned_by_self()) {

Suggestion:

  if (MemTracker::enabled() && NmtVirtualMemory_lock != nullptr  && MemTracker::is_done_bootstrap() && NmtVirtualMemory_lock->owned_by_self()) {

-------------

Changes requested by dholmes (Reviewer).

PR Review: https://git.openjdk.org/jdk/pull/22745#pullrequestreview-2510765294
PR Review Comment: https://git.openjdk.org/jdk/pull/22745#discussion_r1889595113
PR Review Comment: https://git.openjdk.org/jdk/pull/22745#discussion_r1889598981
PR Review Comment: https://git.openjdk.org/jdk/pull/22745#discussion_r1889600501


More information about the hotspot-dev mailing list