=>From:   Joe <[EMAIL PROTECTED]>
 =>...
 =>it came back last night, while using X my mouse suddenly went
 =>bezerko again.

I had (still have, but very occasionally) a similar problem with 2.3.3
and some patches on an Intel N440BX (2xPIII,256MB) system.  I've tried
2.2.x kernels as well, and without my patch, I have *lots* of mouse
problems.

I tracked it down to problems with the kernel's service of
gettimeofday() calls: the routines in linux/arch/i386/kernel/time.c do
calculations to detect missed interrupts and (if your processor has a
TSC) to improve time resolution.  What would happen is that the missed
interrupts calculation and/or the TSC-elapsed-time calculation would
return a "negative" number which, since it was treated as unsigned,
would end up advancing the clock a lot (usually about 4294967000uS, or
a little more than an hour).  Then, on the next call to
gettimeofday(), the clock would bounce back to the correct time.
However, the damage was done: on the forward bounce, the X screensaver
would kick in, and on the backwards bounce, the mouse pointer
calculations would get screwed up, resulting in erratic pointer
behaviour, random bogus clicks, and so on.

I made a patch that prevents gettimeofday() from returning times
earlier than it returned previously, and also flags when the missed
interrupts or TSC calculations return a large forward adjustment; this
has solved most of my problems, but I still occasionally get wild time
warps where the clock starts racing forward.  I haven't been able to
track this down, because once it starts, cron jobs and the like get
started up (logrotate, find, makewhatis, etc) and the system dies a
quick, messy death.

Andrea Archangeli also made some patches that were designed to
eliminate missed interrupts (and detect them, too), but I still get
log messages about "lost ticks."

Anyway, you can detect time warps pretty easily with a program that
just calls gettimeofday() in a tight loop.  I'll append the one I used
when I was actively working on this problem.  I've pretty much given
up, though; Andrea's & my patches makes my machine mostly usable, and
I figure eventually one of the non-devel kernels will solve all the
problems the Right Way.

d.

                                                          * * * * *

#include <stdio.h>
#include <sys/types.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>

inline long
timeval_diff( const struct timeval *a, const struct timeval *b )
{
        if (a->tv_sec < b->tv_sec ||
                (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
                return -((b->tv_sec - a->tv_sec) * 1000000 + (b->tv_usec-a->tv_usec));
        else
                return (a->tv_sec - b->tv_sec) * 1000000 + (a->tv_usec - b->tv_usec);
}

int
main( int argc, char **argv )
{
        struct timeval   now;
        struct timeval   then;
        unsigned long    n_fwd = 0;
        long                     max_fwd = 0;
        unsigned long    n_back = 0;
        long                     max_back = 0;
        time_t                   last_log = time( 0 );

        gettimeofday( &then, 0 );
        
        for ( ; ; ) {
                long     delta;
                
                gettimeofday( &now, 0 );

                delta = timeval_diff( &now, &then );

                if (delta >= 0)
                        ++n_fwd;
                else
                        ++n_back;

                if (delta > max_fwd)
                        max_fwd = delta;
                else
                if (delta < max_back)
                        max_back = delta;

                if (now.tv_sec >= last_log + 1) {
                        printf( "%.19s FWD:%6ld/%6ld:BACK (%4ldus > delta > %4ldus)\n",
                                        ctime( &now.tv_sec ),
                                   n_fwd, n_back, max_back, max_fwd );
                        n_fwd = n_back = 0;
                        max_fwd = max_back = 0;
                        last_log = now.tv_sec;
                }

                then = now;
        }

        return 0;
}
-
Linux SMP list: FIRST see FAQ at http://www.irisa.fr/prive/mentre/smp-faq/
To Unsubscribe: send "unsubscribe linux-smp" to [EMAIL PROTECTED]

Reply via email to