update compat
[lttv.git] / trunk / tests / kernel / test-rcu-speed.c
CommitLineData
6087c592 1/* test-rcu-speed.c
3343768e 2 *
6087c592 3 * Compare speed of :
4 * - spin lock irqsave/ spin unlock irqrestore
5 * - using a sequence read lock (uncontended)
6 * - preempt disable/enable
3343768e 7 */
8
9
10#include <linux/jiffies.h>
11#include <linux/compiler.h>
12#include <linux/init.h>
13#include <linux/module.h>
6087c592 14#include <linux/math64.h>
8593c315 15#include <linux/spinlock.h>
16#include <linux/seqlock.h>
6087c592 17#include <linux/cpumask.h>
3343768e 18#include <asm/timex.h>
19#include <asm/system.h>
20
21#define NR_LOOPS 20000
22
6087c592 23#ifndef CONFIG_PREEMPT
24#error "Your kernel should be build with preemption enabled"
25#endif
26
27#ifdef CONFIG_DEBUG_PREEMPT
28#error "Please disable CONFIG_DEBUG_PREEMPT"
29#endif
30
31#ifdef CONFIG_DEBUG_SPINLOCK
32#error "Please disable CONFIG_DEBUG_SPINLOCK"
33#endif
34
35#ifdef CONFIG_LOCKDEP
36#error "Please disable CONFIG_LOCKDEP"
37#endif
38
3343768e 39int test_val;
40
41static void do_testbaseline(void)
42{
6087c592 43 unsigned long flags;
3343768e 44 unsigned int i;
45 cycles_t time1, time2, time;
6087c592 46 u32 rem;
3343768e 47
48 local_irq_save(flags);
49 preempt_disable();
50 time1 = get_cycles();
51 for (i = 0; i < NR_LOOPS; i++) {
52 asm volatile ("");
53 }
54 time2 = get_cycles();
55 local_irq_restore(flags);
56 preempt_enable();
57 time = time2 - time1;
58
59 printk(KERN_ALERT "test results: time for baseline\n");
60 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
61 printk(KERN_ALERT "total time: %llu\n", time);
6087c592 62 time = div_u64_rem(time, NR_LOOPS, &rem);
3343768e 63 printk(KERN_ALERT "-> baseline takes %llu cycles\n", time);
64 printk(KERN_ALERT "test end\n");
65}
66
67static void do_test_spinlock(void)
68{
8593c315 69 static DEFINE_SPINLOCK(mylock);
6087c592 70 unsigned long flags;
3343768e 71 unsigned int i;
72 cycles_t time1, time2, time;
6087c592 73 u32 rem;
3343768e 74
75 preempt_disable();
8593c315 76 spin_lock_irqsave(&mylock, flags);
3343768e 77 time1 = get_cycles();
78 for (i = 0; i < NR_LOOPS; i++) {
0c12e051 79 spin_unlock(&mylock);
80 spin_lock(&mylock);
3343768e 81 }
82 time2 = get_cycles();
8593c315 83 spin_unlock_irqrestore(&mylock, flags);
3343768e 84 preempt_enable();
85 time = time2 - time1;
86
87 printk(KERN_ALERT "test results: time for spinlock\n");
88 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
89 printk(KERN_ALERT "total time: %llu\n", time);
6087c592 90 time = div_u64_rem(time, NR_LOOPS, &rem);
3343768e 91 printk(KERN_ALERT "-> spinlock takes %llu cycles\n", time);
92 printk(KERN_ALERT "test end\n");
93}
94
95static void do_test_seqlock(void)
96{
97 static seqlock_t test_lock;
8593c315 98 unsigned long seq;
6087c592 99 unsigned long flags;
3343768e 100 unsigned int i;
101 cycles_t time1, time2, time;
6087c592 102 u32 rem;
3343768e 103
472e3e15 104 local_irq_save(flags);
3343768e 105 time1 = get_cycles();
106 for (i = 0; i < NR_LOOPS; i++) {
107 do {
472e3e15 108 seq = read_seqbegin(&test_lock);
109 } while (read_seqretry(&test_lock, seq));
3343768e 110 }
111 time2 = get_cycles();
3343768e 112 time = time2 - time1;
472e3e15 113 local_irq_restore(flags);
3343768e 114
115 printk(KERN_ALERT "test results: time for seqlock\n");
116 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
117 printk(KERN_ALERT "total time: %llu\n", time);
6087c592 118 time = div_u64_rem(time, NR_LOOPS, &rem);
3343768e 119 printk(KERN_ALERT "-> seqlock takes %llu cycles\n", time);
120 printk(KERN_ALERT "test end\n");
121}
122
123/*
6087c592 124 * Note : This test _should_ trigger lockdep errors due to preemption
125 * disabling/enabling within irq off section. Given we are only interested in
126 * having the most precise measurement for preemption disable/enable, we don't
127 * care about this.
3343768e 128 */
129static void do_test_preempt(void)
130{
6087c592 131 unsigned long flags;
3343768e 132 unsigned int i;
133 cycles_t time1, time2, time;
6087c592 134 u32 rem;
3343768e 135
136 local_irq_save(flags);
137 preempt_disable();
138 time1 = get_cycles();
139 for (i = 0; i < NR_LOOPS; i++) {
3343768e 140 preempt_disable();
54e7c224 141 preempt_enable();
3343768e 142 }
143 time2 = get_cycles();
144 preempt_enable();
145 time = time2 - time1;
146 local_irq_restore(flags);
147
148 printk(KERN_ALERT "test results: time for preempt disable/enable pairs\n");
149 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
150 printk(KERN_ALERT "total time: %llu\n", time);
6087c592 151 time = div_u64_rem(time, NR_LOOPS, &rem);
3343768e 152 printk(KERN_ALERT "-> preempt disable/enable pair takes %llu cycles\n",
153 time);
154 printk(KERN_ALERT "test end\n");
155}
156
157static int ltt_test_init(void)
158{
159 printk(KERN_ALERT "test init\n");
160
6087c592 161 printk(KERN_ALERT "Number of active CPUs : %d\n", num_online_cpus());
3343768e 162 do_testbaseline();
163 do_test_spinlock();
164 do_test_seqlock();
165 do_test_preempt();
166 return -EAGAIN; /* Fail will directly unload the module */
167}
168
169static void ltt_test_exit(void)
170{
171 printk(KERN_ALERT "test exit\n");
172}
173
174module_init(ltt_test_init)
175module_exit(ltt_test_exit)
176
177MODULE_LICENSE("GPL");
178MODULE_AUTHOR("Mathieu Desnoyers");
179MODULE_DESCRIPTION("Cmpxchg vs int Test");
180
This page took 0.034769 seconds and 4 git commands to generate.