提交 249c543b 编写于 作者: M Martin Schwidefsky

s390/vdso: optimize getcpu system call

Add the CPU number to the per-cpu vdso data page and add the
__kernel_getcpu function to the vdso object to retrieve the
CPU number in user space.
Suggested-by: NHeiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: NHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: NMartin Schwidefsky <schwidefsky@de.ibm.com>
上级 0dab3e0e
...@@ -38,6 +38,8 @@ struct vdso_data { ...@@ -38,6 +38,8 @@ struct vdso_data {
struct vdso_per_cpu_data { struct vdso_per_cpu_data {
__u64 ectg_timer_base; __u64 ectg_timer_base;
__u64 ectg_user_time; __u64 ectg_user_time;
__u32 cpu_nr;
__u32 node_id;
}; };
extern struct vdso_data *vdso_data; extern struct vdso_data *vdso_data;
......
...@@ -80,6 +80,8 @@ int main(void) ...@@ -80,6 +80,8 @@ int main(void)
OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift); OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift);
OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base); OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base);
OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time); OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time);
OFFSET(__VDSO_CPU_NR, vdso_per_cpu_data, cpu_nr);
OFFSET(__VDSO_NODE_ID, vdso_per_cpu_data, node_id);
BLANK(); BLANK();
/* constants used by the vdso */ /* constants used by the vdso */
DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME); DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME);
......
...@@ -80,7 +80,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data; ...@@ -80,7 +80,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data;
/* /*
* Setup vdso data page. * Setup vdso data page.
*/ */
static void vdso_init_data(struct vdso_data *vd) static void __init vdso_init_data(struct vdso_data *vd)
{ {
vd->ectg_available = test_facility(31); vd->ectg_available = test_facility(31);
} }
...@@ -93,6 +93,7 @@ static void vdso_init_data(struct vdso_data *vd) ...@@ -93,6 +93,7 @@ static void vdso_init_data(struct vdso_data *vd)
int vdso_alloc_per_cpu(struct lowcore *lowcore) int vdso_alloc_per_cpu(struct lowcore *lowcore)
{ {
unsigned long segment_table, page_table, page_frame; unsigned long segment_table, page_table, page_frame;
struct vdso_per_cpu_data *vd;
u32 *psal, *aste; u32 *psal, *aste;
int i; int i;
...@@ -107,6 +108,12 @@ int vdso_alloc_per_cpu(struct lowcore *lowcore) ...@@ -107,6 +108,12 @@ int vdso_alloc_per_cpu(struct lowcore *lowcore)
if (!segment_table || !page_table || !page_frame) if (!segment_table || !page_table || !page_frame)
goto out; goto out;
/* Initialize per-cpu vdso data page */
vd = (struct vdso_per_cpu_data *) page_frame;
vd->cpu_nr = lowcore->cpu_nr;
vd->node_id = cpu_to_node(vd->cpu_nr);
/* Set up access register mode page table */
clear_table((unsigned long *) segment_table, _SEGMENT_ENTRY_EMPTY, clear_table((unsigned long *) segment_table, _SEGMENT_ENTRY_EMPTY,
PAGE_SIZE << SEGMENT_ORDER); PAGE_SIZE << SEGMENT_ORDER);
clear_table((unsigned long *) page_table, _PAGE_INVALID, clear_table((unsigned long *) page_table, _PAGE_INVALID,
......
# List of files in the vdso, has to be asm only for now # List of files in the vdso, has to be asm only for now
obj-vdso32 = gettimeofday.o clock_getres.o clock_gettime.o note.o obj-vdso32 = gettimeofday.o clock_getres.o clock_gettime.o note.o getcpu.o
# Build rules # Build rules
......
/*
* Userland implementation of getcpu() for 32 bits processes in a
* s390 kernel for use in the vDSO
*
* Copyright IBM Corp. 2016
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <asm/vdso.h>
#include <asm/asm-offsets.h>
.text
.align 4
.globl __kernel_getcpu
.type __kernel_getcpu,@function
__kernel_getcpu:
.cfi_startproc
ear %r1,%a4
lhi %r4,1
sll %r4,24
sar %a4,%r4
la %r4,0
epsw %r0,0
sacf 512
l %r5,__VDSO_CPU_NR(%r4)
l %r4,__VDSO_NODE_ID(%r4)
tml %r0,0x4000
jo 1f
tml %r0,0x8000
jno 0f
sacf 256
j 1f
0: sacf 0
1: sar %a4,%r1
ltr %r2,%r2
jz 2f
st %r5,0(%r2)
2: ltr %r3,%r3
jz 3f
st %r4,0(%r3)
3: lhi %r2,0
br %r14
.cfi_endproc
.size __kernel_getcpu,.-__kernel_getcpu
...@@ -132,6 +132,7 @@ VERSION ...@@ -132,6 +132,7 @@ VERSION
__kernel_gettimeofday; __kernel_gettimeofday;
__kernel_clock_gettime; __kernel_clock_gettime;
__kernel_clock_getres; __kernel_clock_getres;
__kernel_getcpu;
local: *; local: *;
}; };
......
# List of files in the vdso, has to be asm only for now # List of files in the vdso, has to be asm only for now
obj-vdso64 = gettimeofday.o clock_getres.o clock_gettime.o note.o obj-vdso64 = gettimeofday.o clock_getres.o clock_gettime.o note.o getcpu.o
# Build rules # Build rules
......
/*
* Userland implementation of getcpu() for 64 bits processes in a
* s390 kernel for use in the vDSO
*
* Copyright IBM Corp. 2016
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <asm/vdso.h>
#include <asm/asm-offsets.h>
.text
.align 4
.globl __kernel_getcpu
.type __kernel_getcpu,@function
__kernel_getcpu:
.cfi_startproc
ear %r1,%a4
llilh %r4,0x0100
sar %a4,%r4
la %r4,0
epsw %r0,0
sacf 512
l %r5,__VDSO_CPU_NR(%r4)
l %r4,__VDSO_NODE_ID(%r4)
tml %r0,0x4000
jo 1f
tml %r0,0x8000
jno 0f
sacf 256
j 1f
0: sacf 0
1: sar %a4,%r1
ltgr %r2,%r2
jz 2f
st %r5,0(%r2)
2: ltgr %r3,%r3
jz 3f
st %r4,0(%r3)
3: lghi %r2,0
br %r14
.cfi_endproc
.size __kernel_getcpu,.-__kernel_getcpu
...@@ -132,6 +132,7 @@ VERSION ...@@ -132,6 +132,7 @@ VERSION
__kernel_gettimeofday; __kernel_gettimeofday;
__kernel_clock_gettime; __kernel_clock_gettime;
__kernel_clock_getres; __kernel_clock_getres;
__kernel_getcpu;
local: *; local: *;
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册