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: Heiko Carstens <heiko.carstens@de.ibm.com> Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
0dab3e0e59
commit
249c543b97
|
@ -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)
|
||||||
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;
|
||||||
/*
|
/*
|
||||||
* 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)
|
||||||
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)
|
||||||
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,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# 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
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
__kernel_gettimeofday;
|
__kernel_gettimeofday;
|
||||||
__kernel_clock_gettime;
|
__kernel_clock_gettime;
|
||||||
__kernel_clock_getres;
|
__kernel_clock_getres;
|
||||||
|
__kernel_getcpu;
|
||||||
|
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# 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
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
__kernel_gettimeofday;
|
__kernel_gettimeofday;
|
||||||
__kernel_clock_gettime;
|
__kernel_clock_gettime;
|
||||||
__kernel_clock_getres;
|
__kernel_clock_getres;
|
||||||
|
__kernel_getcpu;
|
||||||
|
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue