Commit 62cc67b9df273be18fcb09a071592dedf751c90a

Authored by Benjamin Herrenschmidt
1 parent e872e41b79

powerpc/pmac/smp: Properly NAP offlined CPU on G5

The current code soft-disables, and then goes to NAP mode which
turns interrupts on. That means that if an interrupt occurs, we
will hit the masked interrupt code path which isn't what we want,
as it will return with EE off, which will either get us out of
NAP mode, or fail to enter it (according to spec).

Instead, let's just rely on the fact that it is safe to take
decrementer interrupts on an offline CPU and leave interrupts
enabled. We can also get rid of the special case in asm for
power4_cpu_offline_powersave() and just use power4_idle().

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Showing 4 changed files with 15 additions and 28 deletions Side-by-side Diff

arch/powerpc/include/asm/machdep.h
... ... @@ -266,7 +266,6 @@
266 266  
267 267 extern void e500_idle(void);
268 268 extern void power4_idle(void);
269   -extern void power4_cpu_offline_powersave(void);
270 269 extern void ppc6xx_idle(void);
271 270 extern void book3e_idle(void);
272 271  
arch/powerpc/kernel/head_64.S
... ... @@ -536,6 +536,13 @@
536 536 add r13,r13,r4 /* for this processor. */
537 537 mtspr SPRN_SPRG_PACA,r13 /* Save vaddr of paca in an SPRG*/
538 538  
  539 + /* Mark interrupts soft and hard disabled (they might be enabled
  540 + * in the PACA when doing hotplug)
  541 + */
  542 + li r0,0
  543 + stb r0,PACASOFTIRQEN(r13)
  544 + stb r0,PACAHARDIRQEN(r13)
  545 +
539 546 /* Create a temp kernel stack for use before relocation is on. */
540 547 ld r1,PACAEMERGSP(r13)
541 548 subi r1,r1,STACK_FRAME_OVERHEAD
arch/powerpc/kernel/idle_power4.S
... ... @@ -52,26 +52,4 @@
52 52 mtmsrd r7
53 53 isync
54 54 b 1b
55   -
56   -_GLOBAL(power4_cpu_offline_powersave)
57   - /* Go to NAP now */
58   - mfmsr r7
59   - rldicl r0,r7,48,1
60   - rotldi r0,r0,16
61   - mtmsrd r0,1 /* hard-disable interrupts */
62   - li r0,1
63   - li r6,0
64   - stb r0,PACAHARDIRQEN(r13) /* we'll hard-enable shortly */
65   - stb r6,PACASOFTIRQEN(r13) /* soft-disable irqs */
66   -BEGIN_FTR_SECTION
67   - DSSALL
68   - sync
69   -END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
70   - ori r7,r7,MSR_EE
71   - oris r7,r7,MSR_POW@h
72   - sync
73   - isync
74   - mtmsrd r7
75   - isync
76   - blr
arch/powerpc/platforms/powermac/smp.c
... ... @@ -916,18 +916,20 @@
916 916 preempt_enable();
917 917  
918 918 /*
919   - * hard-disable interrupts for the non-NAP case, the NAP code
920   - * needs to re-enable interrupts (but soft-disables them)
  919 + * Re-enable interrupts. The NAP code needs to enable them
  920 + * anyways, do it now so we deal with the case where one already
  921 + * happened while soft-disabled.
  922 + * We shouldn't get any external interrupts, only decrementer, and the
  923 + * decrementer handler is safe for use on offline CPUs
921 924 */
922   - hard_irq_disable();
  925 + local_irq_enable();
923 926  
924 927 while (1) {
925 928 /* let's not take timer interrupts too often ... */
926 929 set_dec(0x7fffffff);
927 930  
928   - /* should always be true at this point */
929   - if (cpu_has_feature(CPU_FTR_CAN_NAP))
930   - power4_cpu_offline_powersave();
  931 + /* Enter NAP mode */
  932 + power4_idle();
931 933 }
932 934 }
933 935