Skip to content

RAM Class Persistence: Fix Open liberty server hangs - #22723

Merged
babsingh merged 1 commit into
eclipse-openj9:masterfrom
lzhou2025:hang
Oct 9, 2025
Merged

RAM Class Persistence: Fix Open liberty server hangs#22723
babsingh merged 1 commit into
eclipse-openj9:masterfrom
lzhou2025:hang

Conversation

@lzhou2025

@lzhou2025 lzhou2025 commented Oct 6, 2025

Copy link
Copy Markdown
Member

The Open liberty server hangs on startup when loading classes from RCP cache and initializes the frozen classes. It is caused
by deadlock. Two threads wait for each other on RCP cache mutex and class table mutex in classes loading from RCP cache in loadNonArrayClass(). The changes are to pass the flag J9_FINDCLASS_FLAG_EXISTING_ONLY to class table lookup functions. If it's set for a frozen class, then it won't be loaded from RCP cache. The real problem is that a thread requested a class with J9_FINDCLASS_FLAG_EXISTING_ONLY is attempting to perform a RCP classload (loadWarmClass) which should never happen. We would have similar deadlock issues in a non-RCP scenario if a thread requesting a class with J9_FINDCLASS_FLAG_EXISTING_ONLY attempted to do a full classload. This is why the only threads that are allowed to load classes are VM threads and the JIT threads always call with J9_FINDCLASS_FLAG_EXISTING_ONLY.

Fixes: #22753

Co-authored-by: Tobi Ajila tobi_ajila@ca.ibm.com

@lzhou2025
lzhou2025 force-pushed the hang branch 5 times, most recently from 3584e19 to c739dca Compare October 8, 2025 15:45
@lzhou2025

Copy link
Copy Markdown
Member Author

@babsingh as discussed in the meeting.

@lzhou2025
lzhou2025 marked this pull request as ready for review October 8, 2025 15:47
@lzhou2025
lzhou2025 force-pushed the hang branch 2 times, most recently from 7babc0a to 8328854 Compare October 8, 2025 17:36
@babsingh

babsingh commented Oct 8, 2025

Copy link
Copy Markdown
Contributor

The description of the deadlock is incomplete. Please describe both threads involved and explain how the two monitors interact to cause the deadlock.

@babsingh babsingh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@lzhou2025 These changes won't work. How did you test them?

Comment thread runtime/vm/KeyHashTable.c
Comment thread runtime/vm/KeyHashTable.c Outdated
@lzhou2025
lzhou2025 force-pushed the hang branch 2 times, most recently from 3712c02 to 939cb1f Compare October 8, 2025 19:03
Comment thread runtime/vm/KeyHashTable.c
@babsingh

babsingh commented Oct 8, 2025

Copy link
Copy Markdown
Contributor

The documentation needs more detail. Currently, the connection between the solution and how it resolves the deadlock is missing in the commit message below.

The Open liberty server hangs on startup when loading classes
from RCP cache and initializes the frozen classes. It is caused
by deadlock. Two threads wait for each other on RCP cache mutex
and class table mutex. The changes are to check the flag
J9_FINDCLASS_FLAG_EXISTING_ONLY if set for a frozen class, then
it won't be loaded from RCP cache. HOW IS THE DEADLOCK RESOLVED?

@lzhou2025
lzhou2025 force-pushed the hang branch 2 times, most recently from 67790b6 to 8933244 Compare October 8, 2025 19:30
@babsingh

babsingh commented Oct 8, 2025

Copy link
Copy Markdown
Contributor

The documentation needs to be better.

  • What are the two threads?
  • What code paths are taken by them?
  • Why the monitors aren't released?
  • How the fix resolves the deadlock?

@lzhou2025

Copy link
Copy Markdown
Member Author

The documentation needs to be better.

* What are the two threads?

* What code paths are taken by them?

* Why the monitors aren't released?

* How the fix resolves the deadlock?

There are multiple hangs, this is one of them. Because they are all random, it's difficult to duplicate the case. If I remember correctly, the case is one thread owns RCP cache mutex, waits on class table mutex, other thread owns class table mutex, waits on RCP cache mutex. @TobiAjila suggested fix is to prevent the two threads to run into the situation, I believe.

@tajila

tajila commented Oct 9, 2025

Copy link
Copy Markdown
Contributor

The real problem is that a thread requested a class with J9_FINDCLASS_FLAG_EXISTING_ONLY is attempting to perform a RCP classload (loadWarmClass) which should never happen. In the RCP restore world if the class is frozen it is not loaded, so nothing should be done in this case.

We would have similar deadlock issues in a non-RCP scenario if a thread requesting a class with J9_FINDCLASS_FLAG_EXISTING_ONLY attempted to do a full classload. This is why the only threads that are allowed to load classes are VM threads and the JIT threads always call with J9_FINDCLASS_FLAG_EXISTING_ONLY.

We can mention in the commit message that it solves the deadlock, but it shouldn't be in the code because its really just part of the J9_FINDCLASS_FLAG_EXISTING_ONLY contract and the goal here is to enforce the existing rules in the RCP scenarios.

You may also want to add some of my comments above to the commit message.

Comment thread runtime/vm/KeyHashTable.c Outdated
Comment thread runtime/vm/KeyHashTable.c Outdated
The Open liberty server hangs on startup when loading classes from
RCP cache and initializes the frozen classes. It is caused by
deadlock. Two threads wait for each other on RCP cache mutex and
class table mutex in classes loading from RCP cache in
loadNonArrayClass(). The changes are to pass the flag
J9_FINDCLASS_FLAG_EXISTING_ONLY to class table lookup functions.
If it's set for a frozen class, then it won't be loaded from RCP
cache. The real problem is that a thread requested a class with
J9_FINDCLASS_FLAG_EXISTING_ONLY is attempting to perform a RCP
classload (loadWarmClass) which should never happen. We would have
similar deadlock issues in a non-RCP scenario if a thread
requesting a class with J9_FINDCLASS_FLAG_EXISTING_ONLY attempted
to do a full classload. This is why the only threads that are
allowed to load classes are VM threads and the JIT threads always
call with J9_FINDCLASS_FLAG_EXISTING_ONLY.

Fixes: eclipse-openj9#22753

Co-authored-by: Tobi Ajila tobi_ajila@ca.ibm.com
@babsingh

babsingh commented Oct 9, 2025

Copy link
Copy Markdown
Contributor

Thanks for updating the documentation. I have validated the fix: the hashClassTableAt* functions now return NULL when J9_FINDCLASS_FLAG_EXISTING_ONLY is specified. This prevents loadWarmClassFromSnapshot from being invoked and eliminates the conditions that previously led to deadlocks.

jenkins test sanity.functional plinux jdk21

@babsingh

babsingh commented Oct 9, 2025

Copy link
Copy Markdown
Contributor

jenkins test sanity.functional plinux jdk21

@babsingh

babsingh commented Oct 9, 2025

Copy link
Copy Markdown
Contributor

jenkins test sanity alinux jdk21

@babsingh
babsingh merged commit 946f941 into eclipse-openj9:master Oct 9, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RCP: Open liberty server hangs with -Xjit:disableDirectToJNI on the deadlock of RCP cache mutex and class table mutex

3 participants