Port-sparc64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Pausing/resuming CPU's in DDB



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/
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


Home | Main Index | Thread Index | Old Index