From owner-p4-projects@FreeBSD.ORG Wed Dec 26 23:43:05 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 5C36C16A468; Wed, 26 Dec 2007 23:43:05 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id ABB6D16A420 for ; Wed, 26 Dec 2007 23:43:04 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id A066613C468 for ; Wed, 26 Dec 2007 23:43:04 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id lBQNh4t8016286 for ; Wed, 26 Dec 2007 23:43:04 GMT (envelope-from jb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id lBQNh41b016283 for perforce@freebsd.org; Wed, 26 Dec 2007 23:43:04 GMT (envelope-from jb@freebsd.org) Date: Wed, 26 Dec 2007 23:43:04 GMT Message-Id: <200712262343.lBQNh41b016283@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jb@freebsd.org using -f From: John Birrell To: Perforce Change Reviews Cc: Subject: PERFORCE change 131741 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 Dec 2007 23:43:05 -0000 http://perforce.freebsd.org/chv.cgi?CH=131741 Change 131741 by jb@jb_freebsd1 on 2007/12/26 23:42:52 Add support to rendezvous calls to specific CPUs. Sun uses an xcall facility in OpenSolaris. This is our equivalent. Affected files ... .. //depot/projects/dtrace/src/sys/kern/subr_smp.c#7 edit .. //depot/projects/dtrace/src/sys/sys/smp.h#5 edit Differences ... ==== //depot/projects/dtrace/src/sys/kern/subr_smp.c#7 (text+ko) ==== @@ -104,6 +104,7 @@ "Forwarding of roundrobin to all other CPUs"); /* Variables needed for SMP rendezvous. */ +static volatile cpumask_t smp_rv_cpumask; static void (*volatile smp_rv_setup_func)(void *arg); static void (*volatile smp_rv_action_func)(void *arg); static void (* volatile smp_rv_teardown_func)(void *arg); @@ -305,14 +306,20 @@ void smp_rendezvous_action(void) { + cpumask_t map = smp_rv_cpumask; + int i, ncpus = 0; void* local_func_arg = smp_rv_func_arg; void (*local_setup_func)(void*) = smp_rv_setup_func; void (*local_action_func)(void*) = smp_rv_action_func; void (*local_teardown_func)(void*) = smp_rv_teardown_func; + + for (i = 0; i < MAXCPU; i++) + if (((1 << i) & map) != 0 && pcpu_find(i) != NULL) + ncpus++; /* Ensure we have up-to-date values. */ atomic_add_acq_int(&smp_rv_waiters[0], 1); - while (smp_rv_waiters[0] < mp_ncpus) + while (smp_rv_waiters[0] < ncpus) cpu_spinwait(); /* setup function */ @@ -321,7 +328,7 @@ smp_rv_setup_func(smp_rv_func_arg); /* spin on entry rendezvous */ atomic_add_int(&smp_rv_waiters[1], 1); - while (smp_rv_waiters[1] < mp_ncpus) + while (smp_rv_waiters[1] < ncpus) cpu_spinwait(); } @@ -335,7 +342,7 @@ atomic_add_int(&smp_rv_waiters[2], 1); if (local_teardown_func == smp_no_rendevous_barrier) return; - while (smp_rv_waiters[2] < mp_ncpus) + while (smp_rv_waiters[2] < ncpus) cpu_spinwait(); /* teardown function */ if (local_teardown_func != NULL) @@ -343,11 +350,13 @@ } void -smp_rendezvous(void (* setup_func)(void *), - void (* action_func)(void *), - void (* teardown_func)(void *), - void *arg) +smp_rendezvous_cpus(cpumask_t map, + void (* setup_func)(void *), + void (* action_func)(void *), + void (* teardown_func)(void *), + void *arg) { + int i, ncpus = 0; if (!smp_started) { if (setup_func != NULL) @@ -358,11 +367,16 @@ teardown_func(arg); return; } + + for (i = 0; i < MAXCPU; i++) + if (((1 << i) & map) != 0 && pcpu_find(i) != NULL) + ncpus++; /* obtain rendezvous lock */ mtx_lock_spin(&smp_ipi_mtx); /* set static function pointers */ + smp_rv_cpumask = map & ~(1 << curcpu); smp_rv_setup_func = setup_func; smp_rv_action_func = action_func; smp_rv_teardown_func = teardown_func; @@ -371,21 +385,30 @@ smp_rv_waiters[2] = 0; atomic_store_rel_int(&smp_rv_waiters[0], 0); - - /* signal other processors, which will enter the IPI with interrupts off */ - ipi_all_but_self(IPI_RENDEZVOUS); + ipi_selected(map, IPI_RENDEZVOUS); - /* call executor function */ - smp_rendezvous_action(); + /* Check if the current CPU is in the map */ + if ((map & (1 << curcpu)) != 0) + /* call executor function for the current CPU */ + smp_rendezvous_action(); if (teardown_func == smp_no_rendevous_barrier) { - while (atomic_load_acq_int(&smp_rv_waiters[2]) < mp_ncpus) + while (atomic_load_acq_int(&smp_rv_waiters[2]) < ncpus) cpu_spinwait(); } /* release lock */ mtx_unlock_spin(&smp_ipi_mtx); } + +void +smp_rendezvous(void (* setup_func)(void *), + void (* action_func)(void *), + void (* teardown_func)(void *), + void *arg) +{ + smp_rendezvous_cpus(all_cpus, setup_func, action_func, teardown_func, arg); +} #else /* !SMP */ /* @@ -404,6 +427,21 @@ mp_setvariables_for_up, NULL) void +smp_rendezvous_cpus(cpumask_t map, + void (* setup_func)(void *), + void (* action_func)(void *), + void (* teardown_func)(void *), + void *arg) +{ + if (setup_func != NULL) + setup_func(arg); + if (action_func != NULL) + action_func(arg); + if (teardown_func != NULL) + teardown_func(arg); +} + +void smp_rendezvous(void (* setup_func)(void *), void (* action_func)(void *), void (* teardown_func)(void *), ==== //depot/projects/dtrace/src/sys/sys/smp.h#5 (text+ko) ==== @@ -108,6 +108,11 @@ void (*)(void *), void (*)(void *), void *arg); +void smp_rendezvous_cpus(cpumask_t, + void (*)(void *), + void (*)(void *), + void (*)(void *), + void *arg); #endif /* !LOCORE */ #endif /* _KERNEL */ #endif /* _SYS_SMP_H_ */