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
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Thu Jan 27 16:11:27 2011 -0800
+++ b/hotspot/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");