diff options
author | Huacai Chen <chenhuacai@loongson.cn> | 2022-08-06 15:19:33 +0800 |
---|---|---|
committer | Huacai Chen <chenhuacai@loongson.cn> | 2022-08-12 13:10:11 +0800 |
commit | dce6098b22d58e5b646b1c67174c53f5a6a05605 (patch) | |
tree | 0658f8ef3b5efcf58a386100c02b1930bbd9eea0 /arch/loongarch/vdso | |
parent | 57fc7323a8e7c2e7c1d5795ab63cb3ffea3cfdfb (diff) |
LoongArch: Add vDSO syscall __vdso_getcpu()
We test 20 million times of getcpu(), the real syscall version take 25
seconds, while the vsyscall version take only 2.4 seconds.
Signed-off-by: Rui Wang <wangrui@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Diffstat (limited to 'arch/loongarch/vdso')
-rw-r--r-- | arch/loongarch/vdso/Makefile | 2 | ||||
-rw-r--r-- | arch/loongarch/vdso/vdso.lds.S | 1 | ||||
-rw-r--r-- | arch/loongarch/vdso/vgetcpu.c | 43 |
3 files changed, 45 insertions, 1 deletions
diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile index 92e404032257..d89e2ac75f7b 100644 --- a/arch/loongarch/vdso/Makefile +++ b/arch/loongarch/vdso/Makefile @@ -6,7 +6,7 @@ ARCH_REL_TYPE_ABS := R_LARCH_32|R_LARCH_64|R_LARCH_MARK_LA|R_LARCH_JUMP_SLOT include $(srctree)/lib/vdso/Makefile -obj-vdso-y := elf.o vgettimeofday.o sigreturn.o +obj-vdso-y := elf.o vgetcpu.o vgettimeofday.o sigreturn.o # Common compiler flags between ABIs. ccflags-vdso := \ diff --git a/arch/loongarch/vdso/vdso.lds.S b/arch/loongarch/vdso/vdso.lds.S index 955f02de4a2d..56ad855896de 100644 --- a/arch/loongarch/vdso/vdso.lds.S +++ b/arch/loongarch/vdso/vdso.lds.S @@ -58,6 +58,7 @@ VERSION { LINUX_5.10 { global: + __vdso_getcpu; __vdso_clock_getres; __vdso_clock_gettime; __vdso_gettimeofday; diff --git a/arch/loongarch/vdso/vgetcpu.c b/arch/loongarch/vdso/vgetcpu.c new file mode 100644 index 000000000000..43a0078e4418 --- /dev/null +++ b/arch/loongarch/vdso/vgetcpu.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Fast user context implementation of getcpu() + */ + +#include <asm/vdso.h> +#include <linux/getcpu.h> + +static __always_inline int read_cpu_id(void) +{ + int cpu_id; + + __asm__ __volatile__( + " rdtime.d $zero, %0\n" + : "=r" (cpu_id) + : + : "memory"); + + return cpu_id; +} + +static __always_inline const struct vdso_pcpu_data *get_pcpu_data(void) +{ + return (struct vdso_pcpu_data *)(get_vdso_base() - VDSO_DATA_SIZE); +} + +int __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused) +{ + int cpu_id; + const struct vdso_pcpu_data *data; + + cpu_id = read_cpu_id(); + + if (cpu) + *cpu = cpu_id; + + if (node) { + data = get_pcpu_data(); + *node = data[cpu_id].node; + } + + return 0; +} |