mirror of https://gitee.com/openkylin/linux.git
powerpc: Copy only required pieces of the mm_context_t to the paca
Currently we copy the whole mm_context_t to the paca but only access a few bits of it. This is wasteful of space paca and also takes quite some time in the hot path of context switching. This patch pulls in only the required bits from the mm_context_t to the paca and on context switch, copies only those. Benchmarking this (On top of Anton's recent MSR context switching changes [1]) using processes and yield shows an improvement of almost 3% on POWER8: http://ozlabs.org/~anton/junkcode/context_switch2.c ./context_switch2 --test=yield --process 0 0 1. https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-October/135700.html Signed-off-by: Michael Neuling <mikey@neuling.org> [mpe: Rename paca fields to be mm_ctx_foo rather than context_foo] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
c395465da6
commit
2fc251a8dd
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
|
|
||||||
|
#include <linux/string.h>
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
#include <asm/lppaca.h>
|
#include <asm/lppaca.h>
|
||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
|
@ -132,7 +133,13 @@ struct paca_struct {
|
||||||
#endif /* CONFIG_PPC_BOOK3E */
|
#endif /* CONFIG_PPC_BOOK3E */
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_BOOK3S
|
#ifdef CONFIG_PPC_BOOK3S
|
||||||
mm_context_t context;
|
mm_context_id_t mm_ctx_id;
|
||||||
|
#ifdef CONFIG_PPC_MM_SLICES
|
||||||
|
u64 mm_ctx_low_slices_psize;
|
||||||
|
unsigned char mm_ctx_high_slices_psize[SLICE_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
u16 mm_ctx_sllp;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -199,7 +206,14 @@ struct paca_struct {
|
||||||
#ifdef CONFIG_PPC_BOOK3S
|
#ifdef CONFIG_PPC_BOOK3S
|
||||||
static inline void copy_mm_to_paca(mm_context_t *context)
|
static inline void copy_mm_to_paca(mm_context_t *context)
|
||||||
{
|
{
|
||||||
get_paca()->context = *context;
|
get_paca()->mm_ctx_id = context->id;
|
||||||
|
#ifdef CONFIG_PPC_MM_SLICES
|
||||||
|
get_paca()->mm_ctx_low_slices_psize = context->low_slices_psize;
|
||||||
|
memcpy(&get_paca()->mm_ctx_high_slices_psize,
|
||||||
|
&context->high_slices_psize, SLICE_ARRAY_SIZE);
|
||||||
|
#else
|
||||||
|
get_paca()->mm_ctx_sllp = context->sllp;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline void copy_mm_to_paca(mm_context_t *context){}
|
static inline void copy_mm_to_paca(mm_context_t *context){}
|
||||||
|
|
|
@ -186,12 +186,12 @@ int main(void)
|
||||||
DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
|
DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
|
||||||
DEFINE(PACAIRQHAPPENED, offsetof(struct paca_struct, irq_happened));
|
DEFINE(PACAIRQHAPPENED, offsetof(struct paca_struct, irq_happened));
|
||||||
#ifdef CONFIG_PPC_BOOK3S
|
#ifdef CONFIG_PPC_BOOK3S
|
||||||
DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
|
DEFINE(PACACONTEXTID, offsetof(struct paca_struct, mm_ctx_id));
|
||||||
#ifdef CONFIG_PPC_MM_SLICES
|
#ifdef CONFIG_PPC_MM_SLICES
|
||||||
DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
|
DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
|
||||||
context.low_slices_psize));
|
mm_ctx_low_slices_psize));
|
||||||
DEFINE(PACAHIGHSLICEPSIZE, offsetof(struct paca_struct,
|
DEFINE(PACAHIGHSLICEPSIZE, offsetof(struct paca_struct,
|
||||||
context.high_slices_psize));
|
mm_ctx_high_slices_psize));
|
||||||
DEFINE(MMUPSIZEDEFSIZE, sizeof(struct mmu_psize_def));
|
DEFINE(MMUPSIZEDEFSIZE, sizeof(struct mmu_psize_def));
|
||||||
#endif /* CONFIG_PPC_MM_SLICES */
|
#endif /* CONFIG_PPC_MM_SLICES */
|
||||||
#endif
|
#endif
|
||||||
|
@ -224,7 +224,7 @@ int main(void)
|
||||||
#ifdef CONFIG_PPC_MM_SLICES
|
#ifdef CONFIG_PPC_MM_SLICES
|
||||||
DEFINE(MMUPSIZESLLP, offsetof(struct mmu_psize_def, sllp));
|
DEFINE(MMUPSIZESLLP, offsetof(struct mmu_psize_def, sllp));
|
||||||
#else
|
#else
|
||||||
DEFINE(PACACONTEXTSLLP, offsetof(struct paca_struct, context.sllp));
|
DEFINE(PACACONTEXTSLLP, offsetof(struct paca_struct, mm_ctx_sllp));
|
||||||
#endif /* CONFIG_PPC_MM_SLICES */
|
#endif /* CONFIG_PPC_MM_SLICES */
|
||||||
DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
|
DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
|
||||||
DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
|
DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
|
||||||
|
|
|
@ -853,11 +853,11 @@ static unsigned int get_paca_psize(unsigned long addr)
|
||||||
unsigned long index, mask_index;
|
unsigned long index, mask_index;
|
||||||
|
|
||||||
if (addr < SLICE_LOW_TOP) {
|
if (addr < SLICE_LOW_TOP) {
|
||||||
lpsizes = get_paca()->context.low_slices_psize;
|
lpsizes = get_paca()->mm_ctx_low_slices_psize;
|
||||||
index = GET_LOW_SLICE_INDEX(addr);
|
index = GET_LOW_SLICE_INDEX(addr);
|
||||||
return (lpsizes >> (index * 4)) & 0xF;
|
return (lpsizes >> (index * 4)) & 0xF;
|
||||||
}
|
}
|
||||||
hpsizes = get_paca()->context.high_slices_psize;
|
hpsizes = get_paca()->mm_ctx_high_slices_psize;
|
||||||
index = GET_HIGH_SLICE_INDEX(addr);
|
index = GET_HIGH_SLICE_INDEX(addr);
|
||||||
mask_index = index & 0x1;
|
mask_index = index & 0x1;
|
||||||
return (hpsizes[index >> 1] >> (mask_index * 4)) & 0xF;
|
return (hpsizes[index >> 1] >> (mask_index * 4)) & 0xF;
|
||||||
|
|
Loading…
Reference in New Issue