Message ID | 1367223460-4931-1-git-send-email-imunsie@au1.ibm.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
On Mon, 2013-04-29 at 18:17 +1000, Ian Munsie wrote: > This is not an issue with other interrupts that can wake a thread > (external, decrementer) as they are level sensitive and will continue to > be asserted by the hardware. However, it might be worth experimenting setting the corresponding bits in the PACA as well, as this will diminish the latency of processing them. IE. local_irq_enable() will see the bit, generate an interrupt frame and call the handler which is a faster path than re-enabling MSR:EE and then taking an external interrupt. Cheers, Ben.
On Mon, Apr 29, 2013 at 06:17:40PM +1000, Ian Munsie wrote: > From: Ian Munsie <imunsie@au1.ibm.com> > > If a doorbell IPI comes in while a thread is in nap power saving, the > doorbell interrupt won't be replayed by the hardware since it is edge > sensitive. Currently we are not replaying these interrupts in software, > which can cause threads to miss IPIs that come in during power saving > and eventually will result in an RCU warning from rcu_sched that it has > detected a stalled CPU. > > This patch fixes the issue by testing if a doorbell caused the thread to > come out of power saving and sets the corresponding bit in the paca to > indicate a doorbell happened, which will then be handled by the existing > interrupt replay code. > > This is not an issue with other interrupts that can wake a thread > (external, decrementer) as they are level sensitive and will continue to > be asserted by the hardware. > > Signed-off-by: Ian Munsie <imunsie@au1.ibm.com> <formletter> This is not the correct way to submit patches for inclusion in the stable kernel tree. Please read Documentation/stable_kernel_rules.txt for how to do this properly. </formletter>
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 5c6fbe2..dd8a071 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -549,14 +549,17 @@ #define SRR1_ISI_NOPT 0x40000000 /* ISI: Not found in hash */ #define SRR1_ISI_N_OR_G 0x10000000 /* ISI: Access is no-exec or G */ #define SRR1_ISI_PROT 0x08000000 /* ISI: Other protection fault */ -#define SRR1_WAKEMASK 0x00380000 /* reason for wakeup */ +#define SRR1_WAKEMASK 0x003c0000 /* reason for wakeup [42:45] */ +#define SRR1_WAKESHIFT 18 #define SRR1_WAKESYSERR 0x00300000 /* System error */ #define SRR1_WAKEEE 0x00200000 /* External interrupt */ #define SRR1_WAKEMT 0x00280000 /* mtctrl */ #define SRR1_WAKEHMI 0x00280000 /* Hypervisor maintenance */ #define SRR1_WAKEDEC 0x00180000 /* Decrementer interrupt */ +#define SRR1_WAKEDBELLP 0x00140000 /* Privileged Doorbell */ #define SRR1_WAKETHERM 0x00100000 /* Thermal management interrupt */ #define SRR1_WAKERESET 0x00100000 /* System reset */ +#define SRR1_WAKEDBELLH 0x000c0000 /* Hypervisor Doorbell */ #define SRR1_WAKESTATE 0x00030000 /* Powersave exit mask [46:47] */ #define SRR1_WS_DEEPEST 0x00030000 /* Some resources not maintained, * may not be recoverable */ diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S index e11863f..c80bb4b 100644 --- a/arch/powerpc/kernel/idle_power7.S +++ b/arch/powerpc/kernel/idle_power7.S @@ -108,9 +108,7 @@ _GLOBAL(power7_wakeup_loss) ld r5,_NIP(r1) addi r1,r1,INT_FRAME_SIZE mtcr r3 - mtspr SPRN_SRR1,r4 - mtspr SPRN_SRR0,r5 - rfid + b power7_wakeup_common _GLOBAL(power7_wakeup_noloss) lbz r0,PACA_NAPSTATELOST(r13) @@ -120,6 +118,23 @@ _GLOBAL(power7_wakeup_noloss) ld r4,_MSR(r1) ld r5,_NIP(r1) addi r1,r1,INT_FRAME_SIZE - mtspr SPRN_SRR1,r4 + /* Fall through */ + +power7_wakeup_common: +BEGIN_FTR_SECTION + mfspr r3,SPRN_SRR1 + extrdi r3,r3,4,42 /* Extract SRR1_WAKEMASK */ + cmpwi r3,SRR1_WAKEDBELLH >> SRR1_WAKESHIFT + beq 1f + cmpwi r3,SRR1_WAKEDBELLP >> SRR1_WAKESHIFT + bne 2f + +1: /* Woken by a doorbell, set doorbell happened in paca */ + lbz r3,PACAIRQHAPPENED(r13) + ori r3,r3,PACA_IRQ_DBELL + stb r3,PACAIRQHAPPENED(r13) +END_FTR_SECTION_IFSET(CPU_FTR_DBELL) + +2: mtspr SPRN_SRR1,r4 mtspr SPRN_SRR0,r5 rfid