# HG changeset patch # User tonyp # Date 1296509320 18000 # Node ID 908c5092d72a8e7697995d4016035d28892f45d1 # Parent 4e66274b6bb326b2087bf779be9a441b7ed8a810 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 diff -r 4e66274b6bb3 -r 908c5092d72a src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Tue Jan 25 17:58:19 2011 -0500 +++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Mon Jan 31 16:28:40 2011 -0500 @@ -251,6 +251,14 @@ // Now do the remainder of the cleanup operation. _cm->completeCleanup(); + // Notify anyone who's waiting that there are no more free + // regions coming. We have to do this before we join the STS, + // otherwise we might deadlock: a GC worker could be blocked + // waiting for the notification whereas this thread will be + // blocked for the pause to finish while it's trying to join + // the STS, which is conditional on the GC workers finishing. + g1h->reset_free_regions_coming(); + _sts.join(); g1_policy->record_concurrent_mark_cleanup_completed(); _sts.leave(); @@ -262,9 +270,6 @@ gclog_or_tty->print_cr("[GC concurrent-cleanup-end, %1.7lf]", cleanup_end_sec - cleanup_start_sec); } - - // We're done: no more free regions coming. - g1h->reset_free_regions_coming(); } guarantee(cm()->cleanup_list_is_empty(), "at this point there should be no regions on the cleanup list");