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>
This commit is contained in:
Michael Neuling 2014-06-11 15:59:28 +10:00 committed by Benjamin Herrenschmidt
parent 9b6a68d943
commit d4e58e5928
5 changed files with 18 additions and 1 deletions

View File

@ -56,6 +56,7 @@ _GLOBAL(__setup_cpu_power8)
li r0,0 li r0,0
mtspr SPRN_LPID,r0 mtspr SPRN_LPID,r0
mfspr r3,SPRN_LPCR mfspr r3,SPRN_LPCR
ori r3, r3, LPCR_PECEDH
bl __init_LPCR bl __init_LPCR
bl __init_HFSCR bl __init_HFSCR
bl __init_tlb_power8 bl __init_tlb_power8
@ -74,6 +75,7 @@ _GLOBAL(__restore_cpu_power8)
li r0,0 li r0,0
mtspr SPRN_LPID,r0 mtspr SPRN_LPID,r0
mfspr r3,SPRN_LPCR mfspr r3,SPRN_LPCR
ori r3, r3, LPCR_PECEDH
bl __init_LPCR bl __init_LPCR
bl __init_HFSCR bl __init_HFSCR
bl __init_tlb_power8 bl __init_tlb_power8

View File

@ -17,6 +17,7 @@ config PPC_POWERNV
select CPU_FREQ_GOV_USERSPACE select CPU_FREQ_GOV_USERSPACE
select CPU_FREQ_GOV_ONDEMAND select CPU_FREQ_GOV_ONDEMAND
select CPU_FREQ_GOV_CONSERVATIVE select CPU_FREQ_GOV_CONSERVATIVE
select PPC_DOORBELL
default y default y
config PPC_POWERNV_RTAS config PPC_POWERNV_RTAS

View File

@ -32,6 +32,7 @@
#include <asm/opal.h> #include <asm/opal.h>
#include <asm/runlatch.h> #include <asm/runlatch.h>
#include <asm/code-patching.h> #include <asm/code-patching.h>
#include <asm/dbell.h>
#include "powernv.h" #include "powernv.h"
@ -46,6 +47,11 @@ static void pnv_smp_setup_cpu(int cpu)
{ {
if (cpu != boot_cpuid) if (cpu != boot_cpuid)
xics_setup_cpu(); xics_setup_cpu();
#ifdef CONFIG_PPC_DOORBELL
if (cpu_has_feature(CPU_FTR_DBELL))
doorbell_setup_this_cpu();
#endif
} }
int pnv_smp_kick_cpu(int nr) int pnv_smp_kick_cpu(int nr)

View File

@ -21,6 +21,7 @@ config PPC_PSERIES
select HAVE_CONTEXT_TRACKING select HAVE_CONTEXT_TRACKING
select HOTPLUG_CPU if SMP select HOTPLUG_CPU if SMP
select ARCH_RANDOM select ARCH_RANDOM
select PPC_DOORBELL
default y default y
config PPC_SPLPAR config PPC_SPLPAR

View File

@ -26,6 +26,7 @@
#include <asm/errno.h> #include <asm/errno.h>
#include <asm/xics.h> #include <asm/xics.h>
#include <asm/kvm_ppc.h> #include <asm/kvm_ppc.h>
#include <asm/dbell.h>
struct icp_ipl { struct icp_ipl {
union { union {
@ -145,7 +146,13 @@ static unsigned int icp_native_get_irq(void)
static void icp_native_cause_ipi(int cpu, unsigned long data) static void icp_native_cause_ipi(int cpu, unsigned long data)
{ {
kvmppc_set_host_ipi(cpu, 1); kvmppc_set_host_ipi(cpu, 1);
icp_native_set_qirr(cpu, IPI_PRIORITY); #ifdef CONFIG_PPC_DOORBELL
if (cpu_has_feature(CPU_FTR_DBELL) &&
(cpumask_test_cpu(cpu, cpu_sibling_mask(smp_processor_id()))))
doorbell_cause_ipi(cpu, data);
else
#endif
icp_native_set_qirr(cpu, IPI_PRIORITY);
} }
void xics_wake_cpu(int cpu) void xics_wake_cpu(int cpu)