diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2013-08-09 10:21:55 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2013-08-09 10:53:44 -0400 |
commit | 354714dd2607778692db53947ab93b74956494e5 (patch) | |
tree | f02add96b7d26f88cee9383ed522f7d67264e9bc /arch | |
parent | b8fa70b51aa76737bdb6b493901ef7376977489c (diff) |
x86, pvticketlock: Use callee-save for lock_spinning
Although the lock_spinning calls in the spinlock code are on the
uncommon path, their presence can cause the compiler to generate many
more register save/restores in the function pre/postamble, which is in
the fast path. To avoid this, convert it to using the pvops callee-save
calling convention, which defers all the save/restores until the actual
function is called, keeping the fastpath clean.
Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org>
Link: http://lkml.kernel.org/r/1376058122-8248-8-git-send-email-raghavendra.kt@linux.vnet.ibm.com
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Tested-by: Attilio Rao <attilio.rao@citrix.com>
Signed-off-by: Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/paravirt.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/paravirt_types.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/paravirt-spinlocks.c | 2 | ||||
-rw-r--r-- | arch/x86/xen/spinlock.c | 3 |
4 files changed, 5 insertions, 4 deletions
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 040e72db5ea9..7131e12cefa1 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -715,7 +715,7 @@ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, | |||
715 | static __always_inline void __ticket_lock_spinning(struct arch_spinlock *lock, | 715 | static __always_inline void __ticket_lock_spinning(struct arch_spinlock *lock, |
716 | __ticket_t ticket) | 716 | __ticket_t ticket) |
717 | { | 717 | { |
718 | PVOP_VCALL2(pv_lock_ops.lock_spinning, lock, ticket); | 718 | PVOP_VCALLEE2(pv_lock_ops.lock_spinning, lock, ticket); |
719 | } | 719 | } |
720 | 720 | ||
721 | static __always_inline void ____ticket_unlock_kick(struct arch_spinlock *lock, | 721 | static __always_inline void ____ticket_unlock_kick(struct arch_spinlock *lock, |
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 346a07c1e71d..04ac40e192eb 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h | |||
@@ -334,7 +334,7 @@ typedef u16 __ticket_t; | |||
334 | #endif | 334 | #endif |
335 | 335 | ||
336 | struct pv_lock_ops { | 336 | struct pv_lock_ops { |
337 | void (*lock_spinning)(struct arch_spinlock *lock, __ticket_t ticket); | 337 | struct paravirt_callee_save lock_spinning; |
338 | void (*unlock_kick)(struct arch_spinlock *lock, __ticket_t ticket); | 338 | void (*unlock_kick)(struct arch_spinlock *lock, __ticket_t ticket); |
339 | }; | 339 | }; |
340 | 340 | ||
diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c index c2e010e5fbce..4251c1d4c0be 100644 --- a/arch/x86/kernel/paravirt-spinlocks.c +++ b/arch/x86/kernel/paravirt-spinlocks.c | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | struct pv_lock_ops pv_lock_ops = { | 10 | struct pv_lock_ops pv_lock_ops = { |
11 | #ifdef CONFIG_SMP | 11 | #ifdef CONFIG_SMP |
12 | .lock_spinning = paravirt_nop, | 12 | .lock_spinning = __PV_IS_CALLEE_SAVE(paravirt_nop), |
13 | .unlock_kick = paravirt_nop, | 13 | .unlock_kick = paravirt_nop, |
14 | #endif | 14 | #endif |
15 | }; | 15 | }; |
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 669a971c78fd..6c8792b298ed 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c | |||
@@ -173,6 +173,7 @@ out: | |||
173 | local_irq_restore(flags); | 173 | local_irq_restore(flags); |
174 | spin_time_accum_blocked(start); | 174 | spin_time_accum_blocked(start); |
175 | } | 175 | } |
176 | PV_CALLEE_SAVE_REGS_THUNK(xen_lock_spinning); | ||
176 | 177 | ||
177 | static void xen_unlock_kick(struct arch_spinlock *lock, __ticket_t next) | 178 | static void xen_unlock_kick(struct arch_spinlock *lock, __ticket_t next) |
178 | { | 179 | { |
@@ -260,7 +261,7 @@ void __init xen_init_spinlocks(void) | |||
260 | return; | 261 | return; |
261 | } | 262 | } |
262 | 263 | ||
263 | pv_lock_ops.lock_spinning = xen_lock_spinning; | 264 | pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning); |
264 | pv_lock_ops.unlock_kick = xen_unlock_kick; | 265 | pv_lock_ops.unlock_kick = xen_unlock_kick; |
265 | } | 266 | } |
266 | 267 | ||