powerpc: Move checks in pseries_mach_cpu_die()
Vaidyanathan Srinivasan [Mon, 1 Mar 2010 02:58:16 +0000 (02:58 +0000)]
Rearrange condition checks for better code readability and
prevention of possible race conditions when
preferred_offline_state can potentially change during the
execution of pseries_mach_cpu_die().  The patch will make
pseries_mach_cpu_die() put cpu in one of the consistent states
and not hit the run over BUG()

Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Cc: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

arch/powerpc/platforms/pseries/hotplug-cpu.c

index 349e0af..fefb7f8 100644 (file)
@@ -140,25 +140,25 @@ static void pseries_mach_cpu_die(void)
                if (!get_lppaca()->shared_proc)
                        get_lppaca()->donate_dedicated_cpu = 0;
                get_lppaca()->idle = 0;
-       }
 
-       if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
-               unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
+               if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
+                       unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
 
-               /*
-                * Call to start_secondary_resume() will not return.
-                * Kernel stack will be reset and start_secondary()
-                * will be called to continue the online operation.
-                */
-               start_secondary_resume();
+                       /*
+                        * Call to start_secondary_resume() will not return.
+                        * Kernel stack will be reset and start_secondary()
+                        * will be called to continue the online operation.
+                        */
+                       start_secondary_resume();
+               }
+       }
 
-       } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
+       /* Requested state is CPU_STATE_OFFLINE at this point */
+       WARN_ON(get_preferred_offline_state(cpu) != CPU_STATE_OFFLINE);
 
-               set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
-               unregister_slb_shadow(hard_smp_processor_id(),
-                                       __pa(get_slb_shadow()));
-               rtas_stop_self();
-       }
+       set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
+       unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
+       rtas_stop_self();
 
        /* Should never get here... */
        BUG();