2 * Copyright 2006 Andi Kleen, SUSE Labs.
3 * Subject to the GNU Public License, v.2
5 * Fast user context implementation of getcpu()
8 #include <linux/kernel.h>
9 #include <linux/getcpu.h>
10 #include <linux/jiffies.h>
11 #include <linux/time.h>
12 #include <asm/vsyscall.h>
13 #include <asm/vgtod.h>
16 long __vdso_getcpu(unsigned *cpu
, unsigned *node
, struct getcpu_cache
*tcache
)
18 unsigned int dummy
, p
;
21 /* Fast cache - only recompute value once per jiffies and avoid
22 relatively costly rdtscp/cpuid otherwise.
23 This works because the scheduler usually keeps the process
24 on the same CPU and this syscall doesn't guarantee its
26 We do this here because otherwise user space would do it on
27 its own in a likely inferior way (no access to jiffies).
28 If you don't like it pass NULL. */
29 if (tcache
&& tcache
->blob
[0] == (j
= *vdso_jiffies
)) {
31 } else if (*vdso_vgetcpu_mode
== VGETCPU_RDTSCP
) {
32 /* Load per CPU data from RDTSCP */
33 rdtscp(dummy
, dummy
, p
);
35 /* Load per CPU data from GDT */
36 asm("lsl %1,%0" : "=r" (p
) : "r" (__PER_CPU_SEG
));
49 long getcpu(unsigned *cpu
, unsigned *node
, struct getcpu_cache
*tcache
)
50 __attribute__((weak
, alias("__vdso_getcpu")));