Module Name:    src
Committed By:   riz
Date:           Mon Feb 11 20:42:32 UTC 2013

Modified Files:
        src/sys/kern [netbsd-6]: subr_pserialize.c

Log Message:
Pull up following revision(s) (requested by rmind in ticket #811):
        sys/kern/subr_pserialize.c: revision 1.7
- pserialize_switchpoint: check for passing twice, not more than needed.
- pserialize_perform: avoid a possible race with softint handler.
Reported by hannken@.


To generate a diff of this commit:
cvs rdiff -u -r1.5.2.1 -r1.5.2.2 src/sys/kern/subr_pserialize.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/subr_pserialize.c
diff -u src/sys/kern/subr_pserialize.c:1.5.2.1 src/sys/kern/subr_pserialize.c:1.5.2.2
--- src/sys/kern/subr_pserialize.c:1.5.2.1	Fri Feb  8 19:32:07 2013
+++ src/sys/kern/subr_pserialize.c	Mon Feb 11 20:42:32 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_pserialize.c,v 1.5.2.1 2013/02/08 19:32:07 riz Exp $	*/
+/*	$NetBSD: subr_pserialize.c,v 1.5.2.2 2013/02/11 20:42:32 riz Exp $	*/
 
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_pserialize.c,v 1.5.2.1 2013/02/08 19:32:07 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_pserialize.c,v 1.5.2.2 2013/02/11 20:42:32 riz Exp $");
 
 #include <sys/param.h>
 
@@ -48,13 +48,13 @@ __KERNEL_RCSID(0, "$NetBSD: subr_pserial
 #include <sys/kmem.h>
 #include <sys/mutex.h>
 #include <sys/pserialize.h>
+#include <sys/proc.h>
 #include <sys/queue.h>
 #include <sys/xcall.h>
 
 struct pserialize {
 	TAILQ_ENTRY(pserialize)	psz_chain;
 	lwp_t *			psz_owner;
-	kcondvar_t		psz_notifier;
 	kcpuset_t *		psz_target;
 	kcpuset_t *		psz_pass;
 };
@@ -102,7 +102,6 @@ pserialize_create(void)
 	pserialize_t psz;
 
 	psz = kmem_zalloc(sizeof(struct pserialize), KM_SLEEP);
-	cv_init(&psz->psz_notifier, "psrlz");
 	kcpuset_create(&psz->psz_target, true);
 	kcpuset_create(&psz->psz_pass, true);
 	psz->psz_owner = NULL;
@@ -121,7 +120,6 @@ pserialize_destroy(pserialize_t psz)
 
 	KASSERT(psz->psz_owner == NULL);
 
-	cv_destroy(&psz->psz_notifier);
 	kcpuset_destroy(psz->psz_target);
 	kcpuset_destroy(psz->psz_pass);
 	kmem_free(psz, sizeof(struct pserialize));
@@ -163,27 +161,21 @@ pserialize_perform(pserialize_t psz)
 	mutex_spin_enter(&psz_lock);
 	TAILQ_INSERT_TAIL(&psz_queue0, psz, psz_chain);
 	psz_work_todo++;
-	mutex_spin_exit(&psz_lock);
 
-	/*
-	 * Force some context switch activity on every CPU, as the system
-	 * may not be busy.  Note: should pass the point twice.
-	 */
-	xc = xc_broadcast(XC_HIGHPRI, (xcfunc_t)nullop, NULL, NULL);
-	xc_wait(xc);
+	do {
+		mutex_spin_exit(&psz_lock);
 
-	/* No need to xc_wait() as we implement our own condvar. */
-	xc_broadcast(XC_HIGHPRI, (xcfunc_t)nullop, NULL, NULL);
+		/*
+		 * Force some context switch activity on every CPU, as
+		 * the system may not be busy.  Pause to not flood.
+		 */
+		xc = xc_broadcast(XC_HIGHPRI, (xcfunc_t)nullop, NULL, NULL);
+		xc_wait(xc);
+		kpause("psrlz", false, 1, NULL);
+
+		mutex_spin_enter(&psz_lock);
+	} while (!kcpuset_iszero(psz->psz_target));
 
-	/*
-	 * Wait for all CPUs to cycle through mi_switch() twice.
-	 * The last one through will remove our update from the
-	 * queue and awaken us.
-	 */
-	mutex_spin_enter(&psz_lock);
-	while (!kcpuset_iszero(psz->psz_target)) {
-		cv_wait(&psz->psz_notifier, &psz_lock);
-	}
 	psz_ev_excl.ev_count++;
 	mutex_spin_exit(&psz_lock);
 
@@ -236,8 +228,8 @@ pserialize_switchpoint(void)
 	 */
 	for (psz = TAILQ_FIRST(&psz_queue1); psz != NULL; psz = next) {
 		next = TAILQ_NEXT(psz, psz_chain);
+		kcpuset_set(psz->psz_pass, cid);
 		if (!kcpuset_match(psz->psz_pass, psz->psz_target)) {
-			kcpuset_set(psz->psz_pass, cid);
 			continue;
 		}
 		kcpuset_zero(psz->psz_pass);
@@ -250,8 +242,8 @@ pserialize_switchpoint(void)
 	 */
 	for (psz = TAILQ_FIRST(&psz_queue0); psz != NULL; psz = next) {
 		next = TAILQ_NEXT(psz, psz_chain);
+		kcpuset_set(psz->psz_pass, cid);
 		if (!kcpuset_match(psz->psz_pass, psz->psz_target)) {
-			kcpuset_set(psz->psz_pass, cid);
 			continue;
 		}
 		kcpuset_zero(psz->psz_pass);
@@ -265,7 +257,6 @@ pserialize_switchpoint(void)
 	while ((psz = TAILQ_FIRST(&psz_queue2)) != NULL) {
 		TAILQ_REMOVE(&psz_queue2, psz, psz_chain);
 		kcpuset_zero(psz->psz_target);
-		cv_signal(&psz->psz_notifier);
 		psz_work_todo--;
 	}
 	mutex_spin_exit(&psz_lock);

Reply via email to