Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/sparc/sparc rework the timer interrupt usage on MP ...



details:   https://anonhg.NetBSD.org/src/rev/e39ff3b7d986
branches:  trunk
changeset: 750519:e39ff3b7d986
user:      mrg <mrg%NetBSD.org@localhost>
date:      Mon Jan 04 04:21:35 2010 +0000

description:
rework the timer interrupt usage on MP sun4m systems a little.  use
either schedintr() or schedintr_4m() and make sure we call hardclock()
and schedclock() appropriately.  the level10 interrupt isn't used much
for MP sun4m systems anymore..

now, besides crazy interrupts panics, sparc smp is functionaly again.

diffstat:

 sys/arch/sparc/sparc/timer.c       |  12 +++++++---
 sys/arch/sparc/sparc/timer_sun4m.c |  41 +++++++++++++++++++++++++++++++++----
 sys/arch/sparc/sparc/timervar.h    |   3 +-
 3 files changed, 46 insertions(+), 10 deletions(-)

diffs (169 lines):

diff -r 65965bd794ef -r e39ff3b7d986 sys/arch/sparc/sparc/timer.c
--- a/sys/arch/sparc/sparc/timer.c      Mon Jan 04 04:06:57 2010 +0000
+++ b/sys/arch/sparc/sparc/timer.c      Mon Jan 04 04:21:35 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: timer.c,v 1.25 2010/01/03 23:03:21 mrg Exp $ */
+/*     $NetBSD: timer.c,v 1.26 2010/01/04 04:21:35 mrg Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: timer.c,v 1.25 2010/01/03 23:03:21 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: timer.c,v 1.26 2010/01/04 04:21:35 mrg Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -153,6 +153,7 @@
 timerattach(volatile int *cntreg, volatile int *limreg)
 {
        u_int prec = 0, t0;
+       void    (*sched_intr_fn)(void *);
 
        /*
         * Calibrate delay() by tweaking the magic constant
@@ -192,11 +193,13 @@
        cntr.mask = (1 << (31-t0))-1;
        counter_timecounter.tc_frequency = 1000000 * (TMR_SHIFT - t0 + 1);
        
-       printf(": delay constant %d, frequency = %" PRIu64 " Hz\n", timerblurb, counter_timecounter.tc_frequency);
+       printf(": delay constant %d, frequency = %" PRIu64 " Hz\n",
+              timerblurb, counter_timecounter.tc_frequency);
 
 #if defined(SUN4) || defined(SUN4C)
        if (CPU_ISSUN4 || CPU_ISSUN4C) {
                timer_init = timer_init_4;
+               sched_intr_fn = schedintr;
                level10.ih_fun = clockintr_4;
                level14.ih_fun = statintr_4;
                cntr.limit = tmr_ustolim(tick);
@@ -205,6 +208,7 @@
 #if defined(SUN4M)
        if (CPU_ISSUN4M) {
                timer_init = timer_init_4m;
+               sched_intr_fn = schedintr_4m;
                level10.ih_fun = clockintr_4m;
                level14.ih_fun = statintr_4m;
                cntr.limit = tmr_ustolim4m(tick);
@@ -215,7 +219,7 @@
        intr_establish(14, 0, &level14, NULL, true);
 
        /* Establish a soft interrupt at a lower level for schedclock */
-       sched_cookie = sparc_softintr_establish(IPL_SCHED, schedintr, NULL);
+       sched_cookie = sparc_softintr_establish(IPL_SCHED, sched_intr_fn, NULL);
        if (sched_cookie == NULL)
                panic("timerattach: cannot establish schedintr");
 
diff -r 65965bd794ef -r e39ff3b7d986 sys/arch/sparc/sparc/timer_sun4m.c
--- a/sys/arch/sparc/sparc/timer_sun4m.c        Mon Jan 04 04:06:57 2010 +0000
+++ b/sys/arch/sparc/sparc/timer_sun4m.c        Mon Jan 04 04:21:35 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: timer_sun4m.c,v 1.19 2010/01/01 08:00:02 mrg Exp $     */
+/*     $NetBSD: timer_sun4m.c,v 1.20 2010/01/04 04:21:35 mrg Exp $     */
 
 /*
  * Copyright (c) 1992, 1993
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: timer_sun4m.c,v 1.19 2010/01/01 08:00:02 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: timer_sun4m.c,v 1.20 2010/01/04 04:21:35 mrg Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -95,6 +95,28 @@
        icr_si_bic(SINTR_T);
 }
 
+void
+schedintr_4m(void *v)
+{
+
+#ifdef MULTIPROCESSOR
+       /*
+        * We call hardclock() here so that we make sure it is called on
+        * all CPUs.  This function ends up being called on sun4m systems
+        * every tick, so we have avoid 
+        */
+       hardclock(v);
+
+       /*
+        * The factor 8 is only valid for stathz==100.
+        * See also clock.c
+        */
+       if ((++cpuinfo.ci_schedstate.spc_schedticks & 7) == 0 && schedhz != 0)
+#endif
+               schedclock(curlwp);
+}
+
+
 /*
  * Level 10 (clock) interrupts from system counter.
  */
@@ -109,6 +131,9 @@
         * a timer interrupt - if we call hardclock() at that point we'll
         * panic
         * so for now just bail when cold
+        *
+        * For MP, we defer calling hardclock() to the schedintr so
+        * that we call it on all cpus.
         */
        cpuinfo.ci_lev10.ev_count++;
        if (cold)
@@ -116,7 +141,9 @@
        /* read the limit register to clear the interrupt */
        *((volatile int *)&timerreg4m->t_limit);
        tickle_tc();
+#if !defined(MULTIPROCESSOR)
        hardclock((struct clockframe *)cap);
+#endif
        return (1);
 }
 
@@ -152,19 +179,23 @@
         * The factor 8 is only valid for stathz==100.
         * See also clock.c
         */
-       if (curlwp && (++cpuinfo.ci_schedstate.spc_schedticks & 7) == 0) {
+#if !defined(MULTIPROCESSOR)
+       if ((++cpuinfo.ci_schedstate.spc_schedticks & 7) == 0 && schedhz != 0) {
+#endif
                if (CLKF_LOPRI(frame, IPL_SCHED)) {
                        /* No need to schedule a soft interrupt */
                        spllowerschedclock();
-                       schedintr(cap);
+                       schedintr_4m(cap);
                } else {
                        /*
                         * We're interrupting a thread that may have the
-                        * scheduler lock; run schedintr() on this CPU later.
+                        * scheduler lock; run schedintr_4m() on this CPU later.
                         */
                        raise_ipi(&cpuinfo, IPL_SCHED); /* sched_cookie->pil */
                }
+#if !defined(MULTIPROCESSOR)
        }
+#endif
 
        return (1);
 }
diff -r 65965bd794ef -r e39ff3b7d986 sys/arch/sparc/sparc/timervar.h
--- a/sys/arch/sparc/sparc/timervar.h   Mon Jan 04 04:06:57 2010 +0000
+++ b/sys/arch/sparc/sparc/timervar.h   Mon Jan 04 04:21:35 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: timervar.h,v 1.8 2006/06/07 22:38:50 kardel Exp $      */
+/*     $NetBSD: timervar.h,v 1.9 2010/01/04 04:21:35 mrg Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -50,6 +50,7 @@
 #endif /* SUN4 || SUN4C */
 
 #if defined(SUN4M)
+void   schedintr_4m(void *);
 int    clockintr_4m(void *);
 int    statintr_4m(void *);
 void   timer_init_4m(void);



Home | Main Index | Thread Index | Old Index