Skip to content

Commit 7957994

Browse files
committedOct 4, 2021
8273695: Safepoint deadlock on VMOperation_lock
Reviewed-by: dcubed, pchilanomate, eosterlund
1 parent 9ca6bf0 commit 7957994

File tree

5 files changed

+30
-22
lines changed

5 files changed

+30
-22
lines changed
 

‎src/hotspot/share/runtime/safepointMechanism.hpp

-3
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,12 @@ class SafepointMechanism : public AllStatic {
4545

4646
static address _polling_page;
4747

48-
4948
static inline void disarm_local_poll(JavaThread* thread);
5049

5150
static inline bool global_poll();
5251

5352
static void process(JavaThread *thread, bool allow_suspend);
5453

55-
static inline bool should_process_no_suspend(JavaThread* thread);
56-
5754
static void default_initialize();
5855

5956
static void pd_initialize() NOT_AIX({ default_initialize(); });

‎src/hotspot/share/runtime/safepointMechanism.inline.hpp

+18-14
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "runtime/atomic.hpp"
3131
#include "runtime/handshake.hpp"
3232
#include "runtime/safepoint.hpp"
33+
#include "runtime/stackWatermarkSet.hpp"
3334
#include "runtime/thread.inline.hpp"
3435

3536
// Caller is responsible for using a memory barrier if needed.
@@ -62,26 +63,29 @@ bool SafepointMechanism::global_poll() {
6263
return (SafepointSynchronize::_state != SafepointSynchronize::_not_synchronized);
6364
}
6465

65-
bool SafepointMechanism::should_process_no_suspend(JavaThread* thread) {
66-
if (global_poll() || thread->handshake_state()->has_a_non_suspend_operation()) {
67-
return true;
68-
} else {
69-
// We ignore suspend requests if any and just check before returning if we need
70-
// to fix the thread's oops and first few frames due to a possible safepoint.
71-
StackWatermarkSet::on_safepoint(thread);
72-
update_poll_values(thread);
73-
OrderAccess::cross_modify_fence();
74-
return false;
75-
}
76-
}
77-
7866
bool SafepointMechanism::should_process(JavaThread* thread, bool allow_suspend) {
7967
if (!local_poll_armed(thread)) {
8068
return false;
8169
} else if (allow_suspend) {
8270
return true;
8371
}
84-
return should_process_no_suspend(thread);
72+
// We are armed but we should ignore suspend operations.
73+
if (global_poll() || // Safepoint
74+
thread->handshake_state()->has_a_non_suspend_operation() || // Non-suspend handshake
75+
!StackWatermarkSet::processing_started(thread)) { // StackWatermark processing is not started
76+
return true;
77+
}
78+
79+
// It has boiled down to two possibilities:
80+
// 1: We have nothing to process, this just a disarm poll.
81+
// 2: We have a suspend handshake, which cannot be processed.
82+
// We update the poll value in case of a disarm, to reduce false positives.
83+
update_poll_values(thread);
84+
85+
// We are now about to avoid processing and thus no cross modify fence will be executed.
86+
// In case a safepoint happened, while being blocked, we execute it here.
87+
OrderAccess::cross_modify_fence();
88+
return false;
8589
}
8690

8791
void SafepointMechanism::process_if_requested(JavaThread* thread, bool allow_suspend) {

‎src/hotspot/share/runtime/stackWatermarkSet.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,15 @@ void StackWatermarkSet::start_processing(JavaThread* jt, StackWatermarkKind kind
128128
// will always update the poll values when waking up from a safepoint.
129129
}
130130

131+
bool StackWatermarkSet::processing_started(JavaThread* jt) {
132+
for (StackWatermark* current = head(jt); current != NULL; current = current->next()) {
133+
if (!current->processing_started()) {
134+
return false;
135+
}
136+
}
137+
return true;
138+
}
139+
131140
void StackWatermarkSet::finish_processing(JavaThread* jt, void* context, StackWatermarkKind kind) {
132141
StackWatermark* watermark = get(jt, kind);
133142
if (watermark != NULL) {

‎src/hotspot/share/runtime/stackWatermarkSet.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ class StackWatermarkSet : public AllStatic {
7979
// Called to ensure that processing of the thread is started
8080
static void start_processing(JavaThread* jt, StackWatermarkKind kind);
8181

82+
// Returns true if all StackWatermarks have been started.
83+
static bool processing_started(JavaThread* jt);
84+
8285
// Called to finish the processing of a thread
8386
static void finish_processing(JavaThread* jt, void* context, StackWatermarkKind kind);
8487

‎test/hotspot/jtreg/ProblemList.txt

-5
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,6 @@ gc/stress/gclocker/TestGCLockerWithParallel.java 8180622 generic-all
8585
gc/stress/gclocker/TestGCLockerWithG1.java 8180622 generic-all
8686
gc/stress/TestJNIBlockFullGC/TestJNIBlockFullGC.java 8192647 generic-all
8787
gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java 8241293 macosx-x64
88-
gc/stringdedup/TestStringDeduplicationAgeThreshold.java#Z 8273695 generic-all
89-
gc/stringdedup/TestStringDeduplicationPrintOptions.java#Z 8273695 generic-all
90-
gc/stringdedup/TestStringDeduplicationInterned.java#Z 8273695 generic-all
91-
gc/stringdedup/TestStringDeduplicationTableResize.java#Z 8273695 generic-all
92-
gc/stringdedup/TestStringDeduplicationYoungGC.java#Z 8273695 generic-all
9388

9489
#############################################################################
9590

0 commit comments

Comments
 (0)
Failed to load comments.