x86: implement trigger API
Subsystems (2)
RFC PATCH 2/3 x86: implement trigger API
Add an x86-specific implementation. This patch doesn't do much other than wire it up to paravirt_ops, and lay the groundwork for the upcoming monitor/mwait implementation.
Signed-off-by Jeremy Fitzhardinge <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Christian Borntraeger <[email protected]>
Cc Rusty Russell <[email protected]>
--- arch/x86/Kconfig | 3 + arch/x86/kernel/Makefile | 1 arch/x86/kernel/paravirt-spinlocks.c | 6 +++ arch/x86/kernel/trigger.c | 23 ++++++++++++++ include/asm-x86/paravirt.h | 27 +++++++++++++++++ include/asm-x86/trigger.h | 54 ++++++++++++++++++++++++++++++++++ 6 files changed, 114 insertions(+)
===================================================================
arch/x86/Kconfig +3 -0
@@ -124,6 +124,9 @@ config ARCH_HAS_CPU_RELAX def_bool y + +config ARCH_HAS_TRIGGER + def_bool y config ARCH_HAS_CACHE_LINE_SIZE def_bool y
===================================================================
arch/x86/kernel/Makefile +1 -0
@@ -36,6 +36,7 @@ obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o obj-y += alternative.o i8253.o pci-nommu.o obj-y += tsc.o io_delay.o rtc.o +obj-y += trigger.o obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o obj-y += process.o
===================================================================
arch/x86/kernel/paravirt-spinlocks.c +6 -0
@@ -3,6 +3,7 @@* compiled in a FTRACE-compatible way. */ #include <linux/spinlock.h> +#include <linux/trigger.h> #include <linux/module.h> #include <asm/paravirt.h>
@@ -22,6 +23,11 @@ .spin_trylock = __ticket_spin_trylock, .spin_unlock = __ticket_spin_unlock, #endif + + .trigger_wait = native_trigger_wait, + .trigger_reset = native_trigger_reset, + .trigger_kick = native_trigger_kick, + .trigger_finish = paravirt_nop, };EXPORT_SYMBOL_GPL (pv_lock_ops);
===================================================================
arch/x86/kernel/trigger.c new file +23 -0
@@ -0,0 +1,23 @@ +#include <linux/trigger.h> +#include <linux/smp.h> + +void native_trigger_reset (trigger_t *t) +{ +cpu_clear (smp_processor_id (), t->cpus); +} + +void native_trigger_wait (trigger_t *t) +{ +int cpu =smp_processor_id (); + +while (!cpu_isset (cpu, t->cpus)) +cpu_relax (); + +cpu_clear (cpu, t->cpus); +} + +void native_trigger_kick (trigger_t *t) +{ +smp_wmb (); +cpus_setall (t->cpus); +}
===================================================================
include/asm-x86/paravirt.h +27 -0
@@ -324,6 +324,8 @@ };struct raw_spinlock ; +struct trigger ; +struct pv_lock_ops {int (*spin_is_locked)(struct raw_spinlock *lock);int (*spin_is_contended)(struct raw_spinlock *lock);
@@ -331,6 +333,11 @@void (*spin_lock_flags)(struct raw_spinlock *lock,unsigned long flags);int (*spin_trylock)(struct raw_spinlock *lock);void (*spin_unlock)(struct raw_spinlock *lock); + +void (*trigger_reset)(struct trigger *t); +void (*trigger_wait)(struct trigger *t); +void (*trigger_kick)(struct trigger *t); +void (*trigger_finish)(struct trigger *t); };/* This contains all the paravirt structures: we get a convenient
@@ -1415,6 +1422,26 @@#endif +static __always_inline void __raw_trigger_reset(struct trigger *t) +{ +PVOP_VCALL1 (pv_lock_ops.trigger_reset, t); +} + +static __always_inline void __raw_trigger_wait(struct trigger *t) +{ +PVOP_VCALL1 (pv_lock_ops.trigger_wait, t); +} + +static __always_inline void __raw_trigger_kick(struct trigger *t) +{ +PVOP_VCALL1 (pv_lock_ops.trigger_kick, t); +} + +static __always_inline void __raw_trigger_finish(struct trigger *t) +{ +PVOP_VCALL1 (pv_lock_ops.trigger_finish, t); +} +/* These all sit in the .parainstructions section to tell us what to patch. */ struct paravirt_patch_site {u8 *instr;/* original instructions */
===================================================================
include/asm-x86/trigger.h new file +54 -0
54 lines not on this page · raw message