diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-27 16:19:22 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-27 16:19:22 -0800 |
commit | f1dd6ad599732fc89f36fdd65a2c2cf3c63a8711 (patch) | |
tree | 5092207128e47cba99dc0fe373fff6a36f4cb4b8 /arch/mips/kernel/spinlock_test.c | |
parent | 8d37a371b6869920e6c40c495c68eabba1ef3909 (diff) | |
parent | e10b234b3c4e255d3300a486c4ac15b43253ac6d (diff) |
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (141 commits)
MIPS: Alchemy: defconfig updates
MIPS: Alchemy: Fix Au1100 ethernet build failure
MIPS: Alchemy: Repair db1500/bosporus builds
MIPS: ARC: Cleanup unused definitions from sgialib.h
MIPS: Cobalt: convert legacy port addresses to GT-64111 bus addresses
MIPS: Alchemy: use 36bit addresses for PCMCIA resources.
MIPS: Cobalt: Fix theoretical port aliasing issue
MIPS: Use ALIGN(x, bytes) instead of __ALIGN_MASK(x, bytes - 1)
MIPS: Crazy spinlock speed test.
MIPS: Optimize spinlocks.
MIPS: Alchemy: devboard PM needs to save CPLD registers.
MIPS: PowerTV: Eliminate duplicate opcode definition macros
MIPS: Lemote 2F: Move printks out of port_access_lock.
MIPS: PNX833x: Convert IRQ controller locks to raw spinlocks.
MIPS: Octeon: Replace spinlock with raw_spinlocks in dma-octeon.c.
MIPS: Octeon: Replace rwlocks in irq_chip handlers with raw_spinlocks.
MIPS: Octeon: Convert octeon_irq_msi_lock to raw spinlock.
MIPS: Loongson: Remove pointless sample_lock from oprofile code.
MIPS: SNI: Convert sni_rm200_i8259A_lock to raw spinlock.
MIPS: i8259: Convert IRQ controller lock to raw spinlock.
...
Diffstat (limited to 'arch/mips/kernel/spinlock_test.c')
-rw-r--r-- | arch/mips/kernel/spinlock_test.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/arch/mips/kernel/spinlock_test.c b/arch/mips/kernel/spinlock_test.c new file mode 100644 index 00000000000..da61134dfc5 --- /dev/null +++ b/arch/mips/kernel/spinlock_test.c @@ -0,0 +1,141 @@ +#include <linux/init.h> +#include <linux/kthread.h> +#include <linux/hrtimer.h> +#include <linux/fs.h> +#include <linux/debugfs.h> +#include <linux/module.h> +#include <linux/spinlock.h> + + +static int ss_get(void *data, u64 *val) +{ + ktime_t start, finish; + int loops; + int cont; + DEFINE_RAW_SPINLOCK(ss_spin); + + loops = 1000000; + cont = 1; + + start = ktime_get(); + + while (cont) { + raw_spin_lock(&ss_spin); + loops--; + if (loops == 0) + cont = 0; + raw_spin_unlock(&ss_spin); + } + + finish = ktime_get(); + + *val = ktime_us_delta(finish, start); + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(fops_ss, ss_get, NULL, "%llu\n"); + + + +struct spin_multi_state { + raw_spinlock_t lock; + atomic_t start_wait; + atomic_t enter_wait; + atomic_t exit_wait; + int loops; +}; + +struct spin_multi_per_thread { + struct spin_multi_state *state; + ktime_t start; +}; + +static int multi_other(void *data) +{ + int loops; + int cont; + struct spin_multi_per_thread *pt = data; + struct spin_multi_state *s = pt->state; + + loops = s->loops; + cont = 1; + + atomic_dec(&s->enter_wait); + + while (atomic_read(&s->enter_wait)) + ; /* spin */ + + pt->start = ktime_get(); + + atomic_dec(&s->start_wait); + + while (atomic_read(&s->start_wait)) + ; /* spin */ + + while (cont) { + raw_spin_lock(&s->lock); + loops--; + if (loops == 0) + cont = 0; + raw_spin_unlock(&s->lock); + } + + atomic_dec(&s->exit_wait); + while (atomic_read(&s->exit_wait)) + ; /* spin */ + return 0; +} + +static int multi_get(void *data, u64 *val) +{ + ktime_t finish; + struct spin_multi_state ms; + struct spin_multi_per_thread t1, t2; + + ms.lock = __RAW_SPIN_LOCK_UNLOCKED("multi_get"); + ms.loops = 1000000; + + atomic_set(&ms.start_wait, 2); + atomic_set(&ms.enter_wait, 2); + atomic_set(&ms.exit_wait, 2); + t1.state = &ms; + t2.state = &ms; + + kthread_run(multi_other, &t2, "multi_get"); + + multi_other(&t1); + + finish = ktime_get(); + + *val = ktime_us_delta(finish, t1.start); + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(fops_multi, multi_get, NULL, "%llu\n"); + + +extern struct dentry *mips_debugfs_dir; +static int __init spinlock_test(void) +{ + struct dentry *d; + + if (!mips_debugfs_dir) + return -ENODEV; + + d = debugfs_create_file("spin_single", S_IRUGO, + mips_debugfs_dir, NULL, + &fops_ss); + if (!d) + return -ENOMEM; + + d = debugfs_create_file("spin_multi", S_IRUGO, + mips_debugfs_dir, NULL, + &fops_multi); + if (!d) + return -ENOMEM; + + return 0; +} +device_initcall(spinlock_test); |