# HG changeset patch # User tonyp # Date 1296509320 18000 # Node ID b7a938236e4312113bed5b078e77e783dd404001 # Parent 3582bf76420e440f9d58d5bf6c9221a704c066ec 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 3582bf76420e -r b7a938236e43 src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Thu Jan 27 16:11:27 2011 -0800 +++ 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");