convert from svn repository: remove tags directory
[lttv.git] / trunk / tests / kernel / test-tsc.c
CommitLineData
63787240 1/* test-tsc.c
2 *
3 * Test TSC synchronization
4 */
5
6
7#include <linux/module.h>
8#include <linux/timer.h>
9#include <asm/timex.h>
10#include <linux/jiffies.h>
11#include <linux/cpu.h>
12#include <linux/kthread.h>
13
14#define MAX_CYCLES_DELTA 1000ULL
15
16static DEFINE_PER_CPU(cycles_t, tsc_count) = 0;
17
18static atomic_t wait_sync;
19static atomic_t wait_end_sync;
20
21/* Mark it noinline so we make sure it is not unrolled.
22 * Wait until value is reached. */
23static noinline void tsc_barrier(int value)
24{
25 sync_core();
26 atomic_dec(&wait_sync);
27 do {
28 barrier();
29 } while(unlikely(atomic_read(&wait_sync) > value));
30 __get_cpu_var(tsc_count) = get_cycles_sync();
31}
32
33/* worker thread called on each CPU.
34 * First wait with interrupts enabled, then wait with interrupt disabled,
35 * for precision. We are already bound to one CPU. */
36static void test_sync(void *arg)
37{
38 unsigned long flags;
39
40 local_irq_save(flags);
41 tsc_barrier(2); /* Make sure the instructions are in I-CACHE */
42 tsc_barrier(0);
43 atomic_dec(&wait_end_sync);
44 do {
45 barrier();
46 } while(unlikely(atomic_read(&wait_end_sync)));
47 local_irq_restore(flags);
48}
49
50/* Do loops (making sure no unexpected event changes the timing), keep the
51 * best one. The result of each loop is the highest tsc delta between the
52 * master CPU and the slaves. */
53static int test_synchronization(void)
54{
55 int cpu, master;
56 cycles_t max_diff = 0, diff, best_loop, worse_loop = 0;
57 int i;
58
59 preempt_disable();
60 master = smp_processor_id();
61 for_each_online_cpu(cpu) {
62 if (master == cpu)
63 continue;
64 best_loop = ULLONG_MAX;
65 for (i = 0; i < 10; i++) {
66 /* Each CPU (master and slave) must decrement the
67 * wait_sync value twice (one for priming in cache) */
68 atomic_set(&wait_sync, 4);
69 atomic_set(&wait_end_sync, 2);
70 smp_call_function_single(cpu, test_sync, NULL, 1, 0);
71 test_sync(NULL);
72 diff = abs(per_cpu(tsc_count, cpu)
73 - per_cpu(tsc_count, master));
74 best_loop = min(best_loop, diff);
75 worse_loop = max(worse_loop, diff);
76 }
77 max_diff = max(best_loop, max_diff);
78 }
79 preempt_enable();
80 if (max_diff >= MAX_CYCLES_DELTA) {
81 printk("Synchronization tsc : %llu cycles delta is over "
82 "threshold %llu\n", max_diff, MAX_CYCLES_DELTA);
83 printk("Synchronization tsc (worse loop) : %llu cycles delta\n",
84 worse_loop);
85 }
86 return max_diff < MAX_CYCLES_DELTA;
87}
88
89static int __init test_init(void)
90{
91 int ret;
92
93 ret = test_synchronization();
94 return 0;
95}
96
97static void __exit test_exit(void)
98{
99}
100
101module_init(test_init);
102module_exit(test_exit);
103
104MODULE_LICENSE("GPL");
105MODULE_AUTHOR("Mathieu Desnoyers");
106MODULE_DESCRIPTION("sync tsc test");
107
This page took 0.0431589999999999 seconds and 4 git commands to generate.