PERFORCE change 131741 for review
John Birrell
jb at FreeBSD.org
Wed Dec 26 15:43:05 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=131741
Change 131741 by jb at 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_ */
More information about the p4-projects
mailing list