Hello Klaus and Jim,

 On Saturday, February 2, 2008 at 14:02:23 +0100, Klaus Ethgen wrote:

> /dev/rtc doesn't allow user access to update interrupts
>  - using busy wait instead

Understood: This is printed when ioctl(RTC_UIE_ON) fails, because the
kernel driver thinks that the interrupt is not available. Adjtimex 1.23
has a fallback for this case: it calls busy_wait() in the intent to sync
on UIP fall (instead of interrupt).

Problem: the implementation of busy_wait() doesn't work in this case.
Busy_wait() depends on using_dev_rtc=0, it depends on cmos_fd=/dev/port,
and perhaps on other minor things. While Klaus is trying to use /dev/rtc
default access mode, where using_dev_rtc=1 and cmos_fd=/dev/rtc.

> lseek(3, 112, SEEK_SET)                 = -1 ESPIPE (Illegal seek)
> write(3, "\212", 1)                     = -1 EBADF (Bad file descriptor)

Of course, seeking direct access to IO ports 0x70 and 0x71 via
a /dev/rtc device not done for this can only miserably fail.


I see 3 possible solutions:

 -1) Rewrite busy_wait() to make it work in whatever using_dev_rtc mode,
decouple cmos_fd for rtc and port, and fix some other minor probs.

 -2) When ioctl(RTC_UIE_ON) fails, close /dev/rtc, reset using_dev_rtc
to 0, call again cmos_init(), and repeat the whole cmos_read_time() as
if we were in --directisa mode all the time.

 -3) Rename busy_wait() to busywait_uip_fall() only for --directisa
mode. Write a new busywait_second_change() function only for /dev/rtc
mode, looping around ioctl(RTC_RD_TIME) until the time changes.


Solution (1) is easy, quick, and dirty. I'm not really comfortable with
mixing clean device access thru a driver, and dirty hack direct IO (even
if it's not really directly, but thru /dev/port).

Solution (2) is full direct IO. Dirty, but at least self-coherant.

Solution (3) is clean: full /dev/rtc, self-coherant. The sync accuracy
is rather good, only very little less than --directisa. Some low tens of
microseconds delay on recent kernels since 2.6.16 (I measured the tick
only 15 to 39 µs late on my dead old and slow machine). However the
method steps on a bug of all previous kernels until 2.6.15, bug
introducing a random error between 8000 and 18000 microseconds (ouch!).
In the same no-interrupt fallback case, hwclock 2.31 uses method (3).
And it has a --nointerrupt option to force this mode even outside of the
fallback case.


Before looking closely at the code, I'd seem to tend to prefer
method (3). What's your opinion James?


Alain.


Reply via email to