PERFORCE change 134489 for review
John Birrell
jb at FreeBSD.org
Wed Jan 30 14:34:17 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=134489
Change 134489 by jb at jb_freebsd1 on 2008/01/30 22:34:16
IFdtrace.
Affected files ...
.. //depot/projects/dtrace7/src/sys/kern/subr_smp.c#2 edit
.. //depot/projects/dtrace7/src/sys/sys/smp.h#2 edit
Differences ...
==== //depot/projects/dtrace7/src/sys/kern/subr_smp.c#2 (text+ko) ====
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/subr_smp.c,v 1.201 2007/09/11 22:54:09 attilio Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/subr_smp.c,v 1.203 2008/01/02 17:09:15 jhb Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -74,6 +74,9 @@
SYSCTL_NODE(_kern, OID_AUTO, smp, CTLFLAG_RD, NULL, "Kernel SMP");
+SYSCTL_INT(_kern_smp, OID_AUTO, maxid, CTLFLAG_RD, &mp_maxid, 0,
+ "Max CPU ID.");
+
SYSCTL_INT(_kern_smp, OID_AUTO, maxcpus, CTLFLAG_RD, &mp_maxcpus, 0,
"Max number of CPUs that the system was compiled for.");
@@ -104,10 +107,11 @@
"Forwarding of roundrobin to all other CPUs");
/* Variables needed for SMP rendezvous. */
-static void (*smp_rv_setup_func)(void *arg);
-static void (*smp_rv_action_func)(void *arg);
-static void (*smp_rv_teardown_func)(void *arg);
-static void *smp_rv_func_arg;
+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);
+static void * volatile smp_rv_func_arg;
static volatile int smp_rv_waiters[3];
/*
@@ -286,6 +290,14 @@
return 1;
}
+void
+smp_no_rendevous_barrier(void *dummy)
+{
+#ifdef SMP
+ KASSERT((!smp_started),("smp_no_rendevous called and smp is started"));
+#endif
+}
+
/*
* All-CPU rendezvous. CPUs are signalled, all execute the setup function
* (if specified), rendezvous, execute the action function (if specified),
@@ -298,41 +310,57 @@
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 */
- if (smp_rv_setup_func != NULL)
- smp_rv_setup_func(smp_rv_func_arg);
+ if (local_setup_func != smp_no_rendevous_barrier) {
+ if (smp_rv_setup_func != NULL)
+ 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)
- cpu_spinwait();
+ /* spin on entry rendezvous */
+ atomic_add_int(&smp_rv_waiters[1], 1);
+ while (smp_rv_waiters[1] < ncpus)
+ cpu_spinwait();
+ }
/* action function */
- if (smp_rv_action_func != NULL)
- smp_rv_action_func(smp_rv_func_arg);
+ if (local_action_func != NULL)
+ local_action_func(local_func_arg);
/* spin on exit rendezvous */
atomic_add_int(&smp_rv_waiters[2], 1);
- while (smp_rv_waiters[2] < mp_ncpus)
+ if (local_teardown_func == smp_no_rendevous_barrier)
+ return;
+ while (smp_rv_waiters[2] < ncpus)
cpu_spinwait();
/* teardown function */
- if (smp_rv_teardown_func != NULL)
- smp_rv_teardown_func(smp_rv_func_arg);
+ if (local_teardown_func != NULL)
+ local_teardown_func(local_func_arg);
}
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)
@@ -343,11 +371,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;
@@ -357,14 +390,29 @@
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);
+
+ /* Check if the current CPU is in the map */
+ if ((map & (1 << curcpu)) != 0)
+ /* call executor function for the current CPU */
+ smp_rendezvous_action();
- /* call executor function */
- smp_rendezvous_action();
+ if (teardown_func == smp_no_rendevous_barrier)
+ 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 */
/*
@@ -383,9 +431,24 @@
mp_setvariables_for_up, NULL)
void
-smp_rendezvous(void (* setup_func)(void *),
- void (* action_func)(void *),
- void (* teardown_func)(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 *),
void *arg)
{
==== //depot/projects/dtrace7/src/sys/sys/smp.h#2 (text+ko) ====
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $FreeBSD: src/sys/sys/smp.h,v 1.85 2005/10/24 21:04:19 jhb Exp $
+ * $FreeBSD: src/sys/sys/smp.h,v 1.86 2007/11/08 14:47:55 ups Exp $
*/
#ifndef _SYS_SMP_H_
@@ -100,6 +100,7 @@
int restart_cpus(cpumask_t);
int stop_cpus(cpumask_t);
void smp_rendezvous_action(void);
+void smp_no_rendevous_barrier(void *);
extern struct mtx smp_ipi_mtx;
#endif /* SMP */
@@ -107,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_ */
More information about the p4-projects
mailing list