Pausing/resuming CPU's in DDB

Julian Coleman <[email protected]>
Newsgroups gmane.os.netbsd.ports.sparc64
Message-ID <[email protected]>
Hi,

On my 8-way E3500, I almost always see some of the CPU's fail to pause when
entering DDB, and fail to resume when leaving.  This makes it hard to obtain
CPU-specific information for some CPU's.  Martin suggested that a loop around
the pause/resume code might help here, and the attached patch works for me.
Does anyone see any problem with it?

Thanks,

J

-- 
  My other computer also runs NetBSD    /        Sailing at Newbiggin
        http://www.netbsd.org/        /   http://www.newbigginsailingclub.org/
ipifuncs.c.diff (text/plain, 1.6 KB)
Index: ipifuncs.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/ipifuncs.c,v
retrieving revision 1.44
diff -u -r1.44 ipifuncs.c
--- ipifuncs.c	12 Feb 2012 16:34:10 -0000	1.44
+++ ipifuncs.c	22 Feb 2012 08:09:09 -0000
@@ -325,17 +325,21 @@
 void
 mp_pause_cpus(void)
 {
+	int i = 3;
 	sparc64_cpuset_t cpuset;
 
-	CPUSET_ASSIGN(cpuset, cpus_active);
-	CPUSET_DEL(cpuset, cpu_number());
-
-	if (CPUSET_EMPTY(cpuset))
-		return;
-
-	sparc64_multicast_ipi(cpuset, sparc64_ipi_pause, 0, 0);
-	if (sparc64_ipi_wait(&cpus_paused, cpuset))
-		sparc64_ipi_error("pause", cpus_paused, cpuset);
+	while (i-- > 0) {
+		CPUSET_ASSIGN(cpuset, cpus_active);
+		CPUSET_DEL(cpuset, cpu_number());
+
+		if (CPUSET_EMPTY(cpuset))
+			return;
+
+		sparc64_multicast_ipi(cpuset, sparc64_ipi_pause, 0, 0);
+		if (!sparc64_ipi_wait(&cpus_paused, cpuset))
+			return;
+	}
+	sparc64_ipi_error("pause", cpus_paused, cpuset);
 }
 
 /*
@@ -354,16 +358,20 @@
 void
 mp_resume_cpus(void)
 {
+	int i = 3;
 	sparc64_cpuset_t cpuset;
 
-	CPUSET_CLEAR(cpus_resumed);
-	CPUSET_ASSIGN(cpuset, cpus_paused);
-	membar_Sync();
-	CPUSET_CLEAR(cpus_paused);
-
-	/* CPUs awake on cpus_paused clear */
-	if (sparc64_ipi_wait(&cpus_resumed, cpuset))
-		sparc64_ipi_error("resume", cpus_resumed, cpuset);
+	while (i-- > 0) {
+		CPUSET_CLEAR(cpus_resumed);
+		CPUSET_ASSIGN(cpuset, cpus_paused);
+		membar_Sync();
+		CPUSET_CLEAR(cpus_paused);
+
+		/* CPUs awake on cpus_paused clear */
+		if (!sparc64_ipi_wait(&cpus_resumed, cpuset))
+			return;
+	}
+	sparc64_ipi_error("resume", cpus_resumed, cpuset);
 }
 
 int
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.