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);