Index: linux-2.6.7/arch/ia64/kernel/time.c =================================================================== --- linux-2.6.7.orig/arch/ia64/kernel/time.c +++ linux-2.6.7/arch/ia64/kernel/time.c @@ -47,6 +47,31 @@ static struct time_interpolator itc_interpolator; +#define FASTCALL_DEBUG + +#ifdef FASTCALL_DEBUG +struct { + unsigned long off; + unsigned long x1; + unsigned long x2; + unsigned long x3; + unsigned long x4; + unsigned long x5; + unsigned long x6; + unsigned long x7; + unsigned long x8; + unsigned long x9; + unsigned long x10; +} fastcall_debug; +#endif + +#define COUNTER_DEBUG + +#ifdef COUNTER_DEBUG +unsigned count_gettod,count_gettime,count_einval,count_efault,count_success; +unsigned count_retry_cmpxchg,count_retry_seq,count_inc_sec; +#endif + int do_settimeofday (struct timespec *tv) { @@ -105,6 +130,18 @@ tv->tv_sec = sec; tv->tv_usec = usec; +#ifdef FASTCALL_DEBUG + if (fastcall_debug.off) + { + printk("fastcall_debug action=%lx old_cyc=%lu new_cyc=%lu cl_diff=%lu ns_diff=%lu ti_offs=%lu t.sec=%lu t.ns=%lu r.us=%lu\n", + fastcall_debug.x1,fastcall_debug.x2,fastcall_debug.x3,fastcall_debug.x4, + fastcall_debug.x5,fastcall_debug.x6,fastcall_debug.x7,fastcall_debug.x8, + fastcall_debug.x9); + printk("c-gettimeofday result sec=%lu nsec=%lu\n",sec,usec); + memset(&fastcall_debug,0,sizeof(fastcall_debug)); + } +#endif + } EXPORT_SYMBOL(do_gettimeofday); Index: linux-2.6.7/arch/ia64/kernel/fsys.S =================================================================== --- linux-2.6.7.orig/arch/ia64/kernel/fsys.S +++ linux-2.6.7/arch/ia64/kernel/fsys.S @@ -156,6 +156,9 @@ #define CLOCK_MONOTONIC 1 #define CLOCK_DIVIDE_BY_1000 0x4000 #define CLOCK_ADD_MONOTONIC 0x8000 + +// #define FASTCALL_DEBUG +#define COUNTER_DEBUG ENTRY(fsys_gettimeofday) .prologue .altrp b6 @@ -164,12 +167,20 @@ mov r26 = CLOCK_DIVIDE_BY_1000 tnat.nz p6,p0 = r33 // guard against NaT argument (p6) br.cond.spnt.few .fail_einval +#ifdef COUNTER_DEBUG + movl r10 = count_gettod;; + ld4 r3 =[r10] ;; + add r3 = 1,r3 ;; + st4 [r10]=r3;; +#endif ;; .gettime: // Register map // Not touched >=r32, r16=application, r10 etc. // Incoming r27 = pointer to address where to place result // r26 = flags determining how time is processed + // r10 = counter debugging + // r17 = pointer to fastcall debug info // r20 = initial sequence number // r21 = result seconds // r22 = result nanoseconds @@ -200,6 +211,16 @@ movl r30 = time_interpolator movl r31 = xtime_lock movl r21 = xtime +#ifdef FASTCALL_DEBUG + movl r17=fastcall_debug + ;; + ld8 r3=[r17] + ;; + cmp.ne p6, p0 = r0, r3 // If debug information has already been written +(p6) br.spnt.many fsys_fallback_syscall // then fall back instead of doing a fastcall + ;; + st8 [r17]=r17,8 +#endif ;; EX(.fail_efault, probe.w.fault r27, 3) EX(.fail_efault, probe.w.fault r28, 3) @@ -215,6 +236,11 @@ (p6) br.cond.spnt.many fsys_fallback_syscall mov pr = r3,0x3f00 // Set up predicate for timer operations ;; +#ifdef FASTCALL_DEBUG + ;; + st8 [r17] = r3,8 // timer control quad + ;; +#endif (p11) br.cond.spnt.many fsys_fallback_syscall // timer source is C function extr r23 = r3,16,16 // time_interpolator->shift extr r3 = r3,32,32 // time_interpolator->nsec_per_cyc @@ -260,6 +286,11 @@ getf.sig r2 = f8 and r20 = ~1,r20 // Make sequence even to force retry if odd ;; +#ifdef FASTCALL_DEBUG + st8 [r17] = r2,8 // nsec_diff + ;; + st8 [r17] = r3,8 // time_interpolator_offset +#endif shr.u r2 = r2,r23 mf ld4 r25 = [r31] // xtime_lock.sequence @@ -267,6 +298,13 @@ // End critical section. add r22 = r22,r2 // Add xtime.nsecs cmp4.ne p6,p0 = r25,r20 +#ifdef COUNTER_DEBUG + ;; +(p6) movl r10 = count_retry_seq ;; +(p6) ld4 r2 =[r10] ;; +(p6) add r2 = 1,r2 ;; +(p6) st4 [r10] = r2 ;; +#endif (p6) br.cond.dpnt.few .gettime // sequence number changed ? // Now r21=tv->tv_nsec and r22=tv->tv_sec movl r2 = 1000000000 @@ -280,8 +318,21 @@ (p14) setf.sig f8 = r20 (p6) sub r22 = r22,r2 (p6) add r21 = 1,r21 +#ifdef COUNTER_DEBUG + ;; +(p6) movl r10 = count_inc_sec ;; +(p6) ld4 r8 =[r10] ;; +(p6) add r8 = 1,r8 ;; +(p6) st4 [r10] = r8 ;; +#endif (p6) br.cond.dpnt.few .time_normalize ;; +#ifdef FASTCALL_DEBUG + st8 [r17] = r21,8 + ;; + st8 [r17] = r22,8 + ;; +#endif EX(.fail_efault, st8 [r27] = r21) // tv->tv_sec = seconds // Divided by 8. Now divide by 125 // The compiler is able to do that with a multiply @@ -292,15 +343,38 @@ ;; (p14) shr.u r22 = r2, 4 ;; +#ifdef FASTCALL_DEBUG + st8 [r17] = r22,8 + ;; +#endif +#ifdef COUNTER_DEBUG + movl r10 = count_success ;; + ld4 r2 =[r10] ;; + add r2 = 1,r2 ;; + st4 [r10]=r2;; +#endif + EX(.fail_efault, st8 [r28] = r22) mov r8 = r0 mov r10 = r0 FSYS_RETURN .fail_einval: +#ifdef COUNTER_DEBUG + movl r10 = count_einval ;; + ld4 r2 =[r10] ;; + add r2 = 1,r2 ;; + st4 [r10]=r2;; +#endif mov r8 = EINVAL mov r10 = -1 FSYS_RETURN .fail_efault: +#ifdef COUNTER_DEBUG + movl r10 = count_efault ;; + ld4 r2 =[r10] ;; + add r2 = 1,r2 ;; + st4 [r10]=r2;; +#endif mov r8 = EFAULT mov r10 = -1 FSYS_RETURN @@ -315,6 +389,13 @@ (p6) br.spnt.many fsys_fallback_syscall mov r27 = r33 shl r26 = r32,15 +#ifdef COUNTER_DEBUG + ;; + movl r10 = count_gettime ;; + ld4 r2 =[r10] ;; + add r2 = 1,r2 ;; + st4 [r10] = r2 ;; +#endif br.many .gettime END(fsys_clock_gettime)