Mon, 31 Jan 2011 16:28:40 -0500
7014679: G1: deadlock during concurrent cleanup
Summary: There's a potential deadlock between the concurrent cleanup thread and the GC workers that are trying to allocate and waiting for more free regions to be made available.
Reviewed-by: iveresov, jcoomes
src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Thu Jan 27 16:11:27 2011 -0800 1.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Mon Jan 31 16:28:40 2011 -0500 1.3 @@ -251,6 +251,14 @@ 1.4 1.5 // Now do the remainder of the cleanup operation. 1.6 _cm->completeCleanup(); 1.7 + // Notify anyone who's waiting that there are no more free 1.8 + // regions coming. We have to do this before we join the STS, 1.9 + // otherwise we might deadlock: a GC worker could be blocked 1.10 + // waiting for the notification whereas this thread will be 1.11 + // blocked for the pause to finish while it's trying to join 1.12 + // the STS, which is conditional on the GC workers finishing. 1.13 + g1h->reset_free_regions_coming(); 1.14 + 1.15 _sts.join(); 1.16 g1_policy->record_concurrent_mark_cleanup_completed(); 1.17 _sts.leave(); 1.18 @@ -262,9 +270,6 @@ 1.19 gclog_or_tty->print_cr("[GC concurrent-cleanup-end, %1.7lf]", 1.20 cleanup_end_sec - cleanup_start_sec); 1.21 } 1.22 - 1.23 - // We're done: no more free regions coming. 1.24 - g1h->reset_free_regions_coming(); 1.25 } 1.26 guarantee(cm()->cleanup_list_is_empty(), 1.27 "at this point there should be no regions on the cleanup list");