RTC No Sync

From eLinux.org
Revision as of 14:54, 6 December 2006 by Wmat (Talk | contribs) (Legacy Content Conversion)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Introduction

One routine that potentially takes a long time during kernel startup is {{{get_cmos_time()}}}. This routine is used to read the value of the external real-time clock (RTC) when the kernel boots. Currently, this routine delays until the edge of the next second rollover, in order to ensure that the time value in the kernel is accurate with respect to the RTC.

However, this operation can take up to one full second to complete, and thus introduces up to 1 second of variability in the total bootup time.

The synchronization in this routine is easy to remove. It can be eliminated by removing the first two loops in the function {{{get_cmos_time()}}}, which is located in {{{include/asm-i386/mach-default/mach_time.h}}} for the i386 architecture. Similar routines are present in the kernel source tree for other architectures.

One tradeoff in making this modification is that the time stored by the Linux kernel is no longer completely synchronized (to the boundary of a second) with the time in the machine's realtime clock hardware. Some systems save the system time back out to the hardware clock on system shutdown. After numerous bootups and shutdowns, this lack of synchronization will cause the realtime clock value to drift from the correct time value.

Since the amount of un-synchronization is up to a second per boot cycle, this drift can be significant. However, for some embedded applications, this drift is unimportant. Also, in some situations the system time may be synchronized with an external source anyway, so the drift, if any, is corrected under normal circumstances soon after booting.

LKML discussion

The RTC synchronization was discussed on LKML in May (with even Linus himself commenting) That thread is available here.

Rationale

The RTC edge synchronization can take up to 1 second, and takes .5 seconds on average.

Downloads

Patch

  • [Patch for CELF version XXXXXX is *here*]
  • [Patch for 2.4.xx is *here*]
  • Patch for 2.6.7 (only for i386 architecture): rtc-nosynch-3.patch
  • Patch for 2.6.10 for PPC architecture: attachment:rtcnosync-ppc-2.6.10.patch

You might also want to check the Patch Archive

Utility programs

None

How To Use

Apply the patch to your Linux kernel. Then reconfigure your kernel so that "CONFIG_RTC_NO_SYNC_ON_READ" is enabled.

The option will be found under "General Setup", "Fast boot options" labeled as "No SYNC on read of Real Time Clock".

Sample Results

case 1

Tim Bird measured the effect of eliminating this synchronization on an HP xw4100 workstation. The machine had a Pentium 4 processor running at 3 GHz. With the synchronization, the time to perform get_cmos_time() varied from 150 milliseconds to 900 milliseconds. Without the synchronization, the time to perform get_cmos_time() was under 1 millisecond.

case 2

Richard Griffiths measured the effect of eliminating the synchronization on a 1GHZ Pentium III based desktop. With synchronization executing get_cmos_time() took from 200 milliseconds to a full second. Without the synchronization, the time to perform get_cmos_time() was under 1 millisecond.

case 3

Tim Bird measured the RTC read synchronization cost for a PowerPC board. The platform was a PPC440GP (ebony) board, using a Dallas Semiconductor DS1743 RTC.

The RTC read routine is in arch/ppc/syslib/todc_time.c:todc_get_rtc_time(). The loop to synchronize with the seconds edge is in arch/ppc/kernel/time.h:time_init().

I measured the time for synchronizing the clock edge several times:

  • 105 ms, 139 ms, 313 ms, 572 ms, 213 ms, 626 ms, 753 ms, 426 ms, 535 ms, 163 ms

Note that for PPC, the synchronization code is outside the RTC read routine, instead of inside the routine (as for i386).

Status

A patch was eventually submitted to LKML for consideration (in Nov, 2004). The thread is here

There was no response.

Future Work

Here is a list of things that could be worked on for this feature:

  • In an earlier thread on LKML, it was suggested that some background method of synchronizing the system clock and hardware clock could be used to avoid the clock drift problem.
  • one idea is: "you could check the cmos time in the timer interrupt during boot, and correct it there rather than busy-waiting"
  • Another person notes:
"There is hwclock that will read or write the CMOS clock, and it synchronizes. So if one wants to synchronize with the CMOS clock (rather than, say, with an external clock), and wants the better-than-1-sec accuracy, then that can be done in a boot script."
  • We need to check if hwclock uses get_cmos_time() to read the clock. If so, this method of synchronizing the clock edge after booting won't work (once the get_cmos_time synch is disabled.)