locking/core: Introduce cpu_relax_yield()
authorChristian Borntraeger <borntraeger@de.ibm.com>
Tue, 25 Oct 2016 09:03:11 +0000 (11:03 +0200)
committerIngo Molnar <mingo@kernel.org>
Wed, 16 Nov 2016 09:15:09 +0000 (10:15 +0100)
For spinning loops people do often use barrier() or cpu_relax().
For most architectures cpu_relax and barrier are the same, but on
some architectures cpu_relax can add some latency.
For example on power,sparc64 and arc, cpu_relax can shift the CPU
towards other hardware threads in an SMT environment.
On s390 cpu_relax does even more, it uses an hypercall to the
hypervisor to give up the timeslice.
In contrast to the SMT yielding this can result in larger latencies.
In some places this latency is unwanted, so another variant
"cpu_relax_lowlatency" was introduced. Before this is used in more
and more places, lets revert the logic and provide a cpu_relax_yield
that can be called in places where yielding is more important than
latency. By default this is the same as cpu_relax on all architectures.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Noam Camus <noamc@ezchip.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: virtualization@lists.linux-foundation.org
Cc: xen-devel@lists.xenproject.org
Link: http://lkml.kernel.org/r/1477386195-32736-2-git-send-email-borntraeger@de.ibm.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
33 files changed:
arch/alpha/include/asm/processor.h
arch/arc/include/asm/processor.h
arch/arm/include/asm/processor.h
arch/arm64/include/asm/processor.h
arch/avr32/include/asm/processor.h
arch/blackfin/include/asm/processor.h
arch/c6x/include/asm/processor.h
arch/cris/include/asm/processor.h
arch/frv/include/asm/processor.h
arch/h8300/include/asm/processor.h
arch/hexagon/include/asm/processor.h
arch/ia64/include/asm/processor.h
arch/m32r/include/asm/processor.h
arch/m68k/include/asm/processor.h
arch/metag/include/asm/processor.h
arch/microblaze/include/asm/processor.h
arch/mips/include/asm/processor.h
arch/mn10300/include/asm/processor.h
arch/nios2/include/asm/processor.h
arch/openrisc/include/asm/processor.h
arch/parisc/include/asm/processor.h
arch/powerpc/include/asm/processor.h
arch/s390/include/asm/processor.h
arch/s390/kernel/processor.c
arch/score/include/asm/processor.h
arch/sh/include/asm/processor.h
arch/sparc/include/asm/processor_32.h
arch/sparc/include/asm/processor_64.h
arch/tile/include/asm/processor.h
arch/unicore32/include/asm/processor.h
arch/x86/include/asm/processor.h
arch/x86/um/asm/processor.h
arch/xtensa/include/asm/processor.h

index 43a7559c448b4e419af2e7fddf954c4fc283ac97..0556fda7bc6df97d4c52cab31cb90bf8bd429675 100644 (file)
@@ -58,6 +58,7 @@ unsigned long get_wchan(struct task_struct *p);
   ((tsk) == current ? rdusp() : task_thread_info(tsk)->pcb.usp)
 
 #define cpu_relax()    barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 #define ARCH_HAS_PREFETCH
index 16b630fbeb6acfb09fc59d20c4f965a0bb3e59aa..6c158d576355b3bb06321e26c8c53603cc68a916 100644 (file)
@@ -60,6 +60,7 @@ struct task_struct;
 #ifndef CONFIG_EZNPS_MTM_EXT
 
 #define cpu_relax()            barrier()
+#define cpu_relax_yield()      cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 #else
@@ -67,6 +68,7 @@ struct task_struct;
 #define cpu_relax()     \
        __asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
 
+#define cpu_relax_yield()      cpu_relax()
 #define cpu_relax_lowlatency() barrier()
 
 #endif
index 8a1e8e995daec45278d088faa3ada7f1d6dbb957..db660e0b4bd3ba6e7aa764f1fb89598c8e6c22c5 100644 (file)
@@ -82,6 +82,7 @@ unsigned long get_wchan(struct task_struct *p);
 #define cpu_relax()                    barrier()
 #endif
 
+#define cpu_relax_yield()                    cpu_relax()
 #define cpu_relax_lowlatency()                cpu_relax()
 
 #define task_pt_regs(p) \
