Re: [chrony-dev] Chrony freezing |
[ Thread Index |
Date Index
| More chrony.tuxfamily.org/chrony-dev Archives
]
On Thu, Nov 12, 2009 at 10:05:27AM -0800, Bill Unruh wrote:
> The problem is that when the UIE flag goes on in the driver for rtc, it
> immediately unblocks-- not waiting for the next seconds rollover, and opens
> opens the file for reading. Chrony assumes that at this unblocking the time is
> at the rollover.
To make sure I understand it correctly, setting UIE caused select to
immediately return that the descriptor is ready and then the read
returned immediately? Or did it block, or returned an error?
Was the second read added to improve accuracy?
I don't see any of that here, on a machine with HPET I guess.
What about making always two readings, i.e. don't disable the interrupt
after first one, wait for the interrupt again and use that? (see the patch)
--
Miroslav Lichvar
diff --git a/rtc_linux.c b/rtc_linux.c
index 1945d21..0009817 100644
--- a/rtc_linux.c
+++ b/rtc_linux.c
@@ -107,6 +107,8 @@ static int measurement_period = LOWEST_MEASUREMENT_PERIOD;
static int timeout_running = 0;
static SCH_TimeoutID timeout_id;
+static int skip_interrupts;
+
/* ================================================== */
/* Maximum number of samples held */
@@ -682,6 +684,7 @@ switch_interrupts(int onoff)
LOG(LOGS_ERR, LOGF_RtcLinux, "Could not start measurement : %s", strerror(errno));
return;
}
+ skip_interrupts = 1;
} else {
status = ioctl(fd, RTC_UIE_OFF, 0);
if (status < 0) {
@@ -873,8 +876,7 @@ read_from_device(void *any)
int error = 0;
status = read(fd, &data, sizeof(data));
- if (operating_mode == OM_NORMAL)
- status = read(fd, &data, sizeof(data));
+
if (status < 0) {
/* This looks like a bad error : the file descriptor was indicating it was
* ready to read but we couldn't read anything. Give up. */
@@ -891,6 +893,12 @@ read_from_device(void *any)
return;
}
+ if (skip_interrupts > 0) {
+ /* Wait for the next interrupt, this one may be bogus */
+ skip_interrupts--;
+ return;
+ }
+
if ((data & RTC_UIE) == RTC_UIE) {
/* Update interrupt detected */