lkml.org 
[lkml]   [2008]   [Aug]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH RFC 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 <jeremy.fitzhardinge@citrix.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
---
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(+)

===================================================================
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -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
===================================================================
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -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
===================================================================
--- a/arch/x86/kernel/paravirt-spinlocks.c
+++ b/arch/x86/kernel/paravirt-spinlocks.c
@@ -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);

===================================================================
--- /dev/null
+++ b/arch/x86/kernel/trigger.c
@@ -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);
+}
===================================================================
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -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 */
===================================================================
--- /dev/null
+++ b/include/asm-x86/trigger.h
@@ -0,0 +1,54 @@
+#ifndef _ASM_X86_TRIGGER_H
+#define _ASM_X86_TRIGGER_H
+
+#include <linux/cpumask.h>
+
+struct trigger {
+ unsigned trigger;
+ cpumask_t cpus;
+};
+
+typedef struct trigger trigger_t;
+
+#define DEFINE_TRIGGER(t) trigger_t t = { 0, CPU_MASK_NONE }
+
+static inline void __raw_trigger_init(trigger_t *t)
+{
+ t->cpus = CPU_MASK_NONE;
+ t->trigger = 0;
+}
+
+static inline void native_trigger_finish(trigger_t *t)
+{
+}
+
+/* out of line to avoid #include hell */
+extern void native_trigger_reset(trigger_t *t);
+extern void native_trigger_wait(trigger_t *t);
+extern void native_trigger_kick(trigger_t *t);
+
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt.h>
+#else /* CONFIG_PARAVIRT */
+static inline void __raw_trigger_reset(trigger_t *t)
+{
+ native_trigger_reset(t);
+}
+
+static inline void __raw_trigger_wait(trigger_t *t)
+{
+ native_trigger_wait(t);
+}
+
+static inline void __raw_trigger_finish(trigger_t *t)
+{
+ native_trigger_finish(t);
+}
+
+static inline void __raw_trigger_kick(trigger_t *t)
+{
+ native_trigger_kick(t);
+}
+#endif /* CONFIG_PARAVIRT */
+
+#endif /* _ASM_X86_TRIGGER_H */



\
 
 \ /
  Last update: 2008-08-16 18:37    [W:0.043 / U:0.596 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site