Re: system time running out - again

Theo Veenker <[email protected]> Thu, 29 Dec 2005 22:49:43 +0100
Newsgroups gmane.linux.real-time.rtlinux.general
Message-ID <[email protected]>
Robson Sales (NETEL - Trana) wrote:
> Hi all!
> 
> Some time ago, people in this list notified a problem with the system 
> time (see in 
> http://www2.fsmlabs.com/pipermail/rtl/2005-February/030056.html).
> 
> After some messages, was identified three problems:
> 
> 1 - A minor error in the HZ variable in include/asm-i368/param.h (the HZ 
> variable was seted with 1000. However, the correct value is 100). This 
> correction was applied.
> 2 -  "the interrupts emulation was changed to trigger the linux side 
> unconditionally which was a hack to kick soft-irq with a low latency 
> independent from the   occurance of hardware interrupts, and secondly 
> the pending of irqs to linux unconditionally to allow sharing of irqs".  
> I can't check in the list if this problem was solved or not.
> 3  - The definition of CLOCK_TICK_RATE (include/asm-i386/timex.h) in AMD 
> Boxes seems to be 1189200 instead 1193100. The value of CLOCK_TICK_RATE 
> was changed to 1189200 for all CPU configs. This correction was applied.
> 
> I use the kernel 2.4.29 with the current rtl3.2-rc1 from cvs in my boxes.
> 
> For my surprise, I observe which the system time is running to fast. To 
> check this, I adjust the system time with the ntp server 200.20.186.75. 
> After 10 minutes, the error with this server is more than 2s. It is a 
> great offset in a small time. Following below the ntpdate output:
> 
> 26 Dec 16:53:13 ntpdate[7757]: adjust time server 200.20.186.75 offset 
> -8.465980 sec
> after 10min:
> 26 Dec 17:03:51 ntpdate[7764]: adjust time server 200.20.186.75 offset 
> -2.119054 sec
> 
> I checks this times with 2 Intel machines (a P4HT and a Celeron D 
> Boxes), with the same kernel configs (PIII processor in config, with 
> local APIC, IO APIC, Unsynced TSC support, APM and ACPI configured). The 
> results are alike.
> 
> After that, I recompile the kernel with the CLOCK_TICK_RATE seted with 
> 1193182 (the value is found in the timex.h from kernel 2.6 tree).
> The results are the same in the two boxes. See the ntpdate output:
> 
> 26 Dec 17:44:32 ntpdate[18590]: adjust time server 200.20.186.75 offset 
> -0.015455 sec
> after 10 min:
> 26 Dec 17:54:56 ntpdate[18726]: step time server 200.20.186.75 offset 
> -2.059203 sec.
> and after ~22min:
> 26 Dec 18:16:50 ntpdate[18749]: step time server 200.20.186.75 offset 
> -4.354148 sec
> 
> I check the error in the CLOCK_REALTIME and the CLOCK_GPOS in both 
> situations. The error is +/- 32ns in almost cases. Both the clocks is 
> run much faster than I expected.
> 
> Someone have any comments or same results with your configurations in 
> your boxes?
> 
> Comments may be very useful!

In our lab for a number of machines I managed to fix CLOCK_TICK_RATE
using the value produced by the attached module. To me the problem
seems to be that the value of CLOCK_TICK_RATE is so mobo specific
that it should really be algorithmically determined in the config
phase. But aparently there are other things that affect clock speed,
because I was unable to fix my home box by adjusting CLOCK_TICK_RATE.
For this system I didn't go to the bottom to find out a fix. I hope
to find this serious problem fixed for the 2.6 kernels.

Regards,
Theo

_______________________________________________
Rtl mailing list
[email protected]
http://hq.fsmlabs.com/mailman/listinfo/rtl
http:/www.rtlinux-gpl.org/
clktst.c (text/x-csrc, 1.8 KB)
/*
 * clktst.c
 *
 * Gets CLOCK_REALTIME and CLOCK_GPOS once every second and prints
 * the difference between the offsets between the two clock values.
 * If the clocks run at the same pace this difference should be zero
 * on average. 
 *
 * Also printed is value of CLOCK_TICK_RATE corrected using the
 * detected speed difference of CLOCK_REALTIME and CLOCK_GPOS. Of
 * course this only makes sence if the actual measurement interval is
 * correct.
 *
 * [email protected]
 *
 */

#include <rtl.h>
#include <posix/time.h>
#include <pthread.h>

static pthread_t mythread;

#define INTERVAL    1000000000

static void* testTask(void* arg)
{
    hrtime_t realtime, gpostime;
    hrtime_t offset, prevoffset;
    hrtime_t diff, tickrate;
    struct timespec rtres;
    struct timespec gpres;
    int n;

    pthread_make_periodic_np(pthread_self(), 
	clock_gethrtime(CLOCK_RTL_SCHED), INTERVAL);

    clock_getres(CLOCK_REALTIME, &rtres);
    clock_getres(CLOCK_GPOS, &gpres);

    rtl_printf("rt resolution: %ld ns\n", (long)rtres.tv_nsec);
    rtl_printf("gp resolution: %ld ns\n", (long)gpres.tv_nsec);

    realtime = clock_gethrtime(CLOCK_REALTIME);
    gpostime = clock_gethrtime(CLOCK_GPOS);

    prevoffset = offset = gpostime - realtime;
    diff = 0;

    for (n = 0; ; n++) {
    	pthread_wait_np();
    	realtime = clock_gethrtime(CLOCK_REALTIME);
    	gpostime = clock_gethrtime(CLOCK_GPOS);
    	offset = gpostime - realtime;
	diff = offset - prevoffset;
	prevoffset = offset;
	tickrate = ((INTERVAL - diff) * CLOCK_TICK_RATE) / INTERVAL;
	rtl_printf("%d: %lld    %lld\n", n, diff, tickrate);
    }

    return 0;
}

int init_module(void)
{
    pthread_create(&mythread, NULL, testTask, NULL);

    return 0;
}

void cleanup_module(void)
{
    pthread_cancel(mythread);
    pthread_join(mythread, NULL);
}