Merge branch 'x86-vdso-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 26 May 2011 19:19:31 +0000 (12:19 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 26 May 2011 19:19:31 +0000 (12:19 -0700)
* 'x86-vdso-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: vdso: Remove unused variable
  x86-64: Optimize vDSO time()
  x86-64: Add time to vDSO
  x86-64: Turn off -pg and turn on -foptimize-sibling-calls for vDSO
  x86-64: Move vread_tsc into a new file with sensible options
  x86-64: Vclock_gettime(CLOCK_MONOTONIC) can't ever see nsec < 0
  x86-64: Don't generate cmov in vread_tsc
  x86-64: Remove unnecessary barrier in vread_tsc
  x86-64: Clean up vdso/kernel shared variables

1  2 
arch/x86/kernel/vmlinux.lds.S
arch/x86/kernel/vsyscall_64.c

@@@ -161,6 -161,12 +161,12 @@@ SECTION
  
  #define VVIRT_OFFSET (VSYSCALL_ADDR - __vsyscall_0)
  #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
+ #define EMIT_VVAR(x, offset) .vsyscall_var_ ## x      \
+       ADDR(.vsyscall_0) + offset                      \
+       : AT(VLOAD(.vsyscall_var_ ## x)) {              \
+               *(.vsyscall_var_ ## x)                  \
+       }                                               \
+       x = VVIRT(.vsyscall_var_ ## x);
  
        . = ALIGN(4096);
        __vsyscall_0 = .;
                *(.vsyscall_fn)
        }
  
-       . = ALIGN(L1_CACHE_BYTES);
-       .vsyscall_gtod_data : AT(VLOAD(.vsyscall_gtod_data)) {
-               *(.vsyscall_gtod_data)
-       }
-       vsyscall_gtod_data = VVIRT(.vsyscall_gtod_data);
-       .vsyscall_clock : AT(VLOAD(.vsyscall_clock)) {
-               *(.vsyscall_clock)
-       }
-       vsyscall_clock = VVIRT(.vsyscall_clock);
        .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) {
                *(.vsyscall_1)
        }
                *(.vsyscall_2)
        }
  
-       .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) {
-               *(.vgetcpu_mode)
-       }
-       vgetcpu_mode = VVIRT(.vgetcpu_mode);
-       . = ALIGN(L1_CACHE_BYTES);
-       .jiffies : AT(VLOAD(.jiffies)) {
-               *(.jiffies)
-       }
-       jiffies = VVIRT(.jiffies);
        .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) {
                *(.vsyscall_3)
        }
  
+ #define __VVAR_KERNEL_LDS
+ #include <asm/vvar.h>
+ #undef __VVAR_KERNEL_LDS
        . = __vsyscall_0 + PAGE_SIZE;
  
  #undef VSYSCALL_ADDR
  #undef VLOAD
  #undef VVIRT_OFFSET
  #undef VVIRT
