diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2013-07-04 17:11:22 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2013-07-04 17:11:22 -0400 |
commit | 2b0f89317e99735bbf32eaede81f707f98ab1b5e (patch) | |
tree | 16daa236e21876b11f1c0b9256cd4046aadba020 /tools | |
parent | 07bd1172902e782f288e4d44b1fde7dec0f08b6f (diff) | |
parent | fa18f7bde3ad4568d1d343b60d963bfbd8dc3991 (diff) |
Merge branch 'timers/posix-cpu-timers-for-tglx' of
git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks into timers/core
Frederic sayed: "Most of these patches have been hanging around for
several month now, in -mmotm for a significant chunk. They already
missed a few releases."
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'tools')
-rwxr-xr-x | tools/perf/scripts/python/net_dropmonitor.py | 39 | ||||
-rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 2 | ||||
-rw-r--r-- | tools/testing/selftests/Makefile | 2 | ||||
-rw-r--r-- | tools/testing/selftests/soft-dirty/Makefile | 10 | ||||
-rw-r--r-- | tools/testing/selftests/soft-dirty/soft-dirty.c | 114 | ||||
-rw-r--r-- | tools/testing/selftests/timers/Makefile | 8 | ||||
-rw-r--r-- | tools/testing/selftests/timers/posix_timers.c | 221 |
7 files changed, 252 insertions, 144 deletions
diff --git a/tools/perf/scripts/python/net_dropmonitor.py b/tools/perf/scripts/python/net_dropmonitor.py index a4ffc9500023..b5740599aabd 100755 --- a/tools/perf/scripts/python/net_dropmonitor.py +++ b/tools/perf/scripts/python/net_dropmonitor.py | |||
@@ -15,35 +15,38 @@ kallsyms = [] | |||
15 | 15 | ||
16 | def get_kallsyms_table(): | 16 | def get_kallsyms_table(): |
17 | global kallsyms | 17 | global kallsyms |
18 | |||
18 | try: | 19 | try: |
19 | f = open("/proc/kallsyms", "r") | 20 | f = open("/proc/kallsyms", "r") |
20 | linecount = 0 | ||
21 | for line in f: | ||
22 | linecount = linecount+1 | ||
23 | f.seek(0) | ||
24 | except: | 21 | except: |
25 | return | 22 | return |
26 | 23 | ||
27 | |||
28 | j = 0 | ||
29 | for line in f: | 24 | for line in f: |
30 | loc = int(line.split()[0], 16) | 25 | loc = int(line.split()[0], 16) |
31 | name = line.split()[2] | 26 | name = line.split()[2] |
32 | j = j +1 | 27 | kallsyms.append((loc, name)) |
33 | if ((j % 100) == 0): | ||
34 | print "\r" + str(j) + "/" + str(linecount), | ||
35 | kallsyms.append({ 'loc': loc, 'name' : name}) | ||
36 | |||
37 | print "\r" + str(j) + "/" + str(linecount) | ||
38 | kallsyms.sort() | 28 | kallsyms.sort() |
39 | return | ||
40 | 29 | ||
41 | def get_sym(sloc): | 30 | def get_sym(sloc): |
42 | loc = int(sloc) | 31 | loc = int(sloc) |
43 | for i in kallsyms: | 32 | |
44 | if (i['loc'] >= loc): | 33 | # Invariant: kallsyms[i][0] <= loc for all 0 <= i <= start |
45 | return (i['name'], i['loc']-loc) | 34 | # kallsyms[i][0] > loc for all end <= i < len(kallsyms) |
46 | return (None, 0) | 35 | start, end = -1, len(kallsyms) |
36 | while end != start + 1: | ||
37 | pivot = (start + end) // 2 | ||
38 | if loc < kallsyms[pivot][0]: | ||
39 | end = pivot | ||
40 | else: | ||
41 | start = pivot | ||
42 | |||
43 | # Now (start == -1 or kallsyms[start][0] <= loc) | ||
44 | # and (start == len(kallsyms) - 1 or loc < kallsyms[start + 1][0]) | ||
45 | if start >= 0: | ||
46 | symloc, name = kallsyms[start] | ||
47 | return (name, loc - symloc) | ||
48 | else: | ||
49 | return (None, 0) | ||
47 | 50 | ||
48 | def print_drop_table(): | 51 | def print_drop_table(): |
49 | print "%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT") | 52 | print "%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT") |
@@ -64,7 +67,7 @@ def trace_end(): | |||
64 | 67 | ||
65 | # called from perf, when it finds a correspoinding event | 68 | # called from perf, when it finds a correspoinding event |
66 | def skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm, | 69 | def skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm, |
67 | skbaddr, protocol, location): | 70 | skbaddr, location, protocol): |
68 | slocation = str(location) | 71 | slocation = str(location) |
69 | try: | 72 | try: |
70 | drop_log[slocation] = drop_log[slocation] + 1 | 73 | drop_log[slocation] = drop_log[slocation] + 1 |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 9e9d34871195..fe702076ca46 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -2191,7 +2191,7 @@ int initialize_counters(int cpu_id) | |||
2191 | 2191 | ||
2192 | void allocate_output_buffer() | 2192 | void allocate_output_buffer() |
2193 | { | 2193 | { |
2194 | output_buffer = calloc(1, (1 + topo.num_cpus) * 128); | 2194 | output_buffer = calloc(1, (1 + topo.num_cpus) * 256); |
2195 | outp = output_buffer; | 2195 | outp = output_buffer; |
2196 | if (outp == NULL) { | 2196 | if (outp == NULL) { |
2197 | perror("calloc"); | 2197 | perror("calloc"); |
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index d4abc59ce1d9..4cb14cae3791 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile | |||
@@ -6,7 +6,7 @@ TARGETS += memory-hotplug | |||
6 | TARGETS += mqueue | 6 | TARGETS += mqueue |
7 | TARGETS += net | 7 | TARGETS += net |
8 | TARGETS += ptrace | 8 | TARGETS += ptrace |
9 | TARGETS += soft-dirty | 9 | TARGETS += timers |
10 | TARGETS += vm | 10 | TARGETS += vm |
11 | 11 | ||
12 | all: | 12 | all: |
diff --git a/tools/testing/selftests/soft-dirty/Makefile b/tools/testing/selftests/soft-dirty/Makefile deleted file mode 100644 index a9cdc823d6e0..000000000000 --- a/tools/testing/selftests/soft-dirty/Makefile +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | CFLAGS += -iquote../../../../include/uapi -Wall | ||
2 | soft-dirty: soft-dirty.c | ||
3 | |||
4 | all: soft-dirty | ||
5 | |||
6 | clean: | ||
7 | rm -f soft-dirty | ||
8 | |||
9 | run_tests: all | ||
10 | @./soft-dirty || echo "soft-dirty selftests: [FAIL]" | ||
diff --git a/tools/testing/selftests/soft-dirty/soft-dirty.c b/tools/testing/selftests/soft-dirty/soft-dirty.c deleted file mode 100644 index aba4f87f87f0..000000000000 --- a/tools/testing/selftests/soft-dirty/soft-dirty.c +++ /dev/null | |||
@@ -1,114 +0,0 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include <stdio.h> | ||
3 | #include <sys/mman.h> | ||
4 | #include <unistd.h> | ||
5 | #include <fcntl.h> | ||
6 | #include <sys/types.h> | ||
7 | |||
8 | typedef unsigned long long u64; | ||
9 | |||
10 | #define PME_PRESENT (1ULL << 63) | ||
11 | #define PME_SOFT_DIRTY (1Ull << 55) | ||
12 | |||
13 | #define PAGES_TO_TEST 3 | ||
14 | #ifndef PAGE_SIZE | ||
15 | #define PAGE_SIZE 4096 | ||
16 | #endif | ||
17 | |||
18 | static void get_pagemap2(char *mem, u64 *map) | ||
19 | { | ||
20 | int fd; | ||
21 | |||
22 | fd = open("/proc/self/pagemap2", O_RDONLY); | ||
23 | if (fd < 0) { | ||
24 | perror("Can't open pagemap2"); | ||
25 | exit(1); | ||
26 | } | ||
27 | |||
28 | lseek(fd, (unsigned long)mem / PAGE_SIZE * sizeof(u64), SEEK_SET); | ||
29 | read(fd, map, sizeof(u64) * PAGES_TO_TEST); | ||
30 | close(fd); | ||
31 | } | ||
32 | |||
33 | static inline char map_p(u64 map) | ||
34 | { | ||
35 | return map & PME_PRESENT ? 'p' : '-'; | ||
36 | } | ||
37 | |||
38 | static inline char map_sd(u64 map) | ||
39 | { | ||
40 | return map & PME_SOFT_DIRTY ? 'd' : '-'; | ||
41 | } | ||
42 | |||
43 | static int check_pte(int step, int page, u64 *map, u64 want) | ||
44 | { | ||
45 | if ((map[page] & want) != want) { | ||
46 | printf("Step %d Page %d has %c%c, want %c%c\n", | ||
47 | step, page, | ||
48 | map_p(map[page]), map_sd(map[page]), | ||
49 | map_p(want), map_sd(want)); | ||
50 | return 1; | ||
51 | } | ||
52 | |||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | static void clear_refs(void) | ||
57 | { | ||
58 | int fd; | ||
59 | char *v = "4"; | ||
60 | |||
61 | fd = open("/proc/self/clear_refs", O_WRONLY); | ||
62 | if (write(fd, v, 3) < 3) { | ||
63 | perror("Can't clear soft-dirty bit"); | ||
64 | exit(1); | ||
65 | } | ||
66 | close(fd); | ||
67 | } | ||
68 | |||
69 | int main(void) | ||
70 | { | ||
71 | char *mem, x; | ||
72 | u64 map[PAGES_TO_TEST]; | ||
73 | |||
74 | mem = mmap(NULL, PAGES_TO_TEST * PAGE_SIZE, | ||
75 | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, 0, 0); | ||
76 | |||
77 | x = mem[0]; | ||
78 | mem[2 * PAGE_SIZE] = 'c'; | ||
79 | get_pagemap2(mem, map); | ||
80 | |||
81 | if (check_pte(1, 0, map, PME_PRESENT)) | ||
82 | return 1; | ||
83 | if (check_pte(1, 1, map, 0)) | ||
84 | return 1; | ||
85 | if (check_pte(1, 2, map, PME_PRESENT | PME_SOFT_DIRTY)) | ||
86 | return 1; | ||
87 | |||
88 | clear_refs(); | ||
89 | get_pagemap2(mem, map); | ||
90 | |||
91 | if (check_pte(2, 0, map, PME_PRESENT)) | ||
92 | return 1; | ||
93 | if (check_pte(2, 1, map, 0)) | ||
94 | return 1; | ||
95 | if (check_pte(2, 2, map, PME_PRESENT)) | ||
96 | return 1; | ||
97 | |||
98 | mem[0] = 'a'; | ||
99 | mem[PAGE_SIZE] = 'b'; | ||
100 | x = mem[2 * PAGE_SIZE]; | ||
101 | get_pagemap2(mem, map); | ||
102 | |||
103 | if (check_pte(3, 0, map, PME_PRESENT | PME_SOFT_DIRTY)) | ||
104 | return 1; | ||
105 | if (check_pte(3, 1, map, PME_PRESENT | PME_SOFT_DIRTY)) | ||
106 | return 1; | ||
107 | if (check_pte(3, 2, map, PME_PRESENT)) | ||
108 | return 1; | ||
109 | |||
110 | (void)x; /* gcc warn */ | ||
111 | |||
112 | printf("PASS\n"); | ||
113 | return 0; | ||
114 | } | ||
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile new file mode 100644 index 000000000000..eb2859f4ad21 --- /dev/null +++ b/tools/testing/selftests/timers/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | all: | ||
2 | gcc posix_timers.c -o posix_timers -lrt | ||
3 | |||
4 | run_tests: all | ||
5 | ./posix_timers | ||
6 | |||
7 | clean: | ||
8 | rm -f ./posix_timers | ||
diff --git a/tools/testing/selftests/timers/posix_timers.c b/tools/testing/selftests/timers/posix_timers.c new file mode 100644 index 000000000000..4fa655d68a81 --- /dev/null +++ b/tools/testing/selftests/timers/posix_timers.c | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Red Hat, Inc., Frederic Weisbecker <fweisbec@redhat.com> | ||
3 | * | ||
4 | * Licensed under the terms of the GNU GPL License version 2 | ||
5 | * | ||
6 | * Selftests for a few posix timers interface. | ||
7 | * | ||
8 | * Kernel loop code stolen from Steven Rostedt <srostedt@redhat.com> | ||
9 | */ | ||
10 | |||
11 | #include <sys/time.h> | ||
12 | #include <stdio.h> | ||
13 | #include <signal.h> | ||
14 | #include <unistd.h> | ||
15 | #include <time.h> | ||
16 | #include <pthread.h> | ||
17 | |||
18 | #define DELAY 2 | ||
19 | #define USECS_PER_SEC 1000000 | ||
20 | |||
21 | static volatile int done; | ||
22 | |||
23 | /* Busy loop in userspace to elapse ITIMER_VIRTUAL */ | ||
24 | static void user_loop(void) | ||
25 | { | ||
26 | while (!done); | ||
27 | } | ||
28 | |||
29 | /* | ||
30 | * Try to spend as much time as possible in kernelspace | ||
31 | * to elapse ITIMER_PROF. | ||
32 | */ | ||
33 | static void kernel_loop(void) | ||
34 | { | ||
35 | void *addr = sbrk(0); | ||
36 | |||
37 | while (!done) { | ||
38 | brk(addr + 4096); | ||
39 | brk(addr); | ||
40 | } | ||
41 | } | ||
42 | |||
43 | /* | ||
44 | * Sleep until ITIMER_REAL expiration. | ||
45 | */ | ||
46 | static void idle_loop(void) | ||
47 | { | ||
48 | pause(); | ||
49 | } | ||
50 | |||
51 | static void sig_handler(int nr) | ||
52 | { | ||
53 | done = 1; | ||
54 | } | ||
55 | |||
56 | /* | ||
57 | * Check the expected timer expiration matches the GTOD elapsed delta since | ||
58 | * we armed the timer. Keep a 0.5 sec error margin due to various jitter. | ||
59 | */ | ||
60 | static int check_diff(struct timeval start, struct timeval end) | ||
61 | { | ||
62 | long long diff; | ||
63 | |||
64 | diff = end.tv_usec - start.tv_usec; | ||
65 | diff += (end.tv_sec - start.tv_sec) * USECS_PER_SEC; | ||
66 | |||
67 | if (abs(diff - DELAY * USECS_PER_SEC) > USECS_PER_SEC / 2) { | ||
68 | printf("Diff too high: %lld..", diff); | ||
69 | return -1; | ||
70 | } | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static int check_itimer(int which) | ||
76 | { | ||
77 | int err; | ||
78 | struct timeval start, end; | ||
79 | struct itimerval val = { | ||
80 | .it_value.tv_sec = DELAY, | ||
81 | }; | ||
82 | |||
83 | printf("Check itimer "); | ||
84 | |||
85 | if (which == ITIMER_VIRTUAL) | ||
86 | printf("virtual... "); | ||
87 | else if (which == ITIMER_PROF) | ||
88 | printf("prof... "); | ||
89 | else if (which == ITIMER_REAL) | ||
90 | printf("real... "); | ||
91 | |||
92 | fflush(stdout); | ||
93 | |||
94 | done = 0; | ||
95 | |||
96 | if (which == ITIMER_VIRTUAL) | ||
97 | signal(SIGVTALRM, sig_handler); | ||
98 | else if (which == ITIMER_PROF) | ||
99 | signal(SIGPROF, sig_handler); | ||
100 | else if (which == ITIMER_REAL) | ||
101 | signal(SIGALRM, sig_handler); | ||
102 | |||
103 | err = gettimeofday(&start, NULL); | ||
104 | if (err < 0) { | ||
105 | perror("Can't call gettimeofday()\n"); | ||
106 | return -1; | ||
107 | } | ||
108 | |||
109 | err = setitimer(which, &val, NULL); | ||
110 | if (err < 0) { | ||
111 | perror("Can't set timer\n"); | ||
112 | return -1; | ||
113 | } | ||
114 | |||
115 | if (which == ITIMER_VIRTUAL) | ||
116 | user_loop(); | ||
117 | else if (which == ITIMER_PROF) | ||
118 | kernel_loop(); | ||
119 | else if (which == ITIMER_REAL) | ||
120 | idle_loop(); | ||
121 | |||
122 | gettimeofday(&end, NULL); | ||
123 | if (err < 0) { | ||
124 | perror("Can't call gettimeofday()\n"); | ||
125 | return -1; | ||
126 | } | ||
127 | |||
128 | if (!check_diff(start, end)) | ||
129 | printf("[OK]\n"); | ||
130 | else | ||
131 | printf("[FAIL]\n"); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int check_timer_create(int which) | ||
137 | { | ||
138 | int err; | ||
139 | timer_t id; | ||
140 | struct timeval start, end; | ||
141 | struct itimerspec val = { | ||
142 | .it_value.tv_sec = DELAY, | ||
143 | }; | ||
144 | |||
145 | printf("Check timer_create() "); | ||
146 | if (which == CLOCK_THREAD_CPUTIME_ID) { | ||
147 | printf("per thread... "); | ||
148 | } else if (which == CLOCK_PROCESS_CPUTIME_ID) { | ||
149 | printf("per process... "); | ||
150 | } | ||
151 | fflush(stdout); | ||
152 | |||
153 | done = 0; | ||
154 | timer_create(which, NULL, &id); | ||
155 | if (err < 0) { | ||
156 | perror("Can't create timer\n"); | ||
157 | return -1; | ||
158 | } | ||
159 | signal(SIGALRM, sig_handler); | ||
160 | |||
161 | err = gettimeofday(&start, NULL); | ||
162 | if (err < 0) { | ||
163 | perror("Can't call gettimeofday()\n"); | ||
164 | return -1; | ||
165 | } | ||
166 | |||
167 | err = timer_settime(id, 0, &val, NULL); | ||
168 | if (err < 0) { | ||
169 | perror("Can't set timer\n"); | ||
170 | return -1; | ||
171 | } | ||
172 | |||
173 | user_loop(); | ||
174 | |||
175 | gettimeofday(&end, NULL); | ||
176 | if (err < 0) { | ||
177 | perror("Can't call gettimeofday()\n"); | ||
178 | return -1; | ||
179 | } | ||
180 | |||
181 | if (!check_diff(start, end)) | ||
182 | printf("[OK]\n"); | ||
183 | else | ||
184 | printf("[FAIL]\n"); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | int main(int argc, char **argv) | ||
190 | { | ||
191 | int err; | ||
192 | |||
193 | printf("Testing posix timers. False negative may happen on CPU execution \n"); | ||
194 | printf("based timers if other threads run on the CPU...\n"); | ||
195 | |||
196 | if (check_itimer(ITIMER_VIRTUAL) < 0) | ||
197 | return -1; | ||
198 | |||
199 | if (check_itimer(ITIMER_PROF) < 0) | ||
200 | return -1; | ||
201 | |||
202 | if (check_itimer(ITIMER_REAL) < 0) | ||
203 | return -1; | ||
204 | |||
205 | if (check_timer_create(CLOCK_THREAD_CPUTIME_ID) < 0) | ||
206 | return -1; | ||
207 | |||
208 | /* | ||
209 | * It's unfortunately hard to reliably test a timer expiration | ||
210 | * on parallel multithread cputime. We could arm it to expire | ||
211 | * on DELAY * nr_threads, with nr_threads busy looping, then wait | ||
212 | * the normal DELAY since the time is elapsing nr_threads faster. | ||
213 | * But for that we need to ensure we have real physical free CPUs | ||
214 | * to ensure true parallelism. So test only one thread until we | ||
215 | * find a better solution. | ||
216 | */ | ||
217 | if (check_timer_create(CLOCK_PROCESS_CPUTIME_ID) < 0) | ||
218 | return -1; | ||
219 | |||
220 | return 0; | ||
221 | } | ||