diff options
| author | Michael Neuling <mikey@neuling.org> | 2014-06-11 01:59:28 -0400 |
|---|---|---|
| committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-06-11 03:05:12 -0400 |
| commit | d4e58e5928f8c6c49228451dd03e0714cbab299a (patch) | |
| tree | 34add9a16b4dbe03da04191f51588f3f6a6bdbf9 | |
| parent | 9b6a68d94333cf19d4ec0f2aaf9f9eb68866630e (diff) | |
powerpc/powernv: Enable POWER8 doorbell IPIs
This patch enables POWER8 doorbell IPIs on powernv.
Since doorbells can only IPI within a core, we test to see when we can use
doorbells and if not we fall back to XICS. This also enables hypervisor
doorbells to wakeup us up from nap/sleep via the LPCR PECEDH bit.
Based on tests by Anton, the best case IPI latency between two threads dropped
from 894ns to 512ns.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
| -rw-r--r-- | arch/powerpc/kernel/cpu_setup_power.S | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/Kconfig | 1 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/smp.c | 6 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/Kconfig | 1 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/xics/icp-native.c | 9 |
5 files changed, 18 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S index 1557e7c2c7e1..46733535cc0b 100644 --- a/arch/powerpc/kernel/cpu_setup_power.S +++ b/arch/powerpc/kernel/cpu_setup_power.S | |||
| @@ -56,6 +56,7 @@ _GLOBAL(__setup_cpu_power8) | |||
| 56 | li r0,0 | 56 | li r0,0 |
| 57 | mtspr SPRN_LPID,r0 | 57 | mtspr SPRN_LPID,r0 |
| 58 | mfspr r3,SPRN_LPCR | 58 | mfspr r3,SPRN_LPCR |
| 59 | ori r3, r3, LPCR_PECEDH | ||
| 59 | bl __init_LPCR | 60 | bl __init_LPCR |
| 60 | bl __init_HFSCR | 61 | bl __init_HFSCR |
| 61 | bl __init_tlb_power8 | 62 | bl __init_tlb_power8 |
| @@ -74,6 +75,7 @@ _GLOBAL(__restore_cpu_power8) | |||
| 74 | li r0,0 | 75 | li r0,0 |
| 75 | mtspr SPRN_LPID,r0 | 76 | mtspr SPRN_LPID,r0 |
| 76 | mfspr r3,SPRN_LPCR | 77 | mfspr r3,SPRN_LPCR |
| 78 | ori r3, r3, LPCR_PECEDH | ||
| 77 | bl __init_LPCR | 79 | bl __init_LPCR |
| 78 | bl __init_HFSCR | 80 | bl __init_HFSCR |
| 79 | bl __init_tlb_power8 | 81 | bl __init_tlb_power8 |
diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig index c252ee95bddf..45a8ed0585cd 100644 --- a/arch/powerpc/platforms/powernv/Kconfig +++ b/arch/powerpc/platforms/powernv/Kconfig | |||
| @@ -17,6 +17,7 @@ config PPC_POWERNV | |||
| 17 | select CPU_FREQ_GOV_USERSPACE | 17 | select CPU_FREQ_GOV_USERSPACE |
| 18 | select CPU_FREQ_GOV_ONDEMAND | 18 | select CPU_FREQ_GOV_ONDEMAND |
| 19 | select CPU_FREQ_GOV_CONSERVATIVE | 19 | select CPU_FREQ_GOV_CONSERVATIVE |
| 20 | select PPC_DOORBELL | ||
| 20 | default y | 21 | default y |
| 21 | 22 | ||
| 22 | config PPC_POWERNV_RTAS | 23 | config PPC_POWERNV_RTAS |
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 0062a43a2e0d..5fcfcf44e3a9 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <asm/opal.h> | 32 | #include <asm/opal.h> |
| 33 | #include <asm/runlatch.h> | 33 | #include <asm/runlatch.h> |
| 34 | #include <asm/code-patching.h> | 34 | #include <asm/code-patching.h> |
| 35 | #include <asm/dbell.h> | ||
| 35 | 36 | ||
| 36 | #include "powernv.h" | 37 | #include "powernv.h" |
| 37 | 38 | ||
| @@ -46,6 +47,11 @@ static void pnv_smp_setup_cpu(int cpu) | |||
| 46 | { | 47 | { |
| 47 | if (cpu != boot_cpuid) | 48 | if (cpu != boot_cpuid) |
| 48 | xics_setup_cpu(); | 49 | xics_setup_cpu(); |
| 50 | |||
| 51 | #ifdef CONFIG_PPC_DOORBELL | ||
| 52 | if (cpu_has_feature(CPU_FTR_DBELL)) | ||
| 53 | doorbell_setup_this_cpu(); | ||
| 54 | #endif | ||
| 49 | } | 55 | } |
| 50 | 56 | ||
| 51 | int pnv_smp_kick_cpu(int nr) | 57 | int pnv_smp_kick_cpu(int nr) |
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 2cb8b776c84a..756b482f819a 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig | |||
| @@ -21,6 +21,7 @@ config PPC_PSERIES | |||
| 21 | select HAVE_CONTEXT_TRACKING | 21 | select HAVE_CONTEXT_TRACKING |
| 22 | select HOTPLUG_CPU if SMP | 22 | select HOTPLUG_CPU if SMP |
| 23 | select ARCH_RANDOM | 23 | select ARCH_RANDOM |
| 24 | select PPC_DOORBELL | ||
| 24 | default y | 25 | default y |
| 25 | 26 | ||
| 26 | config PPC_SPLPAR | 27 | config PPC_SPLPAR |
diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c index 9dee47071af8..de8d9483bbe8 100644 --- a/arch/powerpc/sysdev/xics/icp-native.c +++ b/arch/powerpc/sysdev/xics/icp-native.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <asm/errno.h> | 26 | #include <asm/errno.h> |
| 27 | #include <asm/xics.h> | 27 | #include <asm/xics.h> |
| 28 | #include <asm/kvm_ppc.h> | 28 | #include <asm/kvm_ppc.h> |
| 29 | #include <asm/dbell.h> | ||
| 29 | 30 | ||
| 30 | struct icp_ipl { | 31 | struct icp_ipl { |
| 31 | union { | 32 | union { |
| @@ -145,7 +146,13 @@ static unsigned int icp_native_get_irq(void) | |||
| 145 | static void icp_native_cause_ipi(int cpu, unsigned long data) | 146 | static void icp_native_cause_ipi(int cpu, unsigned long data) |
| 146 | { | 147 | { |
| 147 | kvmppc_set_host_ipi(cpu, 1); | 148 | kvmppc_set_host_ipi(cpu, 1); |
| 148 | icp_native_set_qirr(cpu, IPI_PRIORITY); | 149 | #ifdef CONFIG_PPC_DOORBELL |
| 150 | if (cpu_has_feature(CPU_FTR_DBELL) && | ||
| 151 | (cpumask_test_cpu(cpu, cpu_sibling_mask(smp_processor_id())))) | ||
| 152 | doorbell_cause_ipi(cpu, data); | ||
| 153 | else | ||
| 154 | #endif | ||
| 155 | icp_native_set_qirr(cpu, IPI_PRIORITY); | ||
| 149 | } | 156 | } |
| 150 | 157 | ||
| 151 | void xics_wake_cpu(int cpu) | 158 | void xics_wake_cpu(int cpu) |