+ #undef EMIT_VVAR
  
  #endif /* CONFIG_X86_64 */
  
        }
  
  #if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)
 -      PERCPU(INTERNODE_CACHE_BYTES, PAGE_SIZE)
 +      PERCPU_SECTION(INTERNODE_CACHE_BYTES)
  #endif
  
        . = ALIGN(PAGE_SIZE);
                __attribute__ ((unused, __section__(".vsyscall_" #nr))) notrace
  #define __syscall_clobber "r11","cx","memory"
  
- /*
-  * vsyscall_gtod_data contains data that is :
-  * - readonly from vsyscalls
-  * - written by timer interrupt or systcl (/proc/sys/kernel/vsyscall64)
-  * Try to keep this structure as small as possible to avoid cache line ping pongs
-  */
- int __vgetcpu_mode __section_vgetcpu_mode;
- struct vsyscall_gtod_data __vsyscall_gtod_data __section_vsyscall_gtod_data =
+ DEFINE_VVAR(int, vgetcpu_mode);
+ DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data) =
  {
 -      .lock = SEQLOCK_UNLOCKED,
 +      .lock = __SEQLOCK_UNLOCKED(__vsyscall_gtod_data.lock),
        .sysctl_enabled = 1,
  };
  
@@@ -97,7 -90,7 +90,7 @@@ void update_vsyscall(struct timespec *w
   */
  static __always_inline void do_get_tz(struct timezone * tz)
  {
-       *tz = __vsyscall_gtod_data.sys_tz;
+       *tz = VVAR(vsyscall_gtod_data).sys_tz;
  }
  
  static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz)
@@@ -126,23 -119,24 +119,24 @@@ static __always_inline void do_vgettime
        unsigned long mult, shift, nsec;
        cycle_t (*vread)(void);
        do {
-               seq = read_seqbegin(&__vsyscall_gtod_data.lock);
+               seq = read_seqbegin(&VVAR(vsyscall_gtod_data).lock);
  
-               vread = __vsyscall_gtod_data.clock.vread;
-               if (unlikely(!__vsyscall_gtod_data.sysctl_enabled || !vread)) {
+               vread = VVAR(vsyscall_gtod_data).clock.vread;
+               if (unlikely(!VVAR(vsyscall_gtod_data).sysctl_enabled ||
+                            !vread)) {
                        gettimeofday(tv,NULL);
                        return;
                }
  
                now = vread();
-               base = __vsyscall_gtod_data.clock.cycle_last;
-               mask = __vsyscall_gtod_data.clock.mask;
-               mult = __vsyscall_gtod_data.clock.mult;
-               shift = __vsyscall_gtod_data.clock.shift;
+               base = VVAR(vsyscall_gtod_data).clock.cycle_last;
+               mask = VVAR(vsyscall_gtod_data).clock.mask;
+               mult = VVAR(vsyscall_gtod_data).clock.mult;
+               shift = VVAR(vsyscall_gtod_data).clock.shift;
  
-               tv->tv_sec = __vsyscall_gtod_data.wall_time_sec;
-               nsec = __vsyscall_gtod_data.wall_time_nsec;
-       } while (read_seqretry(&__vsyscall_gtod_data.lock, seq));
+               tv->tv_sec = VVAR(vsyscall_gtod_data).wall_time_sec;
+               nsec = VVAR(vsyscall_gtod_data).wall_time_nsec;
+       } while (read_seqretry(&VVAR(vsyscall_gtod_data).lock, seq));
  
        /* calculate interval: */
        cycle_delta = (now - base) & mask;
@@@ -171,15 -165,15 +165,15 @@@ time_t __vsyscall(1) vtime(time_t *t
  {
        unsigned seq;
        time_t result;
-       if (unlikely(!__vsyscall_gtod_data.sysctl_enabled))
+       if (unlikely(!VVAR(vsyscall_gtod_data).sysctl_enabled))
                return time_syscall(t);
  
        do {
-               seq = read_seqbegin(&__vsyscall_gtod_data.lock);
+               seq = read_seqbegin(&VVAR(vsyscall_gtod_data).lock);
  
-               result = __vsyscall_gtod_data.wall_time_sec;
+               result = VVAR(vsyscall_gtod_data).wall_time_sec;
  
-       } while (read_seqretry(&__vsyscall_gtod_data.lock, seq));
+       } while (read_seqretry(&VVAR(vsyscall_gtod_data).lock, seq));
  
        if (t)
                *t = result;
@@@ -208,9 -202,9 +202,9 @@@ vgetcpu(unsigned *cpu, unsigned *node, 
           We do this here because otherwise user space would do it on
           its own in a likely inferior way (no access to jiffies).
           If you don't like it pass NULL. */
-       if (tcache && tcache->blob[0] == (j = __jiffies)) {
+       if (tcache && tcache->blob[0] == (j = VVAR(jiffies))) {
                p = tcache->blob[1];
-       } else if (__vgetcpu_mode == VGETCPU_RDTSCP) {
+       } else if (VVAR(vgetcpu_mode) == VGETCPU_RDTSCP) {
                /* Load per CPU data from RDTSCP */
                native_read_tscp(&p);
        } else {