index 60e34824e18c96b06c02930961c8ce51b82a90e2..3f9b0e54dae3fc4d6f92ac74a117d0b8fa98d2d7 100644 (file)
@@ -149,6 +149,7 @@ static inline void cpu_relax(void)
        asm volatile("yield" ::: "memory");
 }
 
+#define cpu_relax_yield()                     cpu_relax()
 #define cpu_relax_lowlatency()                cpu_relax()
 
 /* Thread switching */
index 941593c7d9f3c12d841283e3330d2ea7fbef4cdb..e412e8b68a7daf40b8fa6f1e3e2fe970b08e1ad5 100644 (file)
@@ -92,6 +92,7 @@ extern struct avr32_cpuinfo boot_cpu_data;
 #define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
 
 #define cpu_relax()            barrier()
+#define cpu_relax_yield()      cpu_relax()
 #define cpu_relax_lowlatency()        cpu_relax()
 #define cpu_sync_pipeline()    asm volatile("sub pc, -2" : : : "memory")
 
index 0c265aba94add376d8546e716703e0e653d1c6b1..8b8704a44b7798e89bb9e0649678e2c24f27ecc5 100644 (file)
@@ -92,6 +92,7 @@ unsigned long get_wchan(struct task_struct *p);
 #define        KSTK_ESP(tsk)   ((tsk) == current ? rdusp() : (tsk)->thread.usp)
 
 #define cpu_relax()            smp_mb()
+#define cpu_relax_yield()      cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 /* Get the Silicon Revision of the chip */
index f2ef31be2f8b0c1f196c1352eace1511590a2360..914d7308bdb439e767a9cdc6f749c9b23dad70bd 100644 (file)
@@ -121,6 +121,7 @@ extern unsigned long get_wchan(struct task_struct *p);
 #define KSTK_ESP(task) (task_pt_regs(task)->sp)
 
 #define cpu_relax()            do { } while (0)
+#define cpu_relax_yield()             cpu_relax()
 #define cpu_relax_lowlatency()        cpu_relax()
 
 extern const struct seq_operations cpuinfo_op;
index 862126b58116b03e3e1c7793883999c3ab8236a0..01dd52ecac84805478a41ad698eb407d7212e08f 100644 (file)
@@ -63,6 +63,7 @@ static inline void release_thread(struct task_struct *dead_task)
 #define init_stack      (init_thread_union.stack)
 
 #define cpu_relax()     barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 void default_idle(void);
index 73f0a79ad8e691d6106e636a33bb006a688bd97c..4d00d65f5e5ed1b13dd7a79eddcade302ac2e6c0 100644 (file)
@@ -107,6 +107,7 @@ unsigned long get_wchan(struct task_struct *p);
 #define        KSTK_ESP(tsk)   ((tsk)->thread.frame0->sp)
 
 #define cpu_relax() barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 /* data cache prefetch */
index 111df7397ac7bd4ee0aa979bb3b0c5f7438722b4..683a061c3cb5a299c37c7588c427c34adfd0f504 100644 (file)
@@ -127,6 +127,7 @@ unsigned long get_wchan(struct task_struct *p);
 #define        KSTK_ESP(tsk)   ((tsk) == current ? rdusp() : (tsk)->thread.usp)
 
 #define cpu_relax()    barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 #define HARD_RESET_NOW() ({            \
index d8501137c8d022db81fb14676fc40f40ede0d8fa..1558ddb9e5d7eadb401a04c44176b13b2a59a89d 100644 (file)
@@ -56,6 +56,7 @@ struct thread_struct {
 }
 
 #define cpu_relax() __vmyield()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 /*
index ce53c50d0ba443f6e3f925b0c1e0e17e5d385ebe..4654b71dc8db3b68095922d1973e182c68164d1a 100644 (file)
@@ -547,6 +547,7 @@ ia64_eoi (void)
 }
 
 #define cpu_relax()    ia64_hint(ia64_hint_pause)
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 static inline int
index 9f8fd9bef70f58d8c8a2368d777d59e3f9d1dd6d..b2620370320d296d7c7bbd5f8db19740f24fc5cb 100644 (file)
@@ -133,6 +133,7 @@ unsigned long get_wchan(struct task_struct *p);
 #define KSTK_ESP(tsk)  ((tsk)->thread.sp)
 
 #define cpu_relax()    barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 #endif /* _ASM_M32R_PROCESSOR_H */
