diff options
author | tmm <tmm@FreeBSD.org> | 2003-05-29 17:49:21 +0000 |
---|---|---|
committer | tmm <tmm@FreeBSD.org> | 2003-05-29 17:49:21 +0000 |
commit | e330758d56bad341f3b6004687dae494c845e9f0 (patch) | |
tree | cfaf16cfa37c0aa9dd63a002ddd5c024618102eb | |
parent | cccb8a341841afbb6950f77adfed8b5bf81138ae (diff) | |
download | FreeBSD-src-e330758d56bad341f3b6004687dae494c845e9f0.zip FreeBSD-src-e330758d56bad341f3b6004687dae494c845e9f0.tar.gz |
Completely disable interrupts (not just raise %pil) when calculating the
value to be written into tick_compare in tick_hardclock(). While
we were taking care that the value to be written was at least TICK_GRACE
ticks in the future, a vector interrupt could happen between calculating
the value and writing it. If it took longer than TICK_GRACE to complete
(which is doubtful for a single device-triggered vector interrupt, but
quite likely for some IPIs), the value written would be in the past
and tick interrupts (which drive hardclock and statclock) would stop
until %tick wraps around, which takes a long time.
Also, increase TICK_GRACE from 1000 to 10000 for good measure.
Reported by: kris
Reviewed by: jake
Approved by: re (scottl)
-rw-r--r-- | sys/sparc64/sparc64/tick.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/sys/sparc64/sparc64/tick.c b/sys/sparc64/sparc64/tick.c index 46c3b59..6189653 100644 --- a/sys/sparc64/sparc64/tick.c +++ b/sys/sparc64/sparc64/tick.c @@ -53,7 +53,7 @@ int tick_missed; /* statistics */ -#define TICK_GRACE 1000 +#define TICK_GRACE 10000 void cpu_initclocks(void) @@ -80,6 +80,7 @@ tick_hardclock(struct clockframe *cf) { int missed; u_long next; + register_t i; tick_process(cf); /* @@ -91,14 +92,14 @@ tick_hardclock(struct clockframe *cf) */ missed = 0; next = rd(asr23) + tick_increment; - critical_enter(); + i = intr_disable(); while (next < rd(tick) + TICK_GRACE) { next += tick_increment; missed++; } - atomic_add_int(&tick_missed, missed); wr(asr23, next, 0); - critical_exit(); + intr_restore(i); + atomic_add_int(&tick_missed, missed); for (; missed > 0; missed--) tick_process(cf); } |