Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 30 Jan 2008 22:34:16 GMT
From:      John Birrell <jb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 134489 for review
Message-ID:  <200801302234.m0UMYG7Y017161@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=134489

Change 134489 by jb@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_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200801302234.m0UMYG7Y017161>