index c84a2183b3f0abb6110a2c17840d90baac59eb29..13e07ae6786d5a48ce01549e78bc198095210238 100644 (file)
@@ -156,6 +156,7 @@ unsigned long get_wchan(struct task_struct *p);
 #define task_pt_regs(tsk)      ((struct pt_regs *) ((tsk)->thread.esp0))
 
 #define cpu_relax()    barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 #endif
index a0333ebcac35212845db8afc7ce837a7e016075b..61d6e2722893ea41fc8de58d847daa6775e45059 100644 (file)
@@ -152,6 +152,7 @@ unsigned long get_wchan(struct task_struct *p);
 #define user_stack_pointer(regs)        ((regs)->ctx.AX[0].U0)
 
 #define cpu_relax()     barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency()  cpu_relax()
 
 extern void setup_priv(void);
index c38d0dd91134c4049d695931ccee3f4cb4dfd11c..fd7dd11c730af294c867a51a28abfdd1c3ed746e 100644 (file)
@@ -22,6 +22,7 @@
 extern const struct seq_operations cpuinfo_op;
 
 # define cpu_relax()           barrier()
+# define cpu_relax_yield() cpu_relax()
 # define cpu_relax_lowlatency()        cpu_relax()
 
 #define task_pt_regs(tsk) \
index 0d36c87acbe24852e231e0ecc7e24918807877f5..9a656f6afc7cc74b62c2358630cb34eb5840ad70 100644 (file)
@@ -389,6 +389,7 @@ unsigned long get_wchan(struct task_struct *p);
 #define KSTK_STATUS(tsk) (task_pt_regs(tsk)->cp0_status)
 
 #define cpu_relax()    barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 /*
index b10ba121c849c4167551f9a44f7ac2a37b4480d1..89f63d1720ee9ebf345fab5026f540ce2bb8f2d1 100644 (file)
@@ -69,6 +69,7 @@ extern void print_cpu_info(struct mn10300_cpuinfo *);
 extern void dodgy_tsc(void);
 
 #define cpu_relax() barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 /*
index 1c953f0cadbf33ad4b7d0d994427afbfb4d0f358..303e5932a733c5236bdb5fc0146ceaa9663b36ef 100644 (file)
@@ -88,6 +88,7 @@ extern unsigned long get_wchan(struct task_struct *p);
 #define KSTK_ESP(tsk)  ((tsk)->thread.kregs->sp)
 
 #define cpu_relax()    barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency()  cpu_relax()
 
 #endif /* __ASSEMBLY__ */
index 70334c9f7d24ce83a0e81d34f6737351f6f29e90..6ecfc2ab28e410a538ab58727fcd75d980818aa7 100644 (file)
@@ -92,6 +92,7 @@ extern unsigned long thread_saved_pc(struct task_struct *t);
 #define init_stack      (init_thread_union.stack)
 
 #define cpu_relax()     barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 #endif /* __ASSEMBLY__ */
index 2e674e13e005420b15beb9b945e2d88c850937f0..ea2ff9febffd971961aa5bb9f9fc423b2a56d15e 100644 (file)
@@ -309,6 +309,7 @@ extern unsigned long get_wchan(struct task_struct *p);
 #define KSTK_ESP(tsk)  ((tsk)->thread.regs.gr[30])
 
 #define cpu_relax()    barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 /*
index c07c31b0e89e2b4b010127973ba20c32947aef5d..908fa7cb3fb3f76790a353a70c4053e981e55c49 100644 (file)
@@ -404,6 +404,7 @@ static inline unsigned long __pack_fe01(unsigned int fpmode)
 #define cpu_relax()    barrier()
 #endif
 
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 /* Check that a certain kernel stack pointer is valid in task_struct p */
index 602af692efdc1b5273e466b474dbf1a6c7e25922..5bb44333d3203377e3ea759e1e6ef8929b1ddac6 100644 (file)
@@ -234,8 +234,9 @@ static inline unsigned short stap(void)
 /*
  * Give up the time slice of the virtual PU.
  */
-void cpu_relax(void);
+void cpu_relax_yield(void);
 
+#define cpu_relax() cpu_relax_yield()
 #define cpu_relax_lowlatency()  barrier()
 
 #define ECAG_CACHE_ATTRIBUTE   0
index 81d0808085e6bca9d2ff35c30619f7a238754db2..9e60ef144d03ea710179e3ea1b11313d4523b082 100644 (file)
@@ -53,7 +53,7 @@ void s390_update_cpu_mhz(void)
                on_each_cpu(update_cpu_mhz, NULL, 0);
 }
 
