Commit a5ea33f8 authored by Kenneth W. Chen's avatar Kenneth W. Chen Committed by David Mosberger

[PATCH] ia64: fix interpolation-bug in fsys_gettimeofday()

The order of reading ar.itc is incorrect with respect to all other
variables in fsys_gettimeofday.  All variables involved in time
interpolation need to be protected by the sequence lock xtime_lock for
consistency check.  However, the first time that fsys_gettimeofday()
takes a time stamp, it reads the count outside the seq lock leading to
the following possible time leap into the future scenario:

fsys_gettimeofday:
  read ar.itc

  .... <context switch> ....

  read_seqbegin
    read all other variables (last_nsec_offset, jiffies, xtime)
    do time interpolation - elapsed_cycles become a large negative
       number and converting it to nsec overflows and make it a
       large positive number
  read_seqretry success
  updates last_nsec_offset (which is several seconds into the future).

All subsequent gettimeofday() calls will be wrong as well because
monotonic property kicks in.  It only self-corrects once that future
time actually arrives.

This patch fixes the problem (and moves one instruction to make some room).
Signed-off-by: default avatarKen Chen <kenneth.w.chen@intel.com>
Signed-off-by: default avatarAsit Mallick <asit.k.mallick@intel.com>
Signed-off-by: default avatarDavid Mosberger <davidm@hpl.hp.com>
parent 6751b2da
...@@ -165,7 +165,6 @@ ENTRY(fsys_gettimeofday) ...@@ -165,7 +165,6 @@ ENTRY(fsys_gettimeofday)
add r9=TI_FLAGS+IA64_TASK_SIZE,r16 add r9=TI_FLAGS+IA64_TASK_SIZE,r16
addl r3=THIS_CPU(cpu_info),r0 addl r3=THIS_CPU(cpu_info),r0
mov.m r31=ar.itc // put time stamp into r31 (ITC) == now (35 cyc)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
movl r10=__per_cpu_offset movl r10=__per_cpu_offset
movl r2=sal_platform_features movl r2=sal_platform_features
...@@ -240,12 +239,13 @@ EX(.fail_efault, probe.w.fault r10, 3) // this must come _after_ NaT-check ...@@ -240,12 +239,13 @@ EX(.fail_efault, probe.w.fault r10, 3) // this must come _after_ NaT-check
;; ;;
ldf8 f8=[r21] // f8 now contains itm_next ldf8 f8=[r21] // f8 now contains itm_next
mov.m r31=ar.itc // put time stamp into r31 (ITC) == now
sub r28=r29, r28, 1 // r28 now contains "-(lost + 1)" sub r28=r29, r28, 1 // r28 now contains "-(lost + 1)"
tbit.nz p9, p10=r23, 0 // p9 <- is_odd(r23), p10 <- is_even(r23)
;; ;;
ld8 r2=[r19] // r2 = sec = xtime.tv_sec ld8 r2=[r19] // r2 = sec = xtime.tv_sec
ld8 r29=[r20] // r29 = nsec = xtime.tv_nsec ld8 r29=[r20] // r29 = nsec = xtime.tv_nsec
tbit.nz p9, p10=r23, 0 // p9 <- is_odd(r23), p10 <- is_even(r23)
setf.sig f6=r28 // f6 <- -(lost + 1) (6 cyc) setf.sig f6=r28 // f6 <- -(lost + 1) (6 cyc)
;; ;;
...@@ -260,7 +260,6 @@ EX(.fail_efault, probe.w.fault r10, 3) // this must come _after_ NaT-check ...@@ -260,7 +260,6 @@ EX(.fail_efault, probe.w.fault r10, 3) // this must come _after_ NaT-check
nop 0 nop 0
;; ;;
mov r31=ar.itc // re-read ITC in case we .retry (35 cyc)
xma.l f8=f11, f8, f12 // f8 (elapsed_cycles) <- (-1*last_tick + now) = (now - last_tick) xma.l f8=f11, f8, f12 // f8 (elapsed_cycles) <- (-1*last_tick + now) = (now - last_tick)
nop 0 nop 0
;; ;;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment