This bug is likely introduced after integrating a fix for JDK-8339163. JDK-8339163 skips clearing of a potential remembered set in the young collection in favor of doing it only in the old collection.
The code responsible for clearing the remset (ZRememberedSet::clear_all) is dependent on the "_current" variable in ZRememberedSet not being altered in between the two "clear_*" calls in ZRememberedSet::clear_all. If the remembered set is being cleared in the old collection, and successfully clears the current remset with clear_current(), a young collection might then flip/swap the current/previous remembered sets by changing the "_current" value in ZRememberedSet. This would mean that the call to clear_previous() would clean the same bitmap again, resulting in one of the two bitmaps not being cleared at all. This will later crash in an assert checking if both bitmaps are empty when the page is being freed.
void ZRememberedSet::clear_all() {
clear_current();
clear_previous();
}
This has been reproduced by adding a delay between the "clear_*" calls, like below, which gives the young collection more time to potentially change the "_current" value, increasing the likelihood of the young collection changing the "_current" value in between the two clears.
void ZRememberedSet::clear_all() {
clear_current();
os::naked_short_nanosleep(1000);
clear_previous();
}
The stack frames for the two colliding threads are:
#0 0x0000553c7c569adf in __GI___clock_nanosleep (clock_id=clock_id@entry=0x0, flags=flags@entry=0x0, req=0x6a8020789de0, rem=0x0) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
#1 0x0000553c7c576a27 in __GI___nanosleep (req=<optimized out>, rem=<optimized out>) at ../sysdeps/unix/sysv/linux/nanosleep.c:25
#2 0x00007b5c11bd3aeb in os::naked_short_nanosleep (ns=0x989680) at /workdir/src/hotspot/os/posix/os_posix.cpp:1002
#3 os::naked_short_sleep (ms=ms@entry=0xa) at /workdir/src/hotspot/os/posix/os_posix.cpp:1008
#4 0x00007b5c1214bf1a in ZRememberedSet::clear_all (this=this@entry=0x7b5c14b585a8) at /workdir/src/hotspot/share/gc/z/zRememberedSet.cpp:82
#5 0x00007b5c12118079 in ZPage::remset_clear (this=this@entry=0x7b5c14b58540) at /workdir/src/hotspot/share/gc/z/zPage.cpp:87
#6 0x00007b5c120e4700 in ZHeap::free_empty_pages (this=0x2657140e48e0, pages=pages@entry=0x6a802078bb58) at /workdir/src/hotspot/share/gc/z/zHeap.cpp:267
#7 0x00007b5c120e00a8 in ZGeneration::free_empty_pages (bulk=0x0, selector=0x6a802078b0c0, this=0x2657140e52e0) at /workdir/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp:150
#8 ZGeneration::free_empty_pages (bulk=0x0, selector=0x6a802078b0c0, this=0x2657140e52e0) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:163
#9 ZGeneration::select_relocation_set (this=this@entry=0x2657140e52e0, generation=<optimized out>, promote_all=promote_all@entry=0x0) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:237
#10 0x00007b5c120e0d44 in ZGenerationOld::concurrent_select_relocation_set (this=0x2657140e52e0) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:1161
#11 ZGenerationOld::collect (this=0x2657140e52e0, timer=timer@entry=0x26571410cee0) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:1039
#12 0x00007b5c120d7de0 in ZDriverMajor::collect_old (this=0x26571410ca80) at /workdir/src/hotspot/share/gc/z/zGeneration.inline.hpp:71
#13 ZDriverMajor::gc (this=this@entry=0x26571410ca80, request=...) at /workdir/src/hotspot/share/gc/z/zDriver.cpp:452
#14 0x00007b5c120d7f3c in ZDriverMajor::run_thread (this=0x26571410ca80) at /workdir/src/hotspot/share/gc/z/zDriver.cpp:477
#15 0x00007b5c12161d83 in ZThread::run_service (this=0x26571410ca80) at /workdir/src/hotspot/share/gc/z/zThread.cpp:29
#16 0x00007b5c1112ac8b in ConcurrentGCThread::run (this=0x26571410ca80) at /workdir/src/hotspot/share/gc/shared/concurrentGCThread.cpp:48
#17 0x00007b5c11edc056 in Thread::call_run (this=this@entry=0x26571410ca80) at /workdir/src/hotspot/share/runtime/thread.cpp:225
#18 0x00007b5c11bc55d7 in thread_native_entry (thread=0x26571410ca80) at /workdir/src/hotspot/os/linux/os_linux.cpp:858
#19 0x0000553c7c519a94 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#20 0x0000553c7c5a6a34 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100
#0 ZRememberedSet::flip () at /workdir/src/hotspot/share/gc/z/zRememberedSet.cpp:38
#1 0x00007b5c121493e1 in ZRemembered::flip (this=this@entry=0x2657140e87b0) at /workdir/src/hotspot/share/gc/z/zRemembered.cpp:593
#2 0x00007b5c120dce4b in ZGenerationYoung::mark_start (this=0x2657140e6da0) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:877
#3 ZGenerationYoung::mark_start (this=0x2657140e6da0) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:852
#4 0x00007b5c120e1d50 in VM_ZMarkStartYoung::do_operation (this=<optimized out>) at /workdir/src/hotspot/share/gc/z/zGeneration.inline.hpp:67
#5 0x00007b5c120e1079 in VM_ZOperation::doit (this=0x65260c0e2b70) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:448
#6 0x00007b5c11fc5e87 in VM_Operation::evaluate (this=this@entry=0x65260c0e2b70) at /workdir/src/hotspot/share/runtime/vmOperations.cpp:75
#7 0x00007b5c11fe6ff4 in VMThread::evaluate_operation (this=this@entry=0x2657141e8f70, op=0x65260c0e2b70) at /workdir/src/hotspot/share/runtime/vmThread.cpp:283
#8 0x00007b5c11fe7ba3 in VMThread::inner_execute (this=this@entry=0x2657141e8f70, op=<optimized out>) at /workdir/src/hotspot/share/runtime/vmThread.cpp:427
#9 0x00007b5c11fe7d84 in VMThread::loop (this=0x2657141e8f70) at /workdir/src/hotspot/share/runtime/vmThread.cpp:493
#10 VMThread::loop (this=0x2657141e8f70) at /workdir/src/hotspot/share/runtime/vmThread.cpp:478
#11 0x00007b5c11fe7e94 in VMThread::run (this=0x2657141e8f70) at /workdir/src/hotspot/share/runtime/vmThread.cpp:177
#12 0x00007b5c11edc056 in Thread::call_run (this=this@entry=0x2657141e8f70) at /workdir/src/hotspot/share/runtime/thread.cpp:225
#13 0x00007b5c11bc55d7 in thread_native_entry (thread=0x2657141e8f70) at /workdir/src/hotspot/os/linux/os_linux.cpp:858
#14 0x0000553c7c519a94 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#15 0x0000553c7c5a6a34 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100
The code responsible for clearing the remset (ZRememberedSet::clear_all) is dependent on the "_current" variable in ZRememberedSet not being altered in between the two "clear_*" calls in ZRememberedSet::clear_all. If the remembered set is being cleared in the old collection, and successfully clears the current remset with clear_current(), a young collection might then flip/swap the current/previous remembered sets by changing the "_current" value in ZRememberedSet. This would mean that the call to clear_previous() would clean the same bitmap again, resulting in one of the two bitmaps not being cleared at all. This will later crash in an assert checking if both bitmaps are empty when the page is being freed.
void ZRememberedSet::clear_all() {
clear_current();
clear_previous();
}
This has been reproduced by adding a delay between the "clear_*" calls, like below, which gives the young collection more time to potentially change the "_current" value, increasing the likelihood of the young collection changing the "_current" value in between the two clears.
void ZRememberedSet::clear_all() {
clear_current();
os::naked_short_nanosleep(1000);
clear_previous();
}
The stack frames for the two colliding threads are:
#0 0x0000553c7c569adf in __GI___clock_nanosleep (clock_id=clock_id@entry=0x0, flags=flags@entry=0x0, req=0x6a8020789de0, rem=0x0) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
#1 0x0000553c7c576a27 in __GI___nanosleep (req=<optimized out>, rem=<optimized out>) at ../sysdeps/unix/sysv/linux/nanosleep.c:25
#2 0x00007b5c11bd3aeb in os::naked_short_nanosleep (ns=0x989680) at /workdir/src/hotspot/os/posix/os_posix.cpp:1002
#3 os::naked_short_sleep (ms=ms@entry=0xa) at /workdir/src/hotspot/os/posix/os_posix.cpp:1008
#4 0x00007b5c1214bf1a in ZRememberedSet::clear_all (this=this@entry=0x7b5c14b585a8) at /workdir/src/hotspot/share/gc/z/zRememberedSet.cpp:82
#5 0x00007b5c12118079 in ZPage::remset_clear (this=this@entry=0x7b5c14b58540) at /workdir/src/hotspot/share/gc/z/zPage.cpp:87
#6 0x00007b5c120e4700 in ZHeap::free_empty_pages (this=0x2657140e48e0, pages=pages@entry=0x6a802078bb58) at /workdir/src/hotspot/share/gc/z/zHeap.cpp:267
#7 0x00007b5c120e00a8 in ZGeneration::free_empty_pages (bulk=0x0, selector=0x6a802078b0c0, this=0x2657140e52e0) at /workdir/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp:150
#8 ZGeneration::free_empty_pages (bulk=0x0, selector=0x6a802078b0c0, this=0x2657140e52e0) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:163
#9 ZGeneration::select_relocation_set (this=this@entry=0x2657140e52e0, generation=<optimized out>, promote_all=promote_all@entry=0x0) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:237
#10 0x00007b5c120e0d44 in ZGenerationOld::concurrent_select_relocation_set (this=0x2657140e52e0) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:1161
#11 ZGenerationOld::collect (this=0x2657140e52e0, timer=timer@entry=0x26571410cee0) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:1039
#12 0x00007b5c120d7de0 in ZDriverMajor::collect_old (this=0x26571410ca80) at /workdir/src/hotspot/share/gc/z/zGeneration.inline.hpp:71
#13 ZDriverMajor::gc (this=this@entry=0x26571410ca80, request=...) at /workdir/src/hotspot/share/gc/z/zDriver.cpp:452
#14 0x00007b5c120d7f3c in ZDriverMajor::run_thread (this=0x26571410ca80) at /workdir/src/hotspot/share/gc/z/zDriver.cpp:477
#15 0x00007b5c12161d83 in ZThread::run_service (this=0x26571410ca80) at /workdir/src/hotspot/share/gc/z/zThread.cpp:29
#16 0x00007b5c1112ac8b in ConcurrentGCThread::run (this=0x26571410ca80) at /workdir/src/hotspot/share/gc/shared/concurrentGCThread.cpp:48
#17 0x00007b5c11edc056 in Thread::call_run (this=this@entry=0x26571410ca80) at /workdir/src/hotspot/share/runtime/thread.cpp:225
#18 0x00007b5c11bc55d7 in thread_native_entry (thread=0x26571410ca80) at /workdir/src/hotspot/os/linux/os_linux.cpp:858
#19 0x0000553c7c519a94 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#20 0x0000553c7c5a6a34 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100
#0 ZRememberedSet::flip () at /workdir/src/hotspot/share/gc/z/zRememberedSet.cpp:38
#1 0x00007b5c121493e1 in ZRemembered::flip (this=this@entry=0x2657140e87b0) at /workdir/src/hotspot/share/gc/z/zRemembered.cpp:593
#2 0x00007b5c120dce4b in ZGenerationYoung::mark_start (this=0x2657140e6da0) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:877
#3 ZGenerationYoung::mark_start (this=0x2657140e6da0) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:852
#4 0x00007b5c120e1d50 in VM_ZMarkStartYoung::do_operation (this=<optimized out>) at /workdir/src/hotspot/share/gc/z/zGeneration.inline.hpp:67
#5 0x00007b5c120e1079 in VM_ZOperation::doit (this=0x65260c0e2b70) at /workdir/src/hotspot/share/gc/z/zGeneration.cpp:448
#6 0x00007b5c11fc5e87 in VM_Operation::evaluate (this=this@entry=0x65260c0e2b70) at /workdir/src/hotspot/share/runtime/vmOperations.cpp:75
#7 0x00007b5c11fe6ff4 in VMThread::evaluate_operation (this=this@entry=0x2657141e8f70, op=0x65260c0e2b70) at /workdir/src/hotspot/share/runtime/vmThread.cpp:283
#8 0x00007b5c11fe7ba3 in VMThread::inner_execute (this=this@entry=0x2657141e8f70, op=<optimized out>) at /workdir/src/hotspot/share/runtime/vmThread.cpp:427
#9 0x00007b5c11fe7d84 in VMThread::loop (this=0x2657141e8f70) at /workdir/src/hotspot/share/runtime/vmThread.cpp:493
#10 VMThread::loop (this=0x2657141e8f70) at /workdir/src/hotspot/share/runtime/vmThread.cpp:478
#11 0x00007b5c11fe7e94 in VMThread::run (this=0x2657141e8f70) at /workdir/src/hotspot/share/runtime/vmThread.cpp:177
#12 0x00007b5c11edc056 in Thread::call_run (this=this@entry=0x2657141e8f70) at /workdir/src/hotspot/share/runtime/thread.cpp:225
#13 0x00007b5c11bc55d7 in thread_native_entry (thread=0x2657141e8f70) at /workdir/src/hotspot/os/linux/os_linux.cpp:858
#14 0x0000553c7c519a94 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#15 0x0000553c7c5a6a34 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100
- relates to
-
JDK-8339163 ZGC: Race in clearing of remembered sets
- Resolved
- links to
-
Commit(master) openjdk/jdk/ab656c3a
-
Review(master) openjdk/jdk/20869