-void notrace cpu_relax(void)
+void notrace cpu_relax_yield(void)
 {
        if (!smp_cpu_mtid && MACHINE_HAS_DIAG44) {
                diag_stat_inc(DIAG_STAT_X044);
@@ -61,7 +61,7 @@ void notrace cpu_relax(void)
        }
        barrier();
 }
-EXPORT_SYMBOL(cpu_relax);
+EXPORT_SYMBOL(cpu_relax_yield);
 
 /*
  * cpu_init - initializes state that is per-CPU.
index 851f441991d2764315057654ef988db57c659dac..e8e87b4d7971cfbc06b216cb8d09dd6db3f9205e 100644 (file)
@@ -24,6 +24,7 @@ extern unsigned long get_wchan(struct task_struct *p);
 #define current_text_addr() ({ __label__ _l; _l: &&_l; })
 
 #define cpu_relax()            barrier()
+#define cpu_relax_yield()      cpu_relax()
 #define cpu_relax_lowlatency()        cpu_relax()
 #define release_thread(thread) do {} while (0)
 
index f9a09942a32d37249b43ec4139762aaafa16443d..099a99105e1c7f46a1b51904c892c112f415929e 100644 (file)
@@ -97,6 +97,7 @@ extern struct sh_cpuinfo cpu_data[];
 
 #define cpu_sleep()    __asm__ __volatile__ ("sleep" : : : "memory")
 #define cpu_relax()    barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 void default_idle(void);
index 812fd08f3e6253ecb490ff149894bafae79bbc26..50e908a3c6519e6790a72abd11ec5b79ab50dafd 100644 (file)
@@ -119,6 +119,7 @@ extern struct task_struct *last_task_used_math;
 int do_mathemu(struct pt_regs *regs, struct task_struct *fpt);
 
 #define cpu_relax()    barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 extern void (*sparc_idle)(void);
index ce2595c894711367d36027dbe5db3324575596b3..3e8fac724f18c1ac1b8c96152976bc2d081c75ae 100644 (file)
@@ -216,6 +216,7 @@ unsigned long get_wchan(struct task_struct *task);
                                     "nop\n\t"                          \
                                     ".previous"                        \
                                     ::: "memory")
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 /* Prefetch support.  This is tuned for UltraSPARC-III and later.
index 0684e88aacd8ebb8a58a52a82f360bd4e1c77f59..91a39a50520d42c09f84dd916b57571e7b373476 100644 (file)
@@ -264,6 +264,7 @@ static inline void cpu_relax(void)
        barrier();
 }
 
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 /* Info on this processor (see fs/proc/cpuinfo.c) */
index 8d21b7adf26bc3709ba865b6f29db2a18436f0a0..fc54d5d50419234f487919c8175e935461027b09 100644 (file)
@@ -71,6 +71,7 @@ extern void release_thread(struct task_struct *);
 unsigned long get_wchan(struct task_struct *p);
 
 #define cpu_relax()                    barrier()
+#define cpu_relax_yield()              cpu_relax()
 #define cpu_relax_lowlatency()                cpu_relax()
 
 #define task_pt_regs(p) \
index 984a7bf17f6a7295c3a7c8531e68cb807a722c35..44adadab44d6f112e96b73c0f9bd9351f91a7370 100644 (file)
@@ -588,6 +588,7 @@ static __always_inline void cpu_relax(void)
        rep_nop();
 }
 
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 /* Stop speculative execution and prefetching of modified code. */
index 233ee09c1ce88b44fea8366a8e0c43593abe7eb9..01597afa8888e0f6a083714aaa284dd7292c62ef 100644 (file)
@@ -26,6 +26,7 @@ static inline void rep_nop(void)
 }
 
 #define cpu_relax()            rep_nop()
+#define cpu_relax_yield()      cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 #define task_pt_regs(t) (&(t)->thread.regs)
index b42d68bfe3cf0a965380bef7aae9afdcdada8050..fe14dc2b394a20490d95815b21eea75bb9a372ad 100644 (file)
@@ -206,6 +206,7 @@ extern unsigned long get_wchan(struct task_struct *p);
 #define KSTK_ESP(tsk)          (task_pt_regs(tsk)->areg[1])
 
 #define cpu_relax()  barrier()
+#define cpu_relax_yield() cpu_relax()
 #define cpu_relax_lowlatency() cpu_relax()
 
 /* Special register access. */