]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
powerpc: Copy only required pieces of the mm_context_t to the paca
authorMichael Neuling <mikey@neuling.org>
Thu, 10 Dec 2015 22:34:42 +0000 (09:34 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Sun, 27 Dec 2015 08:12:14 +0000 (19:12 +1100)
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>
arch/powerpc/include/asm/paca.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/mm/hash_utils_64.c

index 1cc6e08289076997e522a1d75cf260bffdaa362d..ef78c288c712cedb623c6bbc2683dc4d6fee6d3e 100644 (file)
@@ -16,6 +16,7 @@
 
 #ifdef CONFIG_PPC64
 
+#include <linux/string.h>
 #include <asm/types.h>
 #include <asm/lppaca.h>
 #include <asm/mmu.h>
@@ -132,7 +133,13 @@ struct paca_struct {
 #endif /* CONFIG_PPC_BOOK3E */
 
 #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
 
        /*
@@ -199,7 +206,14 @@ struct paca_struct {
 #ifdef CONFIG_PPC_BOOK3S
 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
 static inline void copy_mm_to_paca(mm_context_t *context){}
index 9db7be292bf367c240b278785a4aabf4df8cf3ee..07cebc3514f34337b734153b02f836e28c402d4f 100644 (file)
@@ -186,12 +186,12 @@ int main(void)
        DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
        DEFINE(PACAIRQHAPPENED, offsetof(struct paca_struct, irq_happened));
 #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
        DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
-                                           context.low_slices_psize));
+                                           mm_ctx_low_slices_psize));
        DEFINE(PACAHIGHSLICEPSIZE, offsetof(struct paca_struct,
-                                           context.high_slices_psize));
+                                           mm_ctx_high_slices_psize));
        DEFINE(MMUPSIZEDEFSIZE, sizeof(struct mmu_psize_def));
 #endif /* CONFIG_PPC_MM_SLICES */
 #endif
@@ -224,7 +224,7 @@ int main(void)
 #ifdef CONFIG_PPC_MM_SLICES
        DEFINE(MMUPSIZESLLP, offsetof(struct mmu_psize_def, sllp));
 #else
-       DEFINE(PACACONTEXTSLLP, offsetof(struct paca_struct, context.sllp));
+       DEFINE(PACACONTEXTSLLP, offsetof(struct paca_struct, mm_ctx_sllp));
 #endif /* CONFIG_PPC_MM_SLICES */
        DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
        DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
index 03279eac09571b944a5265f4d06778d1826ecd89..db744576d730ee8ebeca9f9e9c061fd5678c81f7 100644 (file)
@@ -853,11 +853,11 @@ static unsigned int get_paca_psize(unsigned long addr)
        unsigned long index, mask_index;
 
        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);
                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);
        mask_index = index & 0x1;
        return (hpsizes[index >> 1] >> (mask_index * 4)) & 0xF;