powerpc/64: Drop explicit hwsync in context switch
authorNicholas Piggin <npiggin@gmail.com>
Thu, 8 Jun 2017 15:36:08 +0000 (01:36 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 15 Jun 2017 06:34:39 +0000 (16:34 +1000)
The sync (aka. hwsync, aka. heavyweight sync) in the context switch
code to prevent MMIO access being reordered from the point of view of
a single process if it gets migrated to a different CPU is not
required because there is an hwsync performed earlier in the context
switch path.

Comment this so it's clear enough if anything changes on the scheduler
or the powerpc sides. Remove the hwsync from _switch.

This improves context switch performance by 2-3% on POWER8.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/barrier.h
arch/powerpc/kernel/entry_64.S

index c0deafc212b8b9856bcb923a1bf07c439452d1e9..25d42bd3f1144c177110bb3235157d68b5b09583 100644 (file)
@@ -74,6 +74,11 @@ do {                                                                 \
        ___p1;                                                          \
 })
 
+/*
+ * This must resolve to hwsync on SMP for the context switch path.
+ * See _switch, and core scheduler context switch memory ordering
+ * comments.
+ */
 #define smp_mb__before_spinlock()   smp_mb()
 
 #include <asm-generic/barrier.h>
index 273a35926534c127918205826da6d555e067dd69..fb143859cc687d9c0fc9ebeb9500b539d0b36c18 100644 (file)
@@ -512,13 +512,24 @@ _GLOBAL(_switch)
        std     r23,_CCR(r1)
        std     r1,KSP(r3)      /* Set old stack pointer */
 
-#ifdef CONFIG_SMP
-       /* We need a sync somewhere here to make sure that if the
-        * previous task gets rescheduled on another CPU, it sees all
-        * stores it has performed on this one.
+       /*
+        * On SMP kernels, care must be taken because a task may be
+        * scheduled off CPUx and on to CPUy. Memory ordering must be
+        * considered.
+        *
+        * Cacheable stores on CPUx will be visible when the task is
+        * scheduled on CPUy by virtue of the core scheduler barriers
+        * (see "Notes on Program-Order guarantees on SMP systems." in
+        * kernel/sched/core.c).
+        *
+        * Uncacheable stores in the case of involuntary preemption must
+        * be taken care of. The smp_mb__before_spin_lock() in __schedule()
+        * is implemented as hwsync on powerpc, which orders MMIO too. So
+        * long as there is an hwsync in the context switch path, it will
+        * be executed on the source CPU after the task has performed
+        * all MMIO ops on that CPU, and on the destination CPU before the
+        * task performs any MMIO ops there.
         */
-       sync
-#endif /* CONFIG_SMP */
 
        /*
         * The kernel context switch path must contain a spin_lock,