From 7c8abf0ee42a485ac226dba8f0326b5b26477931 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 20 Aug 2008 17:02:20 -0700 Subject: [PATCH] --- yaml --- r: 113247 b: refs/heads/master c: 1e696f638b523958ee3d95e655becdb4c4b6fcde h: refs/heads/master i: 113245: 6f5d0f3f2313e9cdc379ceba094182448439aea9 113243: e29c9c67fdd4d461f05d62be745f246787c9e0b1 113239: f1a4828b996560abec18d02d557544f6c357280d 113231: 52a32666fa3536209aebaee272db7fdbffe82deb 113215: 24872438d1a56dd8ddea5b4fc4d7d4419b3e07dc v: v3 --- [refs] | 2 +- trunk/arch/x86/xen/spinlock.c | 30 +++++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index a93de29d5120..2d7f55555960 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 994025caba3e6beade9bde84dd1b70d9d250f27b +refs/heads/master: 1e696f638b523958ee3d95e655becdb4c4b6fcde diff --git a/trunk/arch/x86/xen/spinlock.c b/trunk/arch/x86/xen/spinlock.c index 0d8f3b2d9bec..e6061f2e64f2 100644 --- a/trunk/arch/x86/xen/spinlock.c +++ b/trunk/arch/x86/xen/spinlock.c @@ -23,6 +23,7 @@ static struct xen_spinlock_stats u32 taken_slow_nested; u32 taken_slow_pickup; u32 taken_slow_spurious; + u32 taken_slow_irqenable; u64 released; u32 released_slow; @@ -167,12 +168,13 @@ static inline void unspinning_lock(struct xen_spinlock *xl, struct xen_spinlock __get_cpu_var(lock_spinners) = prev; } -static noinline int xen_spin_lock_slow(struct raw_spinlock *lock) +static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enable) { struct xen_spinlock *xl = (struct xen_spinlock *)lock; struct xen_spinlock *prev; int irq = __get_cpu_var(lock_kicker_irq); int ret; + unsigned long flags; /* If kicker interrupts not initialized yet, just spin */ if (irq == -1) @@ -181,6 +183,12 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock) /* announce we're spinning */ prev = spinning_lock(xl); + flags = __raw_local_save_flags(); + if (irq_enable) { + ADD_STATS(taken_slow_irqenable, 1); + raw_local_irq_enable(); + } + ADD_STATS(taken_slow, 1); ADD_STATS(taken_slow_nested, prev != NULL); @@ -220,11 +228,12 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock) kstat_this_cpu.irqs[irq]++; out: + raw_local_irq_restore(flags); unspinning_lock(xl, prev); return ret; } -static void xen_spin_lock(struct raw_spinlock *lock) +static inline void __xen_spin_lock(struct raw_spinlock *lock, bool irq_enable) { struct xen_spinlock *xl = (struct xen_spinlock *)lock; unsigned timeout; @@ -254,11 +263,23 @@ static void xen_spin_lock(struct raw_spinlock *lock) : "memory"); spin_time_accum_fast(start_spin_fast); - } while (unlikely(oldval != 0 && (TIMEOUT == ~0 || !xen_spin_lock_slow(lock)))); + + } while (unlikely(oldval != 0 && + (TIMEOUT == ~0 || !xen_spin_lock_slow(lock, irq_enable)))); spin_time_accum(start_spin); } +static void xen_spin_lock(struct raw_spinlock *lock) +{ + __xen_spin_lock(lock, false); +} + +static void xen_spin_lock_flags(struct raw_spinlock *lock, unsigned long flags) +{ + __xen_spin_lock(lock, !raw_irqs_disabled_flags(flags)); +} + static noinline void xen_spin_unlock_slow(struct xen_spinlock *xl) { int cpu; @@ -323,6 +344,7 @@ void __init xen_init_spinlocks(void) pv_lock_ops.spin_is_locked = xen_spin_is_locked; pv_lock_ops.spin_is_contended = xen_spin_is_contended; pv_lock_ops.spin_lock = xen_spin_lock; + pv_lock_ops.spin_lock_flags = xen_spin_lock_flags; pv_lock_ops.spin_trylock = xen_spin_trylock; pv_lock_ops.spin_unlock = xen_spin_unlock; } @@ -353,6 +375,8 @@ static int __init xen_spinlock_debugfs(void) &spinlock_stats.taken_slow_pickup); debugfs_create_u32("taken_slow_spurious", 0444, d_spin_debug, &spinlock_stats.taken_slow_spurious); + debugfs_create_u32("taken_slow_irqenable", 0444, d_spin_debug, + &spinlock_stats.taken_slow_irqenable); debugfs_create_u64("released", 0444, d_spin_debug, &spinlock_stats.released); debugfs_create_u32("released_slow", 0444, d_spin_debug,