From patchwork Thu Aug 26 22:10:38 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 62809 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 9094DB70DD for ; Fri, 27 Aug 2010 08:10:59 +1000 (EST) Received: (qmail 1372 invoked by alias); 26 Aug 2010 22:10:57 -0000 Received: (qmail 1363 invoked by uid 22791); 26 Aug 2010 22:10:56 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, SPF_HELO_PASS, TW_CC, T_RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.44.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 26 Aug 2010 22:10:47 +0000 Received: from kpbe14.cbf.corp.google.com (kpbe14.cbf.corp.google.com [172.25.105.78]) by smtp-out.google.com with ESMTP id o7QMAi6w031005 for ; Thu, 26 Aug 2010 15:10:44 -0700 Received: from pwj5 (pwj5.prod.google.com [10.241.219.69]) by kpbe14.cbf.corp.google.com with ESMTP id o7QMAhx7012071 for ; Thu, 26 Aug 2010 15:10:43 -0700 Received: by pwj5 with SMTP id 5so950900pwj.35 for ; Thu, 26 Aug 2010 15:10:43 -0700 (PDT) Received: by 10.142.229.13 with SMTP id b13mr375485wfh.304.1282860643057; Thu, 26 Aug 2010 15:10:43 -0700 (PDT) Received: from coign.google.com ([216.239.45.130]) by mx.google.com with ESMTPS id 23sm3487391wfa.22.2010.08.26.15.10.40 (version=TLSv1/SSLv3 cipher=RC4-MD5); Thu, 26 Aug 2010 15:10:41 -0700 (PDT) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: [gccgo] Avoid GC deadlock Date: Thu, 26 Aug 2010 15:10:38 -0700 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org I discovered a possible deadlock in the garbage collector due to memory profiling. When a thread is gathering data for memory profiling, it postpones GC until that is complete. The same happens during memory allocation. However, memory profiling can actually lead to memory allocation. Because the code used the same variable to postpone GC, that can cause the GC to start when the memory allocation is complete but memory profiling is still active. That can in turn cause a deadlock when the GC releases memory profiling data. This patch avoids the deadlock by using a different variable to postpone GC while doing memory profiling. Committed to gccgo branch. Ian diff -r b20eed5a1425 libgo/runtime/go-go.c --- a/libgo/runtime/go-go.c Wed Aug 25 16:59:52 2010 -0700 +++ b/libgo/runtime/go-go.c Thu Aug 26 15:06:20 2010 -0700 @@ -323,7 +323,7 @@ /* Similarly, we can't interrupt the thread while it is building profiling information. Otherwise we can get into a deadlock when sweepspan calls MProf_Free. */ - __sync_bool_compare_and_swap (&pm->gcing, 0, 1); + __sync_bool_compare_and_swap (&pm->gcing_for_prof, 0, 1); return; } diff -r b20eed5a1425 libgo/runtime/mprof.goc --- a/libgo/runtime/mprof.goc Wed Aug 25 16:59:52 2010 -0700 +++ b/libgo/runtime/mprof.goc Thu Aug 26 15:06:20 2010 -0700 @@ -208,7 +208,7 @@ unlock(&proflock); __sync_bool_compare_and_swap(&m->nomemprof, 1, 0); - if(__sync_bool_compare_and_swap(&m->gcing, 1, 0)) + if(__sync_bool_compare_and_swap(&m->gcing_for_prof, 1, 0)) __go_run_goroutine_gc(100); } @@ -230,7 +230,7 @@ unlock(&proflock); __sync_bool_compare_and_swap(&m->nomemprof, 1, 0); - if(__sync_bool_compare_and_swap(&m->gcing, 1, 0)) + if(__sync_bool_compare_and_swap(&m->gcing_for_prof, 1, 0)) __go_run_goroutine_gc(101); } @@ -285,7 +285,7 @@ __sync_bool_compare_and_swap(&m->nomemprof, 1, 0); - if(__sync_bool_compare_and_swap(&m->gcing, 1, 0)) + if(__sync_bool_compare_and_swap(&m->gcing_for_prof, 1, 0)) __go_run_goroutine_gc(102); } diff -r b20eed5a1425 libgo/runtime/runtime.h --- a/libgo/runtime/runtime.h Wed Aug 25 16:59:52 2010 -0700 +++ b/libgo/runtime/runtime.h Thu Aug 26 15:06:20 2010 -0700 @@ -94,6 +94,7 @@ int32 gcing; int32 locks; int32 nomemprof; + int32 gcing_for_prof; MCache *mcache; /* For the list of all threads. */