proposed smp_rendezvous change

Andriy Gapon avg at FreeBSD.org
Fri May 13 15:28:39 UTC 2011


on 13/05/2011 17:41 Max Laier said the following:
> this ncpus isn't the one you are looking for.

Thank you!

Here's an updated patch:

Index: sys/kern/subr_smp.c
===================================================================
--- sys/kern/subr_smp.c	(revision 221835)
+++ sys/kern/subr_smp.c	(working copy)
@@ -316,19 +316,14 @@
 	void (*local_action_func)(void*)   = smp_rv_action_func;
 	void (*local_teardown_func)(void*) = smp_rv_teardown_func;

-	/* Ensure we have up-to-date values. */
-	atomic_add_acq_int(&smp_rv_waiters[0], 1);
-	while (smp_rv_waiters[0] < smp_rv_ncpus)
-		cpu_spinwait();
-
 	/* setup function */
 	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] < smp_rv_ncpus)
+		atomic_add_int(&smp_rv_waiters[0], 1);
+		while (smp_rv_waiters[0] < smp_rv_ncpus)
                 	cpu_spinwait();
 	}

@@ -337,12 +332,16 @@
 		local_action_func(local_func_arg);

 	/* spin on exit rendezvous */
-	atomic_add_int(&smp_rv_waiters[2], 1);
-	if (local_teardown_func == smp_no_rendevous_barrier)
+	atomic_add_int(&smp_rv_waiters[1], 1);
+	if (local_teardown_func == smp_no_rendevous_barrier) {
+		atomic_add_int(&smp_rv_waiters[2], 1);
                 return;
-	while (smp_rv_waiters[2] < smp_rv_ncpus)
+	}
+	while (smp_rv_waiters[1] < smp_rv_ncpus)
 		cpu_spinwait();

+	atomic_add_int(&smp_rv_waiters[2], 1);
+
 	/* teardown function */
 	if (local_teardown_func != NULL)
 		local_teardown_func(local_func_arg);
@@ -377,6 +376,10 @@
 	/* obtain rendezvous lock */
 	mtx_lock_spin(&smp_ipi_mtx);

+	/* Wait for any previous unwaited rendezvous to finish. */
+	while (atomic_load_acq_int(&smp_rv_waiters[2]) < smp_rv_ncpus)
+		cpu_spinwait();
+
 	/* set static function pointers */
 	smp_rv_ncpus = ncpus;
 	smp_rv_setup_func = setup_func;
@@ -395,7 +398,7 @@
 		smp_rendezvous_action();

 	if (teardown_func == smp_no_rendevous_barrier)
-		while (atomic_load_acq_int(&smp_rv_waiters[2]) < ncpus)
+		while (atomic_load_acq_int(&smp_rv_waiters[1]) < ncpus)
 			cpu_spinwait();

 	/* release lock */


More information about the freebsd-current mailing list