From owner-svn-src-user@FreeBSD.ORG Thu May 12 09:24:50 2011 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DFB2B106566B; Thu, 12 May 2011 09:24:50 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id B5D2F8FC0A; Thu, 12 May 2011 09:24:50 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p4C9OoEI028830; Thu, 12 May 2011 09:24:50 GMT (envelope-from avg@svn.freebsd.org) Received: (from avg@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p4C9Oo4H028828; Thu, 12 May 2011 09:24:50 GMT (envelope-from avg@svn.freebsd.org) Message-Id: <201105120924.p4C9Oo4H028828@svn.freebsd.org> From: Andriy Gapon Date: Thu, 12 May 2011 09:24:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r221804 - user/avg/xcpu/sys/kern X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 May 2011 09:24:51 -0000 Author: avg Date: Thu May 12 09:24:50 2011 New Revision: 221804 URL: http://svn.freebsd.org/changeset/base/221804 Log: (re-)add another rendezvous counter The problem was that if a master cpu calls rendezvous in rapid succession then the rendezvous object could be re-used while some slave cpus were still spinning on the dual-function teardown/exit counter if a teardown function was actually specified. To fix this problem use separate counters, one for teardown entry and the other for signaling full rendezvous completion. Modified: user/avg/xcpu/sys/kern/subr_smp.c Modified: user/avg/xcpu/sys/kern/subr_smp.c ============================================================================== --- user/avg/xcpu/sys/kern/subr_smp.c Thu May 12 07:44:41 2011 (r221803) +++ user/avg/xcpu/sys/kern/subr_smp.c Thu May 12 09:24:50 2011 (r221804) @@ -118,7 +118,7 @@ struct smp_rendezvous_data { void (*smp_rv_action_func)(void *arg); void (*smp_rv_teardown_func)(void *arg); void *smp_rv_func_arg; - volatile int smp_rv_waiters[2]; + volatile int smp_rv_waiters[3]; int smp_rv_ncpus; }; @@ -439,17 +439,19 @@ smp_rendezvous_action_body(int cpu) if (local_action_func != NULL) local_action_func(local_func_arg); - atomic_add_int(&rv->smp_rv_waiters[1], 1); - if (local_teardown_func == smp_no_rendevous_barrier) - return; + if (local_teardown_func != smp_no_rendevous_barrier) { + /* spin on exit rendezvous */ + atomic_add_int(&rv->smp_rv_waiters[1], 1); + while (rv->smp_rv_waiters[1] < ncpus) + cpu_spinwait(); - /* spin on exit rendezvous */ - while (rv->smp_rv_waiters[1] < ncpus) - cpu_spinwait(); + atomic_add_int(&rv->smp_rv_waiters[2], 1); - /* teardown function */ - if (local_teardown_func != NULL) - local_teardown_func(local_func_arg); + /* teardown function */ + if (local_teardown_func != NULL) + local_teardown_func(local_func_arg); + } else + atomic_add_int(&rv->smp_rv_waiters[2], 1); } void @@ -492,7 +494,7 @@ smp_rendezvous_wait(void) rv = DPCPU_PTR(smp_rv_data); ncpus = rv->smp_rv_ncpus; - while (atomic_load_acq_int(&rv->smp_rv_waiters[1]) < ncpus) { + while (atomic_load_acq_int(&rv->smp_rv_waiters[2]) < ncpus) { /* check for incoming events */ if ((stopping_cpus & (1 << curcpu)) != 0) cpustop_handler(); @@ -580,6 +582,7 @@ smp_rendezvous_cpus(cpumask_t map, rv->smp_rv_teardown_func = teardown_func; rv->smp_rv_func_arg = arg; rv->smp_rv_waiters[1] = 0; + rv->smp_rv_waiters[2] = 0; atomic_store_rel_int(&rv->smp_rv_waiters[0], 0); /* signal other CPUs, which will enter the IPI with interrupts off */