Module Name:    src
Committed By:   mrg
Date:           Mon Jan  4 04:21:35 UTC 2010

Modified Files:
        src/sys/arch/sparc/sparc: timer.c timer_sun4m.c timervar.h

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.26 src/sys/arch/sparc/sparc/timer.c
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/sparc/sparc/timer_sun4m.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/sparc/sparc/timervar.h

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

Modified files:

Index: src/sys/arch/sparc/sparc/timer.c
diff -u src/sys/arch/sparc/sparc/timer.c:1.25 src/sys/arch/sparc/sparc/timer.c:1.26
--- src/sys/arch/sparc/sparc/timer.c:1.25	Sun Jan  3 23:03:21 2010
+++ src/sys/arch/sparc/sparc/timer.c	Mon Jan  4 04:21:35 2010
@@ -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");
 

Index: src/sys/arch/sparc/sparc/timer_sun4m.c
diff -u src/sys/arch/sparc/sparc/timer_sun4m.c:1.19 src/sys/arch/sparc/sparc/timer_sun4m.c:1.20
--- src/sys/arch/sparc/sparc/timer_sun4m.c:1.19	Fri Jan  1 08:00:02 2010
+++ src/sys/arch/sparc/sparc/timer_sun4m.c	Mon Jan  4 04:21:35 2010
@@ -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);
 }

Index: src/sys/arch/sparc/sparc/timervar.h
diff -u src/sys/arch/sparc/sparc/timervar.h:1.8 src/sys/arch/sparc/sparc/timervar.h:1.9
--- src/sys/arch/sparc/sparc/timervar.h:1.8	Wed Jun  7 22:38:50 2006
+++ src/sys/arch/sparc/sparc/timervar.h	Mon Jan  4 04:21:35 2010
@@ -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);

Reply via email to