Add idle entry halt vs spin statistics counters machdep.cpu_idle_*,
authorMatthew Dillon <dillon@dragonflybsd.org>
Tue, 30 Dec 2003 03:19:04 +0000 (03:19 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Tue, 30 Dec 2003 03:19:04 +0000 (03:19 +0000)
Clear the reschedule flag in chooseproc() to prevent stale reschedule
requests from causing double-reschedules, and only disable HLT when a
system interrupt is pending (verses non critical process requests which
do not apply to the idle thread).

Problem focused in by: YONETANI Tomokazu <qhwt+dragonfly-kernel@les.ath.cx>

sys/i386/i386/machdep.c
sys/kern/kern_switch.c
sys/kern/lwkt_thread.c
sys/platform/pc32/i386/machdep.c
sys/sys/globaldata.h

index e6d1733..ea01a54 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     from: @(#)machdep.c     7.4 (Berkeley) 6/3/91
  * $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $
- * $DragonFly: src/sys/i386/i386/Attic/machdep.c,v 1.50 2003/12/28 06:11:30 dillon Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/machdep.c,v 1.51 2003/12/30 03:19:00 dillon Exp $
  */
 
 #include "use_apm.h"
@@ -867,8 +867,14 @@ cpu_halt(void)
  * cases lwkt_switch() sets TDF_IDLE_NOHLT.
  */
 static int     cpu_idle_hlt = 1;
+static int     cpu_idle_hltcnt;
+static int     cpu_idle_spincnt;
 SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW,
     &cpu_idle_hlt, 0, "Idle loop HLT enable");
+SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hltcnt, CTLFLAG_RW,
+    &cpu_idle_hltcnt, 0, "Idle loop entry halts");
+SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_spincnt, CTLFLAG_RW,
+    &cpu_idle_spincnt, 0, "Idle loop entry spins");
 
 void
 cpu_idle(void)
@@ -897,9 +903,12 @@ cpu_idle(void)
                        __asm __volatile("cli");
                        splz();
                        __asm __volatile("sti; hlt");
+                       ++cpu_idle_hltcnt;
                } else {
                        td->td_flags &= ~TDF_IDLE_NOHLT;
+                       splz();
                        __asm __volatile("sti");
+                       ++cpu_idle_spincnt;
                }
        }
 }
index ca2e098..dbe81a4 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/kern/kern_switch.c,v 1.3.2.1 2000/05/16 06:58:12 dillon Exp $
- * $DragonFly: src/sys/kern/Attic/kern_switch.c,v 1.15 2003/11/03 02:08:35 dillon Exp $
+ * $DragonFly: src/sys/kern/Attic/kern_switch.c,v 1.16 2003/12/30 03:19:02 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -138,6 +138,7 @@ chooseproc(struct proc *chkp)
        u_int32_t *which;
        u_int32_t pri;
 
+       clear_resched();
        if (rtqueuebits) {
                pri = bsfl(rtqueuebits);
                q = &rtqueues[pri];
index e875fbd..0dd10ba 100644 (file)
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/kern/lwkt_thread.c,v 1.46 2003/12/04 20:09:33 dillon Exp $
+ * $DragonFly: src/sys/kern/lwkt_thread.c,v 1.47 2003/12/30 03:19:02 dillon Exp $
  */
 
 /*
@@ -505,11 +505,11 @@ again:
 #endif
        } else {
            /*
-            * Nothing to run but we may still need the BGL to deal with
-            * pending interrupts, spin in idle if so.
+            * We have nothing to run but only let the idle loop halt
+            * the cpu if there are no pending interrupts.
             */
            ntd = &gd->gd_idlethread;
-           if (gd->gd_reqflags)
+           if (gd->gd_reqflags & RQF_IDLECHECK_MASK)
                ntd->td_flags |= TDF_IDLE_NOHLT;
        }
     }
index 83dce30..15ca4b5 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     from: @(#)machdep.c     7.4 (Berkeley) 6/3/91
  * $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $
- * $DragonFly: src/sys/platform/pc32/i386/machdep.c,v 1.50 2003/12/28 06:11:30 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/machdep.c,v 1.51 2003/12/30 03:19:00 dillon Exp $
  */
 
 #include "use_apm.h"
@@ -867,8 +867,14 @@ cpu_halt(void)
  * cases lwkt_switch() sets TDF_IDLE_NOHLT.
  */
 static int     cpu_idle_hlt = 1;
+static int     cpu_idle_hltcnt;
+static int     cpu_idle_spincnt;
 SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW,
     &cpu_idle_hlt, 0, "Idle loop HLT enable");
+SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hltcnt, CTLFLAG_RW,
+    &cpu_idle_hltcnt, 0, "Idle loop entry halts");
+SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_spincnt, CTLFLAG_RW,
+    &cpu_idle_spincnt, 0, "Idle loop entry spins");
 
 void
 cpu_idle(void)
@@ -897,9 +903,12 @@ cpu_idle(void)
                        __asm __volatile("cli");
                        splz();
                        __asm __volatile("sti; hlt");
+                       ++cpu_idle_hltcnt;
                } else {
                        td->td_flags &= ~TDF_IDLE_NOHLT;
+                       splz();
                        __asm __volatile("sti");
+                       ++cpu_idle_spincnt;
                }
        }
 }
index 3f47e59..6804425 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/include/globaldata.h,v 1.11.2.1 2000/05/16 06:58:10 dillon Exp $
- * $DragonFly: src/sys/sys/globaldata.h,v 1.21 2003/11/21 22:46:13 dillon Exp $
+ * $DragonFly: src/sys/sys/globaldata.h,v 1.22 2003/12/30 03:19:04 dillon Exp $
  */
 
 #ifndef _SYS_GLOBALDATA_H_
@@ -125,6 +125,7 @@ typedef struct globaldata *globaldata_t;
 #define RQF_AST_UPCALL (1 << RQB_AST_UPCALL)
 #define RQF_AST_MASK   (RQF_AST_OWEUPC|RQF_AST_SIGNAL|RQF_AST_RESCHED|\
                         RQF_AST_UPCALL)
+#define RQF_IDLECHECK_MASK     (RQF_IPIQ|RQF_INTPEND)
 
 #endif