summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormckay <mckay@FreeBSD.org>1997-04-06 13:25:48 +0000
committermckay <mckay@FreeBSD.org>1997-04-06 13:25:48 +0000
commit0c36a7b1a13680809688f6246cb00f4a909bd888 (patch)
tree4a5fca54fd849bdcc4a42d72f2a207f99d93faae /sys
parent19bb66de05329a40dbea96735219b22e1213583c (diff)
downloadFreeBSD-src-0c36a7b1a13680809688f6246cb00f4a909bd888.zip
FreeBSD-src-0c36a7b1a13680809688f6246cb00f4a909bd888.tar.gz
Prevent wedging of the stat clock because of missed interrupts.
This should cure the "alternate system clock has died!" problem. Discussed with: bde, joerg
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/tsc.c15
-rw-r--r--sys/amd64/isa/clock.c15
-rw-r--r--sys/i386/i386/tsc.c15
-rw-r--r--sys/i386/isa/clock.c15
-rw-r--r--sys/isa/atrtc.c15
5 files changed, 50 insertions, 25 deletions
diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c
index d7ffe6e..b942553 100644
--- a/sys/amd64/amd64/tsc.c
+++ b/sys/amd64/amd64/tsc.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.78 1997/03/05 00:54:00 gpalmer Exp $
+ * $Id: clock.c,v 1.79 1997/03/05 08:08:48 bde Exp $
*/
/*
@@ -311,15 +311,20 @@ release_timer2()
*
* The RTC chip requires that we read status register C (RTC_INTR)
* to acknowledge an interrupt, before it will generate the next one.
+ * Under high interrupt load, rtcintr() can be indefinitely delayed and
+ * the clock can tick immediately after the read from RTC_INTR. In this
+ * case, the mc146818A interrupt signal will not drop for long enough
+ * to register with the 8259 PIC. If an interrupt is missed, the stat
+ * clock will halt, considerably degrading system performance. This is
+ * why we use 'while' rather than a more straightforward 'if' below.
+ * Stat clock ticks can still be lost, causing minor loss of accuracy
+ * in the statistics, but the stat clock will no longer stop.
*/
static void
rtcintr(struct clockframe frame)
{
- u_char stat;
- stat = rtcin(RTC_INTR);
- if(stat & RTCIR_PERIOD) {
+ while (rtcin(RTC_INTR) & RTCIR_PERIOD)
statclock(&frame);
- }
}
#include "opt_ddb.h"
diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c
index d7ffe6e..b942553 100644
--- a/sys/amd64/isa/clock.c
+++ b/sys/amd64/isa/clock.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.78 1997/03/05 00:54:00 gpalmer Exp $
+ * $Id: clock.c,v 1.79 1997/03/05 08:08:48 bde Exp $
*/
/*
@@ -311,15 +311,20 @@ release_timer2()
*
* The RTC chip requires that we read status register C (RTC_INTR)
* to acknowledge an interrupt, before it will generate the next one.
+ * Under high interrupt load, rtcintr() can be indefinitely delayed and
+ * the clock can tick immediately after the read from RTC_INTR. In this
+ * case, the mc146818A interrupt signal will not drop for long enough
+ * to register with the 8259 PIC. If an interrupt is missed, the stat
+ * clock will halt, considerably degrading system performance. This is
+ * why we use 'while' rather than a more straightforward 'if' below.
+ * Stat clock ticks can still be lost, causing minor loss of accuracy
+ * in the statistics, but the stat clock will no longer stop.
*/
static void
rtcintr(struct clockframe frame)
{
- u_char stat;
- stat = rtcin(RTC_INTR);
- if(stat & RTCIR_PERIOD) {
+ while (rtcin(RTC_INTR) & RTCIR_PERIOD)
statclock(&frame);
- }
}
#include "opt_ddb.h"
diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c
index d7ffe6e..b942553 100644
--- a/sys/i386/i386/tsc.c
+++ b/sys/i386/i386/tsc.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.78 1997/03/05 00:54:00 gpalmer Exp $
+ * $Id: clock.c,v 1.79 1997/03/05 08:08:48 bde Exp $
*/
/*
@@ -311,15 +311,20 @@ release_timer2()
*
* The RTC chip requires that we read status register C (RTC_INTR)
* to acknowledge an interrupt, before it will generate the next one.
+ * Under high interrupt load, rtcintr() can be indefinitely delayed and
+ * the clock can tick immediately after the read from RTC_INTR. In this
+ * case, the mc146818A interrupt signal will not drop for long enough
+ * to register with the 8259 PIC. If an interrupt is missed, the stat
+ * clock will halt, considerably degrading system performance. This is
+ * why we use 'while' rather than a more straightforward 'if' below.
+ * Stat clock ticks can still be lost, causing minor loss of accuracy
+ * in the statistics, but the stat clock will no longer stop.
*/
static void
rtcintr(struct clockframe frame)
{
- u_char stat;
- stat = rtcin(RTC_INTR);
- if(stat & RTCIR_PERIOD) {
+ while (rtcin(RTC_INTR) & RTCIR_PERIOD)
statclock(&frame);
- }
}
#include "opt_ddb.h"
diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c
index d7ffe6e..b942553 100644
--- a/sys/i386/isa/clock.c
+++ b/sys/i386/isa/clock.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.78 1997/03/05 00:54:00 gpalmer Exp $
+ * $Id: clock.c,v 1.79 1997/03/05 08:08:48 bde Exp $
*/
/*
@@ -311,15 +311,20 @@ release_timer2()
*
* The RTC chip requires that we read status register C (RTC_INTR)
* to acknowledge an interrupt, before it will generate the next one.
+ * Under high interrupt load, rtcintr() can be indefinitely delayed and
+ * the clock can tick immediately after the read from RTC_INTR. In this
+ * case, the mc146818A interrupt signal will not drop for long enough
+ * to register with the 8259 PIC. If an interrupt is missed, the stat
+ * clock will halt, considerably degrading system performance. This is
+ * why we use 'while' rather than a more straightforward 'if' below.
+ * Stat clock ticks can still be lost, causing minor loss of accuracy
+ * in the statistics, but the stat clock will no longer stop.
*/
static void
rtcintr(struct clockframe frame)
{
- u_char stat;
- stat = rtcin(RTC_INTR);
- if(stat & RTCIR_PERIOD) {
+ while (rtcin(RTC_INTR) & RTCIR_PERIOD)
statclock(&frame);
- }
}
#include "opt_ddb.h"
diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c
index d7ffe6e..b942553 100644
--- a/sys/isa/atrtc.c
+++ b/sys/isa/atrtc.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.78 1997/03/05 00:54:00 gpalmer Exp $
+ * $Id: clock.c,v 1.79 1997/03/05 08:08:48 bde Exp $
*/
/*
@@ -311,15 +311,20 @@ release_timer2()
*
* The RTC chip requires that we read status register C (RTC_INTR)
* to acknowledge an interrupt, before it will generate the next one.
+ * Under high interrupt load, rtcintr() can be indefinitely delayed and
+ * the clock can tick immediately after the read from RTC_INTR. In this
+ * case, the mc146818A interrupt signal will not drop for long enough
+ * to register with the 8259 PIC. If an interrupt is missed, the stat
+ * clock will halt, considerably degrading system performance. This is
+ * why we use 'while' rather than a more straightforward 'if' below.
+ * Stat clock ticks can still be lost, causing minor loss of accuracy
+ * in the statistics, but the stat clock will no longer stop.
*/
static void
rtcintr(struct clockframe frame)
{
- u_char stat;
- stat = rtcin(RTC_INTR);
- if(stat & RTCIR_PERIOD) {
+ while (rtcin(RTC_INTR) & RTCIR_PERIOD)
statclock(&frame);
- }
}
#include "opt_ddb.h"
OpenPOWER on IntegriCloud