aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-record.txt3
-rw-r--r--tools/perf/Makefile2
-rw-r--r--tools/perf/arch/s390/Makefile4
-rw-r--r--tools/perf/arch/s390/util/dwarf-regs.c22
-rw-r--r--tools/perf/builtin-record.c9
-rw-r--r--tools/perf/builtin-sched.c23
-rw-r--r--tools/perf/builtin-stat.c6
-rw-r--r--tools/perf/builtin-test.c116
-rw-r--r--tools/perf/builtin-top.c3
-rw-r--r--tools/perf/perf.c2
-rw-r--r--tools/perf/util/evsel.c87
-rw-r--r--tools/perf/util/evsel.h2
-rw-r--r--tools/perf/util/parse-events.c74
-rw-r--r--tools/perf/util/session.c2
-rw-r--r--tools/power/x86/turbostat/Makefile8
-rw-r--r--tools/power/x86/turbostat/turbostat.8172
-rw-r--r--tools/power/x86/turbostat/turbostat.c1048
-rw-r--r--tools/power/x86/x86_energy_perf_policy/Makefile8
-rw-r--r--tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8104
-rw-r--r--tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c325
-rw-r--r--tools/slub/slabinfo.c1364
-rwxr-xr-xtools/testing/ktest/compare-ktest-sample.pl30
-rwxr-xr-xtools/testing/ktest/ktest.pl2023
-rw-r--r--tools/testing/ktest/sample.conf622
-rw-r--r--tools/virtio/Makefile12
-rw-r--r--tools/virtio/linux/device.h2
-rw-r--r--tools/virtio/linux/slab.h2
-rw-r--r--tools/virtio/linux/virtio.h223
-rw-r--r--tools/virtio/vhost_test/Makefile2
-rw-r--r--tools/virtio/vhost_test/vhost_test.c1
-rw-r--r--tools/virtio/virtio_test.c248
31 files changed, 6460 insertions, 89 deletions
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 52462ae26455..e032716c839b 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -61,6 +61,9 @@ OPTIONS
61-r:: 61-r::
62--realtime=:: 62--realtime=::
63 Collect data with this RT SCHED_FIFO priority. 63 Collect data with this RT SCHED_FIFO priority.
64-D::
65--no-delay::
66 Collect data without buffering.
64-A:: 67-A::
65--append:: 68--append::
66 Append to the output file to do incremental profiling. 69 Append to the output file to do incremental profiling.
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 1b9b13ee2a72..2b5387d53ba5 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -227,7 +227,7 @@ ifndef PERF_DEBUG
227 CFLAGS_OPTIMIZE = -O6 227 CFLAGS_OPTIMIZE = -O6
228endif 228endif
229 229
230CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) 230CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 -Werror $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
231EXTLIBS = -lpthread -lrt -lelf -lm 231EXTLIBS = -lpthread -lrt -lelf -lm
232ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 232ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
233ALL_LDFLAGS = $(LDFLAGS) 233ALL_LDFLAGS = $(LDFLAGS)
diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile
new file mode 100644
index 000000000000..15130b50dfe3
--- /dev/null
+++ b/tools/perf/arch/s390/Makefile
@@ -0,0 +1,4 @@
1ifndef NO_DWARF
2PERF_HAVE_DWARF_REGS := 1
3LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
4endif
diff --git a/tools/perf/arch/s390/util/dwarf-regs.c b/tools/perf/arch/s390/util/dwarf-regs.c
new file mode 100644
index 000000000000..e19653e025fa
--- /dev/null
+++ b/tools/perf/arch/s390/util/dwarf-regs.c
@@ -0,0 +1,22 @@
1/*
2 * Mapping of DWARF debug register numbers into register names.
3 *
4 * Copyright IBM Corp. 2010
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
6 *
7 */
8
9#include <libio.h>
10#include <dwarf-regs.h>
11
12#define NUM_GPRS 16
13
14static const char *gpr_names[NUM_GPRS] = {
15 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
16 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
17};
18
19const char *get_arch_regstr(unsigned int n)
20{
21 return (n >= NUM_GPRS) ? NULL : gpr_names[n];
22}
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 7bc049035484..df6064ad9bf2 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -49,6 +49,7 @@ static int pipe_output = 0;
49static const char *output_name = "perf.data"; 49static const char *output_name = "perf.data";
50static int group = 0; 50static int group = 0;
51static int realtime_prio = 0; 51static int realtime_prio = 0;
52static bool nodelay = false;
52static bool raw_samples = false; 53static bool raw_samples = false;
53static bool sample_id_all_avail = true; 54static bool sample_id_all_avail = true;
54static bool system_wide = false; 55static bool system_wide = false;
@@ -307,6 +308,11 @@ static void create_counter(struct perf_evsel *evsel, int cpu)
307 attr->sample_type |= PERF_SAMPLE_CPU; 308 attr->sample_type |= PERF_SAMPLE_CPU;
308 } 309 }
309 310
311 if (nodelay) {
312 attr->watermark = 0;
313 attr->wakeup_events = 1;
314 }
315
310 attr->mmap = track; 316 attr->mmap = track;
311 attr->comm = track; 317 attr->comm = track;
312 attr->inherit = !no_inherit; 318 attr->inherit = !no_inherit;
@@ -477,6 +483,7 @@ static void atexit_header(void)
477 process_buildids(); 483 process_buildids();
478 perf_header__write(&session->header, output, true); 484 perf_header__write(&session->header, output, true);
479 perf_session__delete(session); 485 perf_session__delete(session);
486 perf_evsel_list__delete();
480 symbol__exit(); 487 symbol__exit();
481 } 488 }
482} 489}
@@ -842,6 +849,8 @@ const struct option record_options[] = {
842 "record events on existing thread id"), 849 "record events on existing thread id"),
843 OPT_INTEGER('r', "realtime", &realtime_prio, 850 OPT_INTEGER('r', "realtime", &realtime_prio,
844 "collect data with this RT SCHED_FIFO priority"), 851 "collect data with this RT SCHED_FIFO priority"),
852 OPT_BOOLEAN('D', "no-delay", &nodelay,
853 "collect data without buffering"),
845 OPT_BOOLEAN('R', "raw-samples", &raw_samples, 854 OPT_BOOLEAN('R', "raw-samples", &raw_samples,
846 "collect raw sample records from all opened counters"), 855 "collect raw sample records from all opened counters"),
847 OPT_BOOLEAN('a', "all-cpus", &system_wide, 856 OPT_BOOLEAN('a', "all-cpus", &system_wide,
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 7a4ebeb8b016..29e7ffd85690 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -489,7 +489,8 @@ static void create_tasks(void)
489 489
490 err = pthread_attr_init(&attr); 490 err = pthread_attr_init(&attr);
491 BUG_ON(err); 491 BUG_ON(err);
492 err = pthread_attr_setstacksize(&attr, (size_t)(16*1024)); 492 err = pthread_attr_setstacksize(&attr,
493 (size_t) max(16 * 1024, PTHREAD_STACK_MIN));
493 BUG_ON(err); 494 BUG_ON(err);
494 err = pthread_mutex_lock(&start_work_mutex); 495 err = pthread_mutex_lock(&start_work_mutex);
495 BUG_ON(err); 496 BUG_ON(err);
@@ -1842,15 +1843,15 @@ static const char *record_args[] = {
1842 "-f", 1843 "-f",
1843 "-m", "1024", 1844 "-m", "1024",
1844 "-c", "1", 1845 "-c", "1",
1845 "-e", "sched:sched_switch:r", 1846 "-e", "sched:sched_switch",
1846 "-e", "sched:sched_stat_wait:r", 1847 "-e", "sched:sched_stat_wait",
1847 "-e", "sched:sched_stat_sleep:r", 1848 "-e", "sched:sched_stat_sleep",
1848 "-e", "sched:sched_stat_iowait:r", 1849 "-e", "sched:sched_stat_iowait",
1849 "-e", "sched:sched_stat_runtime:r", 1850 "-e", "sched:sched_stat_runtime",
1850 "-e", "sched:sched_process_exit:r", 1851 "-e", "sched:sched_process_exit",
1851 "-e", "sched:sched_process_fork:r", 1852 "-e", "sched:sched_process_fork",
1852 "-e", "sched:sched_wakeup:r", 1853 "-e", "sched:sched_wakeup",
1853 "-e", "sched:sched_migrate_task:r", 1854 "-e", "sched:sched_migrate_task",
1854}; 1855};
1855 1856
1856static int __cmd_record(int argc, const char **argv) 1857static int __cmd_record(int argc, const char **argv)
@@ -1861,7 +1862,7 @@ static int __cmd_record(int argc, const char **argv)
1861 rec_argc = ARRAY_SIZE(record_args) + argc - 1; 1862 rec_argc = ARRAY_SIZE(record_args) + argc - 1;
1862 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 1863 rec_argv = calloc(rec_argc + 1, sizeof(char *));
1863 1864
1864 if (rec_argv) 1865 if (rec_argv == NULL)
1865 return -ENOMEM; 1866 return -ENOMEM;
1866 1867
1867 for (i = 0; i < ARRAY_SIZE(record_args); i++) 1868 for (i = 0; i < ARRAY_SIZE(record_args); i++)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 02b2d8013a61..0ff11d9b13be 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -316,6 +316,8 @@ static int run_perf_stat(int argc __used, const char **argv)
316 "\t Consider tweaking" 316 "\t Consider tweaking"
317 " /proc/sys/kernel/perf_event_paranoid or running as root.", 317 " /proc/sys/kernel/perf_event_paranoid or running as root.",
318 system_wide ? "system-wide " : ""); 318 system_wide ? "system-wide " : "");
319 } else if (errno == ENOENT) {
320 error("%s event is not supported. ", event_name(counter));
319 } else { 321 } else {
320 error("open_counter returned with %d (%s). " 322 error("open_counter returned with %d (%s). "
321 "/bin/dmesg may provide additional information.\n", 323 "/bin/dmesg may provide additional information.\n",
@@ -683,8 +685,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
683 nr_counters = ARRAY_SIZE(default_attrs); 685 nr_counters = ARRAY_SIZE(default_attrs);
684 686
685 for (c = 0; c < ARRAY_SIZE(default_attrs); ++c) { 687 for (c = 0; c < ARRAY_SIZE(default_attrs); ++c) {
686 pos = perf_evsel__new(default_attrs[c].type, 688 pos = perf_evsel__new(&default_attrs[c],
687 default_attrs[c].config,
688 nr_counters); 689 nr_counters);
689 if (pos == NULL) 690 if (pos == NULL)
690 goto out; 691 goto out;
@@ -742,6 +743,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
742out_free_fd: 743out_free_fd:
743 list_for_each_entry(pos, &evsel_list, node) 744 list_for_each_entry(pos, &evsel_list, node)
744 perf_evsel__free_stat_priv(pos); 745 perf_evsel__free_stat_priv(pos);
746 perf_evsel_list__delete();
745out: 747out:
746 thread_map__delete(threads); 748 thread_map__delete(threads);
747 threads = NULL; 749 threads = NULL;
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 1c984342a579..ed5696198d3d 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -234,6 +234,7 @@ out:
234 return err; 234 return err;
235} 235}
236 236
237#include "util/cpumap.h"
237#include "util/evsel.h" 238#include "util/evsel.h"
238#include <sys/types.h> 239#include <sys/types.h>
239 240
@@ -264,6 +265,7 @@ static int test__open_syscall_event(void)
264 int err = -1, fd; 265 int err = -1, fd;
265 struct thread_map *threads; 266 struct thread_map *threads;
266 struct perf_evsel *evsel; 267 struct perf_evsel *evsel;
268 struct perf_event_attr attr;
267 unsigned int nr_open_calls = 111, i; 269 unsigned int nr_open_calls = 111, i;
268 int id = trace_event__id("sys_enter_open"); 270 int id = trace_event__id("sys_enter_open");
269 271
@@ -278,7 +280,10 @@ static int test__open_syscall_event(void)
278 return -1; 280 return -1;
279 } 281 }
280 282
281 evsel = perf_evsel__new(PERF_TYPE_TRACEPOINT, id, 0); 283 memset(&attr, 0, sizeof(attr));
284 attr.type = PERF_TYPE_TRACEPOINT;
285 attr.config = id;
286 evsel = perf_evsel__new(&attr, 0);
282 if (evsel == NULL) { 287 if (evsel == NULL) {
283 pr_debug("perf_evsel__new\n"); 288 pr_debug("perf_evsel__new\n");
284 goto out_thread_map_delete; 289 goto out_thread_map_delete;
@@ -317,6 +322,111 @@ out_thread_map_delete:
317 return err; 322 return err;
318} 323}
319 324
325#include <sched.h>
326
327static int test__open_syscall_event_on_all_cpus(void)
328{
329 int err = -1, fd, cpu;
330 struct thread_map *threads;
331 struct cpu_map *cpus;
332 struct perf_evsel *evsel;
333 struct perf_event_attr attr;
334 unsigned int nr_open_calls = 111, i;
335 cpu_set_t *cpu_set;
336 size_t cpu_set_size;
337 int id = trace_event__id("sys_enter_open");
338
339 if (id < 0) {
340 pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
341 return -1;
342 }
343
344 threads = thread_map__new(-1, getpid());
345 if (threads == NULL) {
346 pr_debug("thread_map__new\n");
347 return -1;
348 }
349
350 cpus = cpu_map__new(NULL);
351 if (threads == NULL) {
352 pr_debug("thread_map__new\n");
353 return -1;
354 }
355
356 cpu_set = CPU_ALLOC(cpus->nr);
357
358 if (cpu_set == NULL)
359 goto out_thread_map_delete;
360
361 cpu_set_size = CPU_ALLOC_SIZE(cpus->nr);
362 CPU_ZERO_S(cpu_set_size, cpu_set);
363
364 memset(&attr, 0, sizeof(attr));
365 attr.type = PERF_TYPE_TRACEPOINT;
366 attr.config = id;
367 evsel = perf_evsel__new(&attr, 0);
368 if (evsel == NULL) {
369 pr_debug("perf_evsel__new\n");
370 goto out_cpu_free;
371 }
372
373 if (perf_evsel__open(evsel, cpus, threads) < 0) {
374 pr_debug("failed to open counter: %s, "
375 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
376 strerror(errno));
377 goto out_evsel_delete;
378 }
379
380 for (cpu = 0; cpu < cpus->nr; ++cpu) {
381 unsigned int ncalls = nr_open_calls + cpu;
382
383 CPU_SET(cpu, cpu_set);
384 sched_setaffinity(0, cpu_set_size, cpu_set);
385 for (i = 0; i < ncalls; ++i) {
386 fd = open("/etc/passwd", O_RDONLY);
387 close(fd);
388 }
389 CPU_CLR(cpu, cpu_set);
390 }
391
392 /*
393 * Here we need to explicitely preallocate the counts, as if
394 * we use the auto allocation it will allocate just for 1 cpu,
395 * as we start by cpu 0.
396 */
397 if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) {
398 pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr);
399 goto out_close_fd;
400 }
401
402 for (cpu = 0; cpu < cpus->nr; ++cpu) {
403 unsigned int expected;
404
405 if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) {
406 pr_debug("perf_evsel__open_read_on_cpu\n");
407 goto out_close_fd;
408 }
409
410 expected = nr_open_calls + cpu;
411 if (evsel->counts->cpu[cpu].val != expected) {
412 pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %Ld\n",
413 expected, cpu, evsel->counts->cpu[cpu].val);
414 goto out_close_fd;
415 }
416 }
417
418 err = 0;
419out_close_fd:
420 perf_evsel__close_fd(evsel, 1, threads->nr);
421out_evsel_delete:
422 perf_evsel__delete(evsel);
423out_cpu_free:
424 CPU_FREE(cpu_set);
425out_thread_map_delete:
426 thread_map__delete(threads);
427 return err;
428}
429
320static struct test { 430static struct test {
321 const char *desc; 431 const char *desc;
322 int (*func)(void); 432 int (*func)(void);
@@ -330,6 +440,10 @@ static struct test {
330 .func = test__open_syscall_event, 440 .func = test__open_syscall_event,
331 }, 441 },
332 { 442 {
443 .desc = "detect open syscall event on all cpus",
444 .func = test__open_syscall_event_on_all_cpus,
445 },
446 {
333 .func = NULL, 447 .func = NULL,
334 }, 448 },
335}; 449};
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 1e67ab9c7ebc..05344c6210ac 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1471,6 +1471,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1471 pos->attr.sample_period = default_interval; 1471 pos->attr.sample_period = default_interval;
1472 } 1472 }
1473 1473
1474 sym_evsel = list_entry(evsel_list.next, struct perf_evsel, node);
1475
1474 symbol_conf.priv_size = (sizeof(struct sym_entry) + 1476 symbol_conf.priv_size = (sizeof(struct sym_entry) +
1475 (nr_counters + 1) * sizeof(unsigned long)); 1477 (nr_counters + 1) * sizeof(unsigned long));
1476 1478
@@ -1488,6 +1490,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1488out_free_fd: 1490out_free_fd:
1489 list_for_each_entry(pos, &evsel_list, node) 1491 list_for_each_entry(pos, &evsel_list, node)
1490 perf_evsel__free_mmap(pos); 1492 perf_evsel__free_mmap(pos);
1493 perf_evsel_list__delete();
1491 1494
1492 return status; 1495 return status;
1493} 1496}
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 5b1ecd66bb36..595d0f4a7103 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -286,8 +286,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
286 status = p->fn(argc, argv, prefix); 286 status = p->fn(argc, argv, prefix);
287 exit_browser(status); 287 exit_browser(status);
288 288
289 perf_evsel_list__delete();
290
291 if (status) 289 if (status)
292 return status & 0xff; 290 return status & 0xff;
293 291
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index c95267e63c5b..f5cfed60af98 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -6,14 +6,13 @@
6 6
7#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 7#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
8 8
9struct perf_evsel *perf_evsel__new(u32 type, u64 config, int idx) 9struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
10{ 10{
11 struct perf_evsel *evsel = zalloc(sizeof(*evsel)); 11 struct perf_evsel *evsel = zalloc(sizeof(*evsel));
12 12
13 if (evsel != NULL) { 13 if (evsel != NULL) {
14 evsel->idx = idx; 14 evsel->idx = idx;
15 evsel->attr.type = type; 15 evsel->attr = *attr;
16 evsel->attr.config = config;
17 INIT_LIST_HEAD(&evsel->node); 16 INIT_LIST_HEAD(&evsel->node);
18 } 17 }
19 18
@@ -128,59 +127,75 @@ int __perf_evsel__read(struct perf_evsel *evsel,
128 return 0; 127 return 0;
129} 128}
130 129
131int perf_evsel__open_per_cpu(struct perf_evsel *evsel, struct cpu_map *cpus) 130static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
131 struct thread_map *threads)
132{ 132{
133 int cpu; 133 int cpu, thread;
134 134
135 if (evsel->fd == NULL && perf_evsel__alloc_fd(evsel, cpus->nr, 1) < 0) 135 if (evsel->fd == NULL &&
136 perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0)
136 return -1; 137 return -1;
137 138
138 for (cpu = 0; cpu < cpus->nr; cpu++) { 139 for (cpu = 0; cpu < cpus->nr; cpu++) {
139 FD(evsel, cpu, 0) = sys_perf_event_open(&evsel->attr, -1, 140 for (thread = 0; thread < threads->nr; thread++) {
140 cpus->map[cpu], -1, 0); 141 FD(evsel, cpu, thread) = sys_perf_event_open(&evsel->attr,
141 if (FD(evsel, cpu, 0) < 0) 142 threads->map[thread],
142 goto out_close; 143 cpus->map[cpu], -1, 0);
144 if (FD(evsel, cpu, thread) < 0)
145 goto out_close;
146 }
143 } 147 }
144 148
145 return 0; 149 return 0;
146 150
147out_close: 151out_close:
148 while (--cpu >= 0) { 152 do {
149 close(FD(evsel, cpu, 0)); 153 while (--thread >= 0) {
150 FD(evsel, cpu, 0) = -1; 154 close(FD(evsel, cpu, thread));
151 } 155 FD(evsel, cpu, thread) = -1;
156 }
157 thread = threads->nr;
158 } while (--cpu >= 0);
152 return -1; 159 return -1;
153} 160}
154 161
155int perf_evsel__open_per_thread(struct perf_evsel *evsel, struct thread_map *threads) 162static struct {
163 struct cpu_map map;
164 int cpus[1];
165} empty_cpu_map = {
166 .map.nr = 1,
167 .cpus = { -1, },
168};
169
170static struct {
171 struct thread_map map;
172 int threads[1];
173} empty_thread_map = {
174 .map.nr = 1,
175 .threads = { -1, },
176};
177
178int perf_evsel__open(struct perf_evsel *evsel,
179 struct cpu_map *cpus, struct thread_map *threads)
156{ 180{
157 int thread;
158
159 if (evsel->fd == NULL && perf_evsel__alloc_fd(evsel, 1, threads->nr))
160 return -1;
161 181
162 for (thread = 0; thread < threads->nr; thread++) { 182 if (cpus == NULL) {
163 FD(evsel, 0, thread) = sys_perf_event_open(&evsel->attr, 183 /* Work around old compiler warnings about strict aliasing */
164 threads->map[thread], -1, -1, 0); 184 cpus = &empty_cpu_map.map;
165 if (FD(evsel, 0, thread) < 0)
166 goto out_close;
167 } 185 }
168 186
169 return 0; 187 if (threads == NULL)
188 threads = &empty_thread_map.map;
170 189
171out_close: 190 return __perf_evsel__open(evsel, cpus, threads);
172 while (--thread >= 0) {
173 close(FD(evsel, 0, thread));
174 FD(evsel, 0, thread) = -1;
175 }
176 return -1;
177} 191}
178 192
179int perf_evsel__open(struct perf_evsel *evsel, 193int perf_evsel__open_per_cpu(struct perf_evsel *evsel, struct cpu_map *cpus)
180 struct cpu_map *cpus, struct thread_map *threads)
181{ 194{
182 if (threads == NULL) 195 return __perf_evsel__open(evsel, cpus, &empty_thread_map.map);
183 return perf_evsel__open_per_cpu(evsel, cpus); 196}
184 197
185 return perf_evsel__open_per_thread(evsel, threads); 198int perf_evsel__open_per_thread(struct perf_evsel *evsel, struct thread_map *threads)
199{
200 return __perf_evsel__open(evsel, &empty_cpu_map.map, threads);
186} 201}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index a0ccd69c3fc2..b2d755fe88a5 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -37,7 +37,7 @@ struct perf_evsel {
37struct cpu_map; 37struct cpu_map;
38struct thread_map; 38struct thread_map;
39 39
40struct perf_evsel *perf_evsel__new(u32 type, u64 config, int idx); 40struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx);
41void perf_evsel__delete(struct perf_evsel *evsel); 41void perf_evsel__delete(struct perf_evsel *evsel);
42 42
43int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); 43int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 649083f27e08..5cb6f4bde905 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -490,6 +490,31 @@ parse_multiple_tracepoint_event(char *sys_name, const char *evt_exp,
490 return EVT_HANDLED_ALL; 490 return EVT_HANDLED_ALL;
491} 491}
492 492
493static int store_event_type(const char *orgname)
494{
495 char filename[PATH_MAX], *c;
496 FILE *file;
497 int id, n;
498
499 sprintf(filename, "%s/", debugfs_path);
500 strncat(filename, orgname, strlen(orgname));
501 strcat(filename, "/id");
502
503 c = strchr(filename, ':');
504 if (c)
505 *c = '/';
506
507 file = fopen(filename, "r");
508 if (!file)
509 return 0;
510 n = fscanf(file, "%i", &id);
511 fclose(file);
512 if (n < 1) {
513 pr_err("cannot store event ID\n");
514 return -EINVAL;
515 }
516 return perf_header__push_event(id, orgname);
517}
493 518
494static enum event_result parse_tracepoint_event(const char **strp, 519static enum event_result parse_tracepoint_event(const char **strp,
495 struct perf_event_attr *attr) 520 struct perf_event_attr *attr)
@@ -533,9 +558,13 @@ static enum event_result parse_tracepoint_event(const char **strp,
533 *strp += strlen(sys_name) + evt_length; 558 *strp += strlen(sys_name) + evt_length;
534 return parse_multiple_tracepoint_event(sys_name, evt_name, 559 return parse_multiple_tracepoint_event(sys_name, evt_name,
535 flags); 560 flags);
536 } else 561 } else {
562 if (store_event_type(evt_name) < 0)
563 return EVT_FAILED;
564
537 return parse_single_tracepoint_event(sys_name, evt_name, 565 return parse_single_tracepoint_event(sys_name, evt_name,
538 evt_length, attr, strp); 566 evt_length, attr, strp);
567 }
539} 568}
540 569
541static enum event_result 570static enum event_result
@@ -778,41 +807,11 @@ modifier:
778 return ret; 807 return ret;
779} 808}
780 809
781static int store_event_type(const char *orgname)
782{
783 char filename[PATH_MAX], *c;
784 FILE *file;
785 int id, n;
786
787 sprintf(filename, "%s/", debugfs_path);
788 strncat(filename, orgname, strlen(orgname));
789 strcat(filename, "/id");
790
791 c = strchr(filename, ':');
792 if (c)
793 *c = '/';
794
795 file = fopen(filename, "r");
796 if (!file)
797 return 0;
798 n = fscanf(file, "%i", &id);
799 fclose(file);
800 if (n < 1) {
801 pr_err("cannot store event ID\n");
802 return -EINVAL;
803 }
804 return perf_header__push_event(id, orgname);
805}
806
807int parse_events(const struct option *opt __used, const char *str, int unset __used) 810int parse_events(const struct option *opt __used, const char *str, int unset __used)
808{ 811{
809 struct perf_event_attr attr; 812 struct perf_event_attr attr;
810 enum event_result ret; 813 enum event_result ret;
811 814
812 if (strchr(str, ':'))
813 if (store_event_type(str) < 0)
814 return -1;
815
816 for (;;) { 815 for (;;) {
817 memset(&attr, 0, sizeof(attr)); 816 memset(&attr, 0, sizeof(attr));
818 ret = parse_event_symbols(&str, &attr); 817 ret = parse_event_symbols(&str, &attr);
@@ -824,7 +823,7 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u
824 823
825 if (ret != EVT_HANDLED_ALL) { 824 if (ret != EVT_HANDLED_ALL) {
826 struct perf_evsel *evsel; 825 struct perf_evsel *evsel;
827 evsel = perf_evsel__new(attr.type, attr.config, 826 evsel = perf_evsel__new(&attr,
828 nr_counters); 827 nr_counters);
829 if (evsel == NULL) 828 if (evsel == NULL)
830 return -1; 829 return -1;
@@ -1014,8 +1013,15 @@ void print_events(void)
1014 1013
1015int perf_evsel_list__create_default(void) 1014int perf_evsel_list__create_default(void)
1016{ 1015{
1017 struct perf_evsel *evsel = perf_evsel__new(PERF_TYPE_HARDWARE, 1016 struct perf_evsel *evsel;
1018 PERF_COUNT_HW_CPU_CYCLES, 0); 1017 struct perf_event_attr attr;
1018
1019 memset(&attr, 0, sizeof(attr));
1020 attr.type = PERF_TYPE_HARDWARE;
1021 attr.config = PERF_COUNT_HW_CPU_CYCLES;
1022
1023 evsel = perf_evsel__new(&attr, 0);
1024
1019 if (evsel == NULL) 1025 if (evsel == NULL)
1020 return -ENOMEM; 1026 return -ENOMEM;
1021 1027
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 6fb4694d05fa..313dac2d94ce 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1007,7 +1007,7 @@ more:
1007 if (size == 0) 1007 if (size == 0)
1008 size = 8; 1008 size = 8;
1009 1009
1010 if (head + event->header.size >= mmap_size) { 1010 if (head + event->header.size > mmap_size) {
1011 if (mmaps[map_idx]) { 1011 if (mmaps[map_idx]) {
1012 munmap(mmaps[map_idx], mmap_size); 1012 munmap(mmaps[map_idx], mmap_size);
1013 mmaps[map_idx] = NULL; 1013 mmaps[map_idx] = NULL;
diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile
new file mode 100644
index 000000000000..fd8e1f1297aa
--- /dev/null
+++ b/tools/power/x86/turbostat/Makefile
@@ -0,0 +1,8 @@
1turbostat : turbostat.c
2
3clean :
4 rm -f turbostat
5
6install :
7 install turbostat /usr/bin/turbostat
8 install turbostat.8 /usr/share/man/man8
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8
new file mode 100644
index 000000000000..ff75125deed0
--- /dev/null
+++ b/tools/power/x86/turbostat/turbostat.8
@@ -0,0 +1,172 @@
1.TH TURBOSTAT 8
2.SH NAME
3turbostat \- Report processor frequency and idle statistics
4.SH SYNOPSIS
5.ft B
6.B turbostat
7.RB [ "\-v" ]
8.RB [ "\-M MSR#" ]
9.RB command
10.br
11.B turbostat
12.RB [ "\-v" ]
13.RB [ "\-M MSR#" ]
14.RB [ "\-i interval_sec" ]
15.SH DESCRIPTION
16\fBturbostat \fP reports processor topology, frequency
17and idle power state statistics on modern X86 processors.
18Either \fBcommand\fP is forked and statistics are printed
19upon its completion, or statistics are printed periodically.
20
21\fBturbostat \fP
22requires that the processor
23supports an "invariant" TSC, plus the APERF and MPERF MSRs.
24\fBturbostat \fP will report idle cpu power state residency
25on processors that additionally support C-state residency counters.
26
27.SS Options
28The \fB-v\fP option increases verbosity.
29.PP
30The \fB-M MSR#\fP option dumps the specified MSR,
31in addition to the usual frequency and idle statistics.
32.PP
33The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds.
34The default is 5 seconds.
35.PP
36The \fBcommand\fP parameter forks \fBcommand\fP and upon its exit,
37displays the statistics gathered since it was forked.
38.PP
39.SH FIELD DESCRIPTIONS
40.nf
41\fBpkg\fP processor package number.
42\fBcore\fP processor core number.
43\fBCPU\fP Linux CPU (logical processor) number.
44\fB%c0\fP percent of the interval that the CPU retired instructions.
45\fBGHz\fP average clock rate while the CPU was in c0 state.
46\fBTSC\fP average GHz that the TSC ran during the entire interval.
47\fB%c1, %c3, %c6\fP show the percentage residency in hardware core idle states.
48\fB%pc3, %pc6\fP percentage residency in hardware package idle states.
49.fi
50.PP
51.SH EXAMPLE
52Without any parameters, turbostat prints out counters ever 5 seconds.
53(override interval with "-i sec" option, or specify a command
54for turbostat to fork).
55
56The first row of statistics reflect the average for the entire system.
57Subsequent rows show per-CPU statistics.
58
59.nf
60[root@x980]# ./turbostat
61core CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6
62 0.04 1.62 3.38 0.11 0.00 99.85 0.00 95.07
63 0 0 0.04 1.62 3.38 0.06 0.00 99.90 0.00 95.07
64 0 6 0.02 1.62 3.38 0.08 0.00 99.90 0.00 95.07
65 1 2 0.10 1.62 3.38 0.29 0.00 99.61 0.00 95.07
66 1 8 0.11 1.62 3.38 0.28 0.00 99.61 0.00 95.07
67 2 4 0.01 1.62 3.38 0.01 0.00 99.98 0.00 95.07
68 2 10 0.01 1.61 3.38 0.02 0.00 99.98 0.00 95.07
69 8 1 0.07 1.62 3.38 0.15 0.00 99.78 0.00 95.07
70 8 7 0.03 1.62 3.38 0.19 0.00 99.78 0.00 95.07
71 9 3 0.01 1.62 3.38 0.02 0.00 99.98 0.00 95.07
72 9 9 0.01 1.62 3.38 0.02 0.00 99.98 0.00 95.07
73 10 5 0.01 1.62 3.38 0.13 0.00 99.86 0.00 95.07
74 10 11 0.08 1.62 3.38 0.05 0.00 99.86 0.00 95.07
75.fi
76.SH VERBOSE EXAMPLE
77The "-v" option adds verbosity to the output:
78
79.nf
80GenuineIntel 11 CPUID levels; family:model:stepping 0x6:2c:2 (6:44:2)
8112 * 133 = 1600 MHz max efficiency
8225 * 133 = 3333 MHz TSC frequency
8326 * 133 = 3467 MHz max turbo 4 active cores
8426 * 133 = 3467 MHz max turbo 3 active cores
8527 * 133 = 3600 MHz max turbo 2 active cores
8627 * 133 = 3600 MHz max turbo 1 active cores
87
88.fi
89The \fBmax efficiency\fP frequency, a.k.a. Low Frequency Mode, is the frequency
90available at the minimum package voltage. The \fBTSC frequency\fP is the nominal
91maximum frequency of the processor if turbo-mode were not available. This frequency
92should be sustainable on all CPUs indefinitely, given nominal power and cooling.
93The remaining rows show what maximum turbo frequency is possible
94depending on the number of idle cores. Note that this information is
95not available on all processors.
96.SH FORK EXAMPLE
97If turbostat is invoked with a command, it will fork that command
98and output the statistics gathered when the command exits.
99eg. Here a cycle soaker is run on 1 CPU (see %c0) for a few seconds
100until ^C while the other CPUs are mostly idle:
101
102.nf
103[root@x980 lenb]# ./turbostat cat /dev/zero > /dev/null
104
105^Ccore CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6
106 8.49 3.63 3.38 16.23 0.66 74.63 0.00 0.00
107 0 0 1.22 3.62 3.38 32.18 0.00 66.60 0.00 0.00
108 0 6 0.40 3.61 3.38 33.00 0.00 66.60 0.00 0.00
109 1 2 0.11 3.14 3.38 0.19 3.95 95.75 0.00 0.00
110 1 8 0.05 2.88 3.38 0.25 3.95 95.75 0.00 0.00
111 2 4 0.00 3.13 3.38 0.02 0.00 99.98 0.00 0.00
112 2 10 0.00 3.09 3.38 0.02 0.00 99.98 0.00 0.00
113 8 1 0.04 3.50 3.38 14.43 0.00 85.54 0.00 0.00
114 8 7 0.03 2.98 3.38 14.43 0.00 85.54 0.00 0.00
115 9 3 0.00 3.16 3.38 100.00 0.00 0.00 0.00 0.00
116 9 9 99.93 3.63 3.38 0.06 0.00 0.00 0.00 0.00
117 10 5 0.01 2.82 3.38 0.08 0.00 99.91 0.00 0.00
118 10 11 0.02 3.36 3.38 0.06 0.00 99.91 0.00 0.00
1196.950866 sec
120
121.fi
122Above the cycle soaker drives cpu9 up 3.6 Ghz turbo limit
123while the other processors are generally in various states of idle.
124
125Note that cpu3 is an HT sibling sharing core9
126with cpu9, and thus it is unable to get to an idle state
127deeper than c1 while cpu9 is busy.
128
129Note that turbostat reports average GHz of 3.61, while
130the arithmetic average of the GHz column above is 3.24.
131This is a weighted average, where the weight is %c0. ie. it is the total number of
132un-halted cycles elapsed per time divided by the number of CPUs.
133.SH NOTES
134
135.B "turbostat "
136must be run as root.
137
138.B "turbostat "
139reads hardware counters, but doesn't write them.
140So it will not interfere with the OS or other programs, including
141multiple invocations of itself.
142
143\fBturbostat \fP
144may work poorly on Linux-2.6.20 through 2.6.29,
145as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF
146in those kernels.
147
148The APERF, MPERF MSRs are defined to count non-halted cycles.
149Although it is not guaranteed by the architecture, turbostat assumes
150that they count at TSC rate, which is true on all processors tested to date.
151
152.SH REFERENCES
153"Intel® Turbo Boost Technology
154in Intel® Core™ Microarchitecture (Nehalem) Based Processors"
155http://download.intel.com/design/processor/applnots/320354.pdf
156
157"Intel® 64 and IA-32 Architectures Software Developer's Manual
158Volume 3B: System Programming Guide"
159http://www.intel.com/products/processor/manuals/
160
161.SH FILES
162.ta
163.nf
164/dev/cpu/*/msr
165.fi
166
167.SH "SEE ALSO"
168msr(4), vmstat(8)
169.PP
170.SH AUTHORS
171.nf
172Written by Len Brown <len.brown@intel.com>
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
new file mode 100644
index 000000000000..4c6983de6fd9
--- /dev/null
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -0,0 +1,1048 @@
1/*
2 * turbostat -- show CPU frequency and C-state residency
3 * on modern Intel turbo-capable processors.
4 *
5 * Copyright (c) 2010, Intel Corporation.
6 * Len Brown <len.brown@intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#include <stdio.h>
23#include <unistd.h>
24#include <sys/types.h>
25#include <sys/wait.h>
26#include <sys/stat.h>
27#include <sys/resource.h>
28#include <fcntl.h>
29#include <signal.h>
30#include <sys/time.h>
31#include <stdlib.h>
32#include <dirent.h>
33#include <string.h>
34#include <ctype.h>
35
36#define MSR_TSC 0x10
37#define MSR_NEHALEM_PLATFORM_INFO 0xCE
38#define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1AD
39#define MSR_APERF 0xE8
40#define MSR_MPERF 0xE7
41#define MSR_PKG_C2_RESIDENCY 0x60D /* SNB only */
42#define MSR_PKG_C3_RESIDENCY 0x3F8
43#define MSR_PKG_C6_RESIDENCY 0x3F9
44#define MSR_PKG_C7_RESIDENCY 0x3FA /* SNB only */
45#define MSR_CORE_C3_RESIDENCY 0x3FC
46#define MSR_CORE_C6_RESIDENCY 0x3FD
47#define MSR_CORE_C7_RESIDENCY 0x3FE /* SNB only */
48
49char *proc_stat = "/proc/stat";
50unsigned int interval_sec = 5; /* set with -i interval_sec */
51unsigned int verbose; /* set with -v */
52unsigned int skip_c0;
53unsigned int skip_c1;
54unsigned int do_nhm_cstates;
55unsigned int do_snb_cstates;
56unsigned int has_aperf;
57unsigned int units = 1000000000; /* Ghz etc */
58unsigned int genuine_intel;
59unsigned int has_invariant_tsc;
60unsigned int do_nehalem_platform_info;
61unsigned int do_nehalem_turbo_ratio_limit;
62unsigned int extra_msr_offset;
63double bclk;
64unsigned int show_pkg;
65unsigned int show_core;
66unsigned int show_cpu;
67
68int aperf_mperf_unstable;
69int backwards_count;
70char *progname;
71int need_reinitialize;
72
73int num_cpus;
74
75typedef struct per_cpu_counters {
76 unsigned long long tsc; /* per thread */
77 unsigned long long aperf; /* per thread */
78 unsigned long long mperf; /* per thread */
79 unsigned long long c1; /* per thread (calculated) */
80 unsigned long long c3; /* per core */
81 unsigned long long c6; /* per core */
82 unsigned long long c7; /* per core */
83 unsigned long long pc2; /* per package */
84 unsigned long long pc3; /* per package */
85 unsigned long long pc6; /* per package */
86 unsigned long long pc7; /* per package */
87 unsigned long long extra_msr; /* per thread */
88 int pkg;
89 int core;
90 int cpu;
91 struct per_cpu_counters *next;
92} PCC;
93
94PCC *pcc_even;
95PCC *pcc_odd;
96PCC *pcc_delta;
97PCC *pcc_average;
98struct timeval tv_even;
99struct timeval tv_odd;
100struct timeval tv_delta;
101
102unsigned long long get_msr(int cpu, off_t offset)
103{
104 ssize_t retval;
105 unsigned long long msr;
106 char pathname[32];
107 int fd;
108
109 sprintf(pathname, "/dev/cpu/%d/msr", cpu);
110 fd = open(pathname, O_RDONLY);
111 if (fd < 0) {
112 perror(pathname);
113 need_reinitialize = 1;
114 return 0;
115 }
116
117 retval = pread(fd, &msr, sizeof msr, offset);
118 if (retval != sizeof msr) {
119 fprintf(stderr, "cpu%d pread(..., 0x%zx) = %jd\n",
120 cpu, offset, retval);
121 exit(-2);
122 }
123
124 close(fd);
125 return msr;
126}
127
128void print_header()
129{
130 if (show_pkg)
131 fprintf(stderr, "pkg ");
132 if (show_core)
133 fprintf(stderr, "core");
134 if (show_cpu)
135 fprintf(stderr, " CPU");
136 if (do_nhm_cstates)
137 fprintf(stderr, " %%c0 ");
138 if (has_aperf)
139 fprintf(stderr, " GHz");
140 fprintf(stderr, " TSC");
141 if (do_nhm_cstates)
142 fprintf(stderr, " %%c1 ");
143 if (do_nhm_cstates)
144 fprintf(stderr, " %%c3 ");
145 if (do_nhm_cstates)
146 fprintf(stderr, " %%c6 ");
147 if (do_snb_cstates)
148 fprintf(stderr, " %%c7 ");
149 if (do_snb_cstates)
150 fprintf(stderr, " %%pc2 ");
151 if (do_nhm_cstates)
152 fprintf(stderr, " %%pc3 ");
153 if (do_nhm_cstates)
154 fprintf(stderr, " %%pc6 ");
155 if (do_snb_cstates)
156 fprintf(stderr, " %%pc7 ");
157 if (extra_msr_offset)
158 fprintf(stderr, " MSR 0x%x ", extra_msr_offset);
159
160 putc('\n', stderr);
161}
162
163void dump_pcc(PCC *pcc)
164{
165 fprintf(stderr, "package: %d ", pcc->pkg);
166 fprintf(stderr, "core:: %d ", pcc->core);
167 fprintf(stderr, "CPU: %d ", pcc->cpu);
168 fprintf(stderr, "TSC: %016llX\n", pcc->tsc);
169 fprintf(stderr, "c3: %016llX\n", pcc->c3);
170 fprintf(stderr, "c6: %016llX\n", pcc->c6);
171 fprintf(stderr, "c7: %016llX\n", pcc->c7);
172 fprintf(stderr, "aperf: %016llX\n", pcc->aperf);
173 fprintf(stderr, "pc2: %016llX\n", pcc->pc2);
174 fprintf(stderr, "pc3: %016llX\n", pcc->pc3);
175 fprintf(stderr, "pc6: %016llX\n", pcc->pc6);
176 fprintf(stderr, "pc7: %016llX\n", pcc->pc7);
177 fprintf(stderr, "msr0x%x: %016llX\n", extra_msr_offset, pcc->extra_msr);
178}
179
180void dump_list(PCC *pcc)
181{
182 printf("dump_list 0x%p\n", pcc);
183
184 for (; pcc; pcc = pcc->next)
185 dump_pcc(pcc);
186}
187
188void print_pcc(PCC *p)
189{
190 double interval_float;
191
192 interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0;
193
194 /* topology columns, print blanks on 1st (average) line */
195 if (p == pcc_average) {
196 if (show_pkg)
197 fprintf(stderr, " ");
198 if (show_core)
199 fprintf(stderr, " ");
200 if (show_cpu)
201 fprintf(stderr, " ");
202 } else {
203 if (show_pkg)
204 fprintf(stderr, "%4d", p->pkg);
205 if (show_core)
206 fprintf(stderr, "%4d", p->core);
207 if (show_cpu)
208 fprintf(stderr, "%4d", p->cpu);
209 }
210
211 /* %c0 */
212 if (do_nhm_cstates) {
213 if (!skip_c0)
214 fprintf(stderr, "%7.2f", 100.0 * p->mperf/p->tsc);
215 else
216 fprintf(stderr, " ****");
217 }
218
219 /* GHz */
220 if (has_aperf) {
221 if (!aperf_mperf_unstable) {
222 fprintf(stderr, "%5.2f",
223 1.0 * p->tsc / units * p->aperf /
224 p->mperf / interval_float);
225 } else {
226 if (p->aperf > p->tsc || p->mperf > p->tsc) {
227 fprintf(stderr, " ****");
228 } else {
229 fprintf(stderr, "%4.1f*",
230 1.0 * p->tsc /
231 units * p->aperf /
232 p->mperf / interval_float);
233 }
234 }
235 }
236
237 /* TSC */
238 fprintf(stderr, "%5.2f", 1.0 * p->tsc/units/interval_float);
239
240 if (do_nhm_cstates) {
241 if (!skip_c1)
242 fprintf(stderr, "%7.2f", 100.0 * p->c1/p->tsc);
243 else
244 fprintf(stderr, " ****");
245 }
246 if (do_nhm_cstates)
247 fprintf(stderr, "%7.2f", 100.0 * p->c3/p->tsc);
248 if (do_nhm_cstates)
249 fprintf(stderr, "%7.2f", 100.0 * p->c6/p->tsc);
250 if (do_snb_cstates)
251 fprintf(stderr, "%7.2f", 100.0 * p->c7/p->tsc);
252 if (do_snb_cstates)
253 fprintf(stderr, "%7.2f", 100.0 * p->pc2/p->tsc);
254 if (do_nhm_cstates)
255 fprintf(stderr, "%7.2f", 100.0 * p->pc3/p->tsc);
256 if (do_nhm_cstates)
257 fprintf(stderr, "%7.2f", 100.0 * p->pc6/p->tsc);
258 if (do_snb_cstates)
259 fprintf(stderr, "%7.2f", 100.0 * p->pc7/p->tsc);
260 if (extra_msr_offset)
261 fprintf(stderr, " 0x%016llx", p->extra_msr);
262 putc('\n', stderr);
263}
264
265void print_counters(PCC *cnt)
266{
267 PCC *pcc;
268
269 print_header();
270
271 if (num_cpus > 1)
272 print_pcc(pcc_average);
273
274 for (pcc = cnt; pcc != NULL; pcc = pcc->next)
275 print_pcc(pcc);
276
277}
278
279#define SUBTRACT_COUNTER(after, before, delta) (delta = (after - before), (before > after))
280
281
282int compute_delta(PCC *after, PCC *before, PCC *delta)
283{
284 int errors = 0;
285 int perf_err = 0;
286
287 skip_c0 = skip_c1 = 0;
288
289 for ( ; after && before && delta;
290 after = after->next, before = before->next, delta = delta->next) {
291 if (before->cpu != after->cpu) {
292 printf("cpu configuration changed: %d != %d\n",
293 before->cpu, after->cpu);
294 return -1;
295 }
296
297 if (SUBTRACT_COUNTER(after->tsc, before->tsc, delta->tsc)) {
298 fprintf(stderr, "cpu%d TSC went backwards %llX to %llX\n",
299 before->cpu, before->tsc, after->tsc);
300 errors++;
301 }
302 /* check for TSC < 1 Mcycles over interval */
303 if (delta->tsc < (1000 * 1000)) {
304 fprintf(stderr, "Insanely slow TSC rate,"
305 " TSC stops in idle?\n");
306 fprintf(stderr, "You can disable all c-states"
307 " by booting with \"idle=poll\"\n");
308 fprintf(stderr, "or just the deep ones with"
309 " \"processor.max_cstate=1\"\n");
310 exit(-3);
311 }
312 if (SUBTRACT_COUNTER(after->c3, before->c3, delta->c3)) {
313 fprintf(stderr, "cpu%d c3 counter went backwards %llX to %llX\n",
314 before->cpu, before->c3, after->c3);
315 errors++;
316 }
317 if (SUBTRACT_COUNTER(after->c6, before->c6, delta->c6)) {
318 fprintf(stderr, "cpu%d c6 counter went backwards %llX to %llX\n",
319 before->cpu, before->c6, after->c6);
320 errors++;
321 }
322 if (SUBTRACT_COUNTER(after->c7, before->c7, delta->c7)) {
323 fprintf(stderr, "cpu%d c7 counter went backwards %llX to %llX\n",
324 before->cpu, before->c7, after->c7);
325 errors++;
326 }
327 if (SUBTRACT_COUNTER(after->pc2, before->pc2, delta->pc2)) {
328 fprintf(stderr, "cpu%d pc2 counter went backwards %llX to %llX\n",
329 before->cpu, before->pc2, after->pc2);
330 errors++;
331 }
332 if (SUBTRACT_COUNTER(after->pc3, before->pc3, delta->pc3)) {
333 fprintf(stderr, "cpu%d pc3 counter went backwards %llX to %llX\n",
334 before->cpu, before->pc3, after->pc3);
335 errors++;
336 }
337 if (SUBTRACT_COUNTER(after->pc6, before->pc6, delta->pc6)) {
338 fprintf(stderr, "cpu%d pc6 counter went backwards %llX to %llX\n",
339 before->cpu, before->pc6, after->pc6);
340 errors++;
341 }
342 if (SUBTRACT_COUNTER(after->pc7, before->pc7, delta->pc7)) {
343 fprintf(stderr, "cpu%d pc7 counter went backwards %llX to %llX\n",
344 before->cpu, before->pc7, after->pc7);
345 errors++;
346 }
347
348 perf_err = SUBTRACT_COUNTER(after->aperf, before->aperf, delta->aperf);
349 if (perf_err) {
350 fprintf(stderr, "cpu%d aperf counter went backwards %llX to %llX\n",
351 before->cpu, before->aperf, after->aperf);
352 }
353 perf_err |= SUBTRACT_COUNTER(after->mperf, before->mperf, delta->mperf);
354 if (perf_err) {
355 fprintf(stderr, "cpu%d mperf counter went backwards %llX to %llX\n",
356 before->cpu, before->mperf, after->mperf);
357 }
358 if (perf_err) {
359 if (!aperf_mperf_unstable) {
360 fprintf(stderr, "%s: APERF or MPERF went backwards *\n", progname);
361 fprintf(stderr, "* Frequency results do not cover entire interval *\n");
362 fprintf(stderr, "* fix this by running Linux-2.6.30 or later *\n");
363
364 aperf_mperf_unstable = 1;
365 }
366 /*
367 * mperf delta is likely a huge "positive" number
368 * can not use it for calculating c0 time
369 */
370 skip_c0 = 1;
371 skip_c1 = 1;
372 }
373
374 /*
375 * As mperf and tsc collection are not atomic,
376 * it is possible for mperf's non-halted cycles
377 * to exceed TSC's all cycles: show c1 = 0% in that case.
378 */
379 if (delta->mperf > delta->tsc)
380 delta->c1 = 0;
381 else /* normal case, derive c1 */
382 delta->c1 = delta->tsc - delta->mperf
383 - delta->c3 - delta->c6 - delta->c7;
384
385 if (delta->mperf == 0)
386 delta->mperf = 1; /* divide by 0 protection */
387
388 /*
389 * for "extra msr", just copy the latest w/o subtracting
390 */
391 delta->extra_msr = after->extra_msr;
392 if (errors) {
393 fprintf(stderr, "ERROR cpu%d before:\n", before->cpu);
394 dump_pcc(before);
395 fprintf(stderr, "ERROR cpu%d after:\n", before->cpu);
396 dump_pcc(after);
397 errors = 0;
398 }
399 }
400 return 0;
401}
402
403void compute_average(PCC *delta, PCC *avg)
404{
405 PCC *sum;
406
407 sum = calloc(1, sizeof(PCC));
408 if (sum == NULL) {
409 perror("calloc sum");
410 exit(1);
411 }
412
413 for (; delta; delta = delta->next) {
414 sum->tsc += delta->tsc;
415 sum->c1 += delta->c1;
416 sum->c3 += delta->c3;
417 sum->c6 += delta->c6;
418 sum->c7 += delta->c7;
419 sum->aperf += delta->aperf;
420 sum->mperf += delta->mperf;
421 sum->pc2 += delta->pc2;
422 sum->pc3 += delta->pc3;
423 sum->pc6 += delta->pc6;
424 sum->pc7 += delta->pc7;
425 }
426 avg->tsc = sum->tsc/num_cpus;
427 avg->c1 = sum->c1/num_cpus;
428 avg->c3 = sum->c3/num_cpus;
429 avg->c6 = sum->c6/num_cpus;
430 avg->c7 = sum->c7/num_cpus;
431 avg->aperf = sum->aperf/num_cpus;
432 avg->mperf = sum->mperf/num_cpus;
433 avg->pc2 = sum->pc2/num_cpus;
434 avg->pc3 = sum->pc3/num_cpus;
435 avg->pc6 = sum->pc6/num_cpus;
436 avg->pc7 = sum->pc7/num_cpus;
437
438 free(sum);
439}
440
441void get_counters(PCC *pcc)
442{
443 for ( ; pcc; pcc = pcc->next) {
444 pcc->tsc = get_msr(pcc->cpu, MSR_TSC);
445 if (do_nhm_cstates)
446 pcc->c3 = get_msr(pcc->cpu, MSR_CORE_C3_RESIDENCY);
447 if (do_nhm_cstates)
448 pcc->c6 = get_msr(pcc->cpu, MSR_CORE_C6_RESIDENCY);
449 if (do_snb_cstates)
450 pcc->c7 = get_msr(pcc->cpu, MSR_CORE_C7_RESIDENCY);
451 if (has_aperf)
452 pcc->aperf = get_msr(pcc->cpu, MSR_APERF);
453 if (has_aperf)
454 pcc->mperf = get_msr(pcc->cpu, MSR_MPERF);
455 if (do_snb_cstates)
456 pcc->pc2 = get_msr(pcc->cpu, MSR_PKG_C2_RESIDENCY);
457 if (do_nhm_cstates)
458 pcc->pc3 = get_msr(pcc->cpu, MSR_PKG_C3_RESIDENCY);
459 if (do_nhm_cstates)
460 pcc->pc6 = get_msr(pcc->cpu, MSR_PKG_C6_RESIDENCY);
461 if (do_snb_cstates)
462 pcc->pc7 = get_msr(pcc->cpu, MSR_PKG_C7_RESIDENCY);
463 if (extra_msr_offset)
464 pcc->extra_msr = get_msr(pcc->cpu, extra_msr_offset);
465 }
466}
467
468
469void print_nehalem_info()
470{
471 unsigned long long msr;
472 unsigned int ratio;
473
474 if (!do_nehalem_platform_info)
475 return;
476
477 msr = get_msr(0, MSR_NEHALEM_PLATFORM_INFO);
478
479 ratio = (msr >> 40) & 0xFF;
480 fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n",
481 ratio, bclk, ratio * bclk);
482
483 ratio = (msr >> 8) & 0xFF;
484 fprintf(stderr, "%d * %.0f = %.0f MHz TSC frequency\n",
485 ratio, bclk, ratio * bclk);
486
487 if (verbose > 1)
488 fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr);
489
490 if (!do_nehalem_turbo_ratio_limit)
491 return;
492
493 msr = get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT);
494
495 ratio = (msr >> 24) & 0xFF;
496 if (ratio)
497 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 4 active cores\n",
498 ratio, bclk, ratio * bclk);
499
500 ratio = (msr >> 16) & 0xFF;
501 if (ratio)
502 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 3 active cores\n",
503 ratio, bclk, ratio * bclk);
504
505 ratio = (msr >> 8) & 0xFF;
506 if (ratio)
507 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 2 active cores\n",
508 ratio, bclk, ratio * bclk);
509
510 ratio = (msr >> 0) & 0xFF;
511 if (ratio)
512 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n",
513 ratio, bclk, ratio * bclk);
514
515}
516
517void free_counter_list(PCC *list)
518{
519 PCC *p;
520
521 for (p = list; p; ) {
522 PCC *free_me;
523
524 free_me = p;
525 p = p->next;
526 free(free_me);
527 }
528 return;
529}
530
531void free_all_counters(void)
532{
533 free_counter_list(pcc_even);
534 pcc_even = NULL;
535
536 free_counter_list(pcc_odd);
537 pcc_odd = NULL;
538
539 free_counter_list(pcc_delta);
540 pcc_delta = NULL;
541
542 free_counter_list(pcc_average);
543 pcc_average = NULL;
544}
545
546void insert_cpu_counters(PCC **list, PCC *new)
547{
548 PCC *prev;
549
550 /*
551 * list was empty
552 */
553 if (*list == NULL) {
554 new->next = *list;
555 *list = new;
556 return;
557 }
558
559 show_cpu = 1; /* there is more than one CPU */
560
561 /*
562 * insert on front of list.
563 * It is sorted by ascending package#, core#, cpu#
564 */
565 if (((*list)->pkg > new->pkg) ||
566 (((*list)->pkg == new->pkg) && ((*list)->core > new->core)) ||
567 (((*list)->pkg == new->pkg) && ((*list)->core == new->core) && ((*list)->cpu > new->cpu))) {
568 new->next = *list;
569 *list = new;
570 return;
571 }
572
573 prev = *list;
574
575 while (prev->next && (prev->next->pkg < new->pkg)) {
576 prev = prev->next;
577 show_pkg = 1; /* there is more than 1 package */
578 }
579
580 while (prev->next && (prev->next->pkg == new->pkg)
581 && (prev->next->core < new->core)) {
582 prev = prev->next;
583 show_core = 1; /* there is more than 1 core */
584 }
585
586 while (prev->next && (prev->next->pkg == new->pkg)
587 && (prev->next->core == new->core)
588 && (prev->next->cpu < new->cpu)) {
589 prev = prev->next;
590 }
591
592 /*
593 * insert after "prev"
594 */
595 new->next = prev->next;
596 prev->next = new;
597
598 return;
599}
600
601void alloc_new_cpu_counters(int pkg, int core, int cpu)
602{
603 PCC *new;
604
605 if (verbose > 1)
606 printf("pkg%d core%d, cpu%d\n", pkg, core, cpu);
607
608 new = (PCC *)calloc(1, sizeof(PCC));
609 if (new == NULL) {
610 perror("calloc");
611 exit(1);
612 }
613 new->pkg = pkg;
614 new->core = core;
615 new->cpu = cpu;
616 insert_cpu_counters(&pcc_odd, new);
617
618 new = (PCC *)calloc(1, sizeof(PCC));
619 if (new == NULL) {
620 perror("calloc");
621 exit(1);
622 }
623 new->pkg = pkg;
624 new->core = core;
625 new->cpu = cpu;
626 insert_cpu_counters(&pcc_even, new);
627
628 new = (PCC *)calloc(1, sizeof(PCC));
629 if (new == NULL) {
630 perror("calloc");
631 exit(1);
632 }
633 new->pkg = pkg;
634 new->core = core;
635 new->cpu = cpu;
636 insert_cpu_counters(&pcc_delta, new);
637
638 new = (PCC *)calloc(1, sizeof(PCC));
639 if (new == NULL) {
640 perror("calloc");
641 exit(1);
642 }
643 new->pkg = pkg;
644 new->core = core;
645 new->cpu = cpu;
646 pcc_average = new;
647}
648
649int get_physical_package_id(int cpu)
650{
651 char path[64];
652 FILE *filep;
653 int pkg;
654
655 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
656 filep = fopen(path, "r");
657 if (filep == NULL) {
658 perror(path);
659 exit(1);
660 }
661 fscanf(filep, "%d", &pkg);
662 fclose(filep);
663 return pkg;
664}
665
666int get_core_id(int cpu)
667{
668 char path[64];
669 FILE *filep;
670 int core;
671
672 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
673 filep = fopen(path, "r");
674 if (filep == NULL) {
675 perror(path);
676 exit(1);
677 }
678 fscanf(filep, "%d", &core);
679 fclose(filep);
680 return core;
681}
682
683/*
684 * run func(index, cpu) on every cpu in /proc/stat
685 */
686
687int for_all_cpus(void (func)(int, int, int))
688{
689 FILE *fp;
690 int cpu_count;
691 int retval;
692
693 fp = fopen(proc_stat, "r");
694 if (fp == NULL) {
695 perror(proc_stat);
696 exit(1);
697 }
698
699 retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
700 if (retval != 0) {
701 perror("/proc/stat format");
702 exit(1);
703 }
704
705 for (cpu_count = 0; ; cpu_count++) {
706 int cpu;
707
708 retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu);
709 if (retval != 1)
710 break;
711
712 func(get_physical_package_id(cpu), get_core_id(cpu), cpu);
713 }
714 fclose(fp);
715 return cpu_count;
716}
717
718void re_initialize(void)
719{
720 printf("turbostat: topology changed, re-initializing.\n");
721 free_all_counters();
722 num_cpus = for_all_cpus(alloc_new_cpu_counters);
723 need_reinitialize = 0;
724 printf("num_cpus is now %d\n", num_cpus);
725}
726
727void dummy(int pkg, int core, int cpu) { return; }
728/*
729 * check to see if a cpu came on-line
730 */
731void verify_num_cpus()
732{
733 int new_num_cpus;
734
735 new_num_cpus = for_all_cpus(dummy);
736
737 if (new_num_cpus != num_cpus) {
738 if (verbose)
739 printf("num_cpus was %d, is now %d\n",
740 num_cpus, new_num_cpus);
741 need_reinitialize = 1;
742 }
743
744 return;
745}
746
747void turbostat_loop()
748{
749restart:
750 get_counters(pcc_even);
751 gettimeofday(&tv_even, (struct timezone *)NULL);
752
753 while (1) {
754 verify_num_cpus();
755 if (need_reinitialize) {
756 re_initialize();
757 goto restart;
758 }
759 sleep(interval_sec);
760 get_counters(pcc_odd);
761 gettimeofday(&tv_odd, (struct timezone *)NULL);
762
763 compute_delta(pcc_odd, pcc_even, pcc_delta);
764 timersub(&tv_odd, &tv_even, &tv_delta);
765 compute_average(pcc_delta, pcc_average);
766 print_counters(pcc_delta);
767 if (need_reinitialize) {
768 re_initialize();
769 goto restart;
770 }
771 sleep(interval_sec);
772 get_counters(pcc_even);
773 gettimeofday(&tv_even, (struct timezone *)NULL);
774 compute_delta(pcc_even, pcc_odd, pcc_delta);
775 timersub(&tv_even, &tv_odd, &tv_delta);
776 compute_average(pcc_delta, pcc_average);
777 print_counters(pcc_delta);
778 }
779}
780
781void check_dev_msr()
782{
783 struct stat sb;
784
785 if (stat("/dev/cpu/0/msr", &sb)) {
786 fprintf(stderr, "no /dev/cpu/0/msr\n");
787 fprintf(stderr, "Try \"# modprobe msr\"\n");
788 exit(-5);
789 }
790}
791
792void check_super_user()
793{
794 if (getuid() != 0) {
795 fprintf(stderr, "must be root\n");
796 exit(-6);
797 }
798}
799
800int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
801{
802 if (!genuine_intel)
803 return 0;
804
805 if (family != 6)
806 return 0;
807
808 switch (model) {
809 case 0x1A: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
810 case 0x1E: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
811 case 0x1F: /* Core i7 and i5 Processor - Nehalem */
812 case 0x25: /* Westmere Client - Clarkdale, Arrandale */
813 case 0x2C: /* Westmere EP - Gulftown */
814 case 0x2A: /* SNB */
815 case 0x2D: /* SNB Xeon */
816 return 1;
817 case 0x2E: /* Nehalem-EX Xeon - Beckton */
818 case 0x2F: /* Westmere-EX Xeon - Eagleton */
819 default:
820 return 0;
821 }
822}
823
824int is_snb(unsigned int family, unsigned int model)
825{
826 if (!genuine_intel)
827 return 0;
828
829 switch (model) {
830 case 0x2A:
831 case 0x2D:
832 return 1;
833 }
834 return 0;
835}
836
837double discover_bclk(unsigned int family, unsigned int model)
838{
839 if (is_snb(family, model))
840 return 100.00;
841 else
842 return 133.33;
843}
844
845void check_cpuid()
846{
847 unsigned int eax, ebx, ecx, edx, max_level;
848 unsigned int fms, family, model, stepping;
849
850 eax = ebx = ecx = edx = 0;
851
852 asm("cpuid" : "=a" (max_level), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0));
853
854 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
855 genuine_intel = 1;
856
857 if (verbose)
858 fprintf(stderr, "%.4s%.4s%.4s ",
859 (char *)&ebx, (char *)&edx, (char *)&ecx);
860
861 asm("cpuid" : "=a" (fms), "=c" (ecx), "=d" (edx) : "a" (1) : "ebx");
862 family = (fms >> 8) & 0xf;
863 model = (fms >> 4) & 0xf;
864 stepping = fms & 0xf;
865 if (family == 6 || family == 0xf)
866 model += ((fms >> 16) & 0xf) << 4;
867
868 if (verbose)
869 fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
870 max_level, family, model, stepping, family, model, stepping);
871
872 if (!(edx & (1 << 5))) {
873 fprintf(stderr, "CPUID: no MSR\n");
874 exit(1);
875 }
876
877 /*
878 * check max extended function levels of CPUID.
879 * This is needed to check for invariant TSC.
880 * This check is valid for both Intel and AMD.
881 */
882 ebx = ecx = edx = 0;
883 asm("cpuid" : "=a" (max_level), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000000));
884
885 if (max_level < 0x80000007) {
886 fprintf(stderr, "CPUID: no invariant TSC (max_level 0x%x)\n", max_level);
887 exit(1);
888 }
889
890 /*
891 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
892 * this check is valid for both Intel and AMD
893 */
894 asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000007));
895 has_invariant_tsc = edx && (1 << 8);
896
897 if (!has_invariant_tsc) {
898 fprintf(stderr, "No invariant TSC\n");
899 exit(1);
900 }
901
902 /*
903 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
904 * this check is valid for both Intel and AMD
905 */
906
907 asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x6));
908 has_aperf = ecx && (1 << 0);
909 if (!has_aperf) {
910 fprintf(stderr, "No APERF MSR\n");
911 exit(1);
912 }
913
914 do_nehalem_platform_info = genuine_intel && has_invariant_tsc;
915 do_nhm_cstates = genuine_intel; /* all Intel w/ non-stop TSC have NHM counters */
916 do_snb_cstates = is_snb(family, model);
917 bclk = discover_bclk(family, model);
918
919 do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model);
920}
921
922
923void usage()
924{
925 fprintf(stderr, "%s: [-v] [-M MSR#] [-i interval_sec | command ...]\n",
926 progname);
927 exit(1);
928}
929
930
931/*
932 * in /dev/cpu/ return success for names that are numbers
933 * ie. filter out ".", "..", "microcode".
934 */
935int dir_filter(const struct dirent *dirp)
936{
937 if (isdigit(dirp->d_name[0]))
938 return 1;
939 else
940 return 0;
941}
942
943int open_dev_cpu_msr(int dummy1)
944{
945 return 0;
946}
947
948void turbostat_init()
949{
950 check_cpuid();
951
952 check_dev_msr();
953 check_super_user();
954
955 num_cpus = for_all_cpus(alloc_new_cpu_counters);
956
957 if (verbose)
958 print_nehalem_info();
959}
960
961int fork_it(char **argv)
962{
963 int retval;
964 pid_t child_pid;
965 get_counters(pcc_even);
966 gettimeofday(&tv_even, (struct timezone *)NULL);
967
968 child_pid = fork();
969 if (!child_pid) {
970 /* child */
971 execvp(argv[0], argv);
972 } else {
973 int status;
974
975 /* parent */
976 if (child_pid == -1) {
977 perror("fork");
978 exit(1);
979 }
980
981 signal(SIGINT, SIG_IGN);
982 signal(SIGQUIT, SIG_IGN);
983 if (waitpid(child_pid, &status, 0) == -1) {
984 perror("wait");
985 exit(1);
986 }
987 }
988 get_counters(pcc_odd);
989 gettimeofday(&tv_odd, (struct timezone *)NULL);
990 retval = compute_delta(pcc_odd, pcc_even, pcc_delta);
991
992 timersub(&tv_odd, &tv_even, &tv_delta);
993 compute_average(pcc_delta, pcc_average);
994 if (!retval)
995 print_counters(pcc_delta);
996
997 fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);;
998
999 return 0;
1000}
1001
1002void cmdline(int argc, char **argv)
1003{
1004 int opt;
1005
1006 progname = argv[0];
1007
1008 while ((opt = getopt(argc, argv, "+vi:M:")) != -1) {
1009 switch (opt) {
1010 case 'v':
1011 verbose++;
1012 break;
1013 case 'i':
1014 interval_sec = atoi(optarg);
1015 break;
1016 case 'M':
1017 sscanf(optarg, "%x", &extra_msr_offset);
1018 if (verbose > 1)
1019 fprintf(stderr, "MSR 0x%X\n", extra_msr_offset);
1020 break;
1021 default:
1022 usage();
1023 }
1024 }
1025}
1026
1027int main(int argc, char **argv)
1028{
1029 cmdline(argc, argv);
1030
1031 if (verbose > 1)
1032 fprintf(stderr, "turbostat Dec 6, 2010"
1033 " - Len Brown <lenb@kernel.org>\n");
1034 if (verbose > 1)
1035 fprintf(stderr, "http://userweb.kernel.org/~lenb/acpi/utils/pmtools/turbostat/\n");
1036
1037 turbostat_init();
1038
1039 /*
1040 * if any params left, it must be a command to fork
1041 */
1042 if (argc - optind)
1043 return fork_it(argv + optind);
1044 else
1045 turbostat_loop();
1046
1047 return 0;
1048}
diff --git a/tools/power/x86/x86_energy_perf_policy/Makefile b/tools/power/x86/x86_energy_perf_policy/Makefile
new file mode 100644
index 000000000000..f458237fdd79
--- /dev/null
+++ b/tools/power/x86/x86_energy_perf_policy/Makefile
@@ -0,0 +1,8 @@
1x86_energy_perf_policy : x86_energy_perf_policy.c
2
3clean :
4 rm -f x86_energy_perf_policy
5
6install :
7 install x86_energy_perf_policy /usr/bin/
8 install x86_energy_perf_policy.8 /usr/share/man/man8/
diff --git a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8 b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8
new file mode 100644
index 000000000000..8eaaad648cdb
--- /dev/null
+++ b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8
@@ -0,0 +1,104 @@
1.\" This page Copyright (C) 2010 Len Brown <len.brown@intel.com>
2.\" Distributed under the GPL, Copyleft 1994.
3.TH X86_ENERGY_PERF_POLICY 8
4.SH NAME
5x86_energy_perf_policy \- read or write MSR_IA32_ENERGY_PERF_BIAS
6.SH SYNOPSIS
7.ft B
8.B x86_energy_perf_policy
9.RB [ "\-c cpu" ]
10.RB [ "\-v" ]
11.RB "\-r"
12.br
13.B x86_energy_perf_policy
14.RB [ "\-c cpu" ]
15.RB [ "\-v" ]
16.RB 'performance'
17.br
18.B x86_energy_perf_policy
19.RB [ "\-c cpu" ]
20.RB [ "\-v" ]
21.RB 'normal'
22.br
23.B x86_energy_perf_policy
24.RB [ "\-c cpu" ]
25.RB [ "\-v" ]
26.RB 'powersave'
27.br
28.B x86_energy_perf_policy
29.RB [ "\-c cpu" ]
30.RB [ "\-v" ]
31.RB n
32.br
33.SH DESCRIPTION
34\fBx86_energy_perf_policy\fP
35allows software to convey
36its policy for the relative importance of performance
37versus energy savings to the processor.
38
39The processor uses this information in model-specific ways
40when it must select trade-offs between performance and
41energy efficiency.
42
43This policy hint does not supersede Processor Performance states
44(P-states) or CPU Idle power states (C-states), but allows
45software to have influence where it would otherwise be unable
46to express a preference.
47
48For example, this setting may tell the hardware how
49aggressively or conservatively to control frequency
50in the "turbo range" above the explicitly OS-controlled
51P-state frequency range. It may also tell the hardware
52how aggressively is should enter the OS requested C-states.
53
54Support for this feature is indicated by CPUID.06H.ECX.bit3
55per the Intel Architectures Software Developer's Manual.
56
57.SS Options
58\fB-c\fP limits operation to a single CPU.
59The default is to operate on all CPUs.
60Note that MSR_IA32_ENERGY_PERF_BIAS is defined per
61logical processor, but that the initial implementations
62of the MSR were shared among all processors in each package.
63.PP
64\fB-v\fP increases verbosity. By default
65x86_energy_perf_policy is silent.
66.PP
67\fB-r\fP is for "read-only" mode - the unchanged state
68is read and displayed.
69.PP
70.I performance
71Set a policy where performance is paramount.
72The processor will be unwilling to sacrifice any performance
73for the sake of energy saving. This is the hardware default.
74.PP
75.I normal
76Set a policy with a normal balance between performance and energy efficiency.
77The processor will tolerate minor performance compromise
78for potentially significant energy savings.
79This reasonable default for most desktops and servers.
80.PP
81.I powersave
82Set a policy where the processor can accept
83a measurable performance hit to maximize energy efficiency.
84.PP
85.I n
86Set MSR_IA32_ENERGY_PERF_BIAS to the specified number.
87The range of valid numbers is 0-15, where 0 is maximum
88performance and 15 is maximum energy efficiency.
89
90.SH NOTES
91.B "x86_energy_perf_policy "
92runs only as root.
93.SH FILES
94.ta
95.nf
96/dev/cpu/*/msr
97.fi
98
99.SH "SEE ALSO"
100msr(4)
101.PP
102.SH AUTHORS
103.nf
104Written by Len Brown <len.brown@intel.com>
diff --git a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c
new file mode 100644
index 000000000000..d9678a34dd70
--- /dev/null
+++ b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c
@@ -0,0 +1,325 @@
1/*
2 * x86_energy_perf_policy -- set the energy versus performance
3 * policy preference bias on recent X86 processors.
4 */
5/*
6 * Copyright (c) 2010, Intel Corporation.
7 * Len Brown <len.brown@intel.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms and conditions of the GNU General Public License,
11 * version 2, as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23#include <stdio.h>
24#include <unistd.h>
25#include <sys/types.h>
26#include <sys/stat.h>
27#include <sys/resource.h>
28#include <fcntl.h>
29#include <signal.h>
30#include <sys/time.h>
31#include <stdlib.h>
32#include <string.h>
33
34unsigned int verbose; /* set with -v */
35unsigned int read_only; /* set with -r */
36char *progname;
37unsigned long long new_bias;
38int cpu = -1;
39
40/*
41 * Usage:
42 *
43 * -c cpu: limit action to a single CPU (default is all CPUs)
44 * -v: verbose output (can invoke more than once)
45 * -r: read-only, don't change any settings
46 *
47 * performance
48 * Performance is paramount.
49 * Unwilling to sacrafice any performance
50 * for the sake of energy saving. (hardware default)
51 *
52 * normal
53 * Can tolerate minor performance compromise
54 * for potentially significant energy savings.
55 * (reasonable default for most desktops and servers)
56 *
57 * powersave
58 * Can tolerate significant performance hit
59 * to maximize energy savings.
60 *
61 * n
62 * a numerical value to write to the underlying MSR.
63 */
64void usage(void)
65{
66 printf("%s: [-c cpu] [-v] "
67 "(-r | 'performance' | 'normal' | 'powersave' | n)\n",
68 progname);
69 exit(1);
70}
71
72#define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0
73
74#define BIAS_PERFORMANCE 0
75#define BIAS_BALANCE 6
76#define BIAS_POWERSAVE 15
77
78void cmdline(int argc, char **argv)
79{
80 int opt;
81
82 progname = argv[0];
83
84 while ((opt = getopt(argc, argv, "+rvc:")) != -1) {
85 switch (opt) {
86 case 'c':
87 cpu = atoi(optarg);
88 break;
89 case 'r':
90 read_only = 1;
91 break;
92 case 'v':
93 verbose++;
94 break;
95 default:
96 usage();
97 }
98 }
99 /* if -r, then should be no additional optind */
100 if (read_only && (argc > optind))
101 usage();
102
103 /*
104 * if no -r , then must be one additional optind
105 */
106 if (!read_only) {
107
108 if (argc != optind + 1) {
109 printf("must supply -r or policy param\n");
110 usage();
111 }
112
113 if (!strcmp("performance", argv[optind])) {
114 new_bias = BIAS_PERFORMANCE;
115 } else if (!strcmp("normal", argv[optind])) {
116 new_bias = BIAS_BALANCE;
117 } else if (!strcmp("powersave", argv[optind])) {
118 new_bias = BIAS_POWERSAVE;
119 } else {
120 char *endptr;
121
122 new_bias = strtoull(argv[optind], &endptr, 0);
123 if (endptr == argv[optind] ||
124 new_bias > BIAS_POWERSAVE) {
125 fprintf(stderr, "invalid value: %s\n",
126 argv[optind]);
127 usage();
128 }
129 }
130 }
131}
132
133/*
134 * validate_cpuid()
135 * returns on success, quietly exits on failure (make verbose with -v)
136 */
137void validate_cpuid(void)
138{
139 unsigned int eax, ebx, ecx, edx, max_level;
140 char brand[16];
141 unsigned int fms, family, model, stepping;
142
143 eax = ebx = ecx = edx = 0;
144
145 asm("cpuid" : "=a" (max_level), "=b" (ebx), "=c" (ecx),
146 "=d" (edx) : "a" (0));
147
148 if (ebx != 0x756e6547 || edx != 0x49656e69 || ecx != 0x6c65746e) {
149 if (verbose)
150 fprintf(stderr, "%.4s%.4s%.4s != GenuineIntel",
151 (char *)&ebx, (char *)&edx, (char *)&ecx);
152 exit(1);
153 }
154
155 asm("cpuid" : "=a" (fms), "=c" (ecx), "=d" (edx) : "a" (1) : "ebx");
156 family = (fms >> 8) & 0xf;
157 model = (fms >> 4) & 0xf;
158 stepping = fms & 0xf;
159 if (family == 6 || family == 0xf)
160 model += ((fms >> 16) & 0xf) << 4;
161
162 if (verbose > 1)
163 printf("CPUID %s %d levels family:model:stepping "
164 "0x%x:%x:%x (%d:%d:%d)\n", brand, max_level,
165 family, model, stepping, family, model, stepping);
166
167 if (!(edx & (1 << 5))) {
168 if (verbose)
169 printf("CPUID: no MSR\n");
170 exit(1);
171 }
172
173 /*
174 * Support for MSR_IA32_ENERGY_PERF_BIAS
175 * is indicated by CPUID.06H.ECX.bit3
176 */
177 asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (6));
178 if (verbose)
179 printf("CPUID.06H.ECX: 0x%x\n", ecx);
180 if (!(ecx & (1 << 3))) {
181 if (verbose)
182 printf("CPUID: No MSR_IA32_ENERGY_PERF_BIAS\n");
183 exit(1);
184 }
185 return; /* success */
186}
187
188unsigned long long get_msr(int cpu, int offset)
189{
190 unsigned long long msr;
191 char msr_path[32];
192 int retval;
193 int fd;
194
195 sprintf(msr_path, "/dev/cpu/%d/msr", cpu);
196 fd = open(msr_path, O_RDONLY);
197 if (fd < 0) {
198 printf("Try \"# modprobe msr\"\n");
199 perror(msr_path);
200 exit(1);
201 }
202
203 retval = pread(fd, &msr, sizeof msr, offset);
204
205 if (retval != sizeof msr) {
206 printf("pread cpu%d 0x%x = %d\n", cpu, offset, retval);
207 exit(-2);
208 }
209 close(fd);
210 return msr;
211}
212
213unsigned long long put_msr(int cpu, unsigned long long new_msr, int offset)
214{
215 unsigned long long old_msr;
216 char msr_path[32];
217 int retval;
218 int fd;
219
220 sprintf(msr_path, "/dev/cpu/%d/msr", cpu);
221 fd = open(msr_path, O_RDWR);
222 if (fd < 0) {
223 perror(msr_path);
224 exit(1);
225 }
226
227 retval = pread(fd, &old_msr, sizeof old_msr, offset);
228 if (retval != sizeof old_msr) {
229 perror("pwrite");
230 printf("pread cpu%d 0x%x = %d\n", cpu, offset, retval);
231 exit(-2);
232 }
233
234 retval = pwrite(fd, &new_msr, sizeof new_msr, offset);
235 if (retval != sizeof new_msr) {
236 perror("pwrite");
237 printf("pwrite cpu%d 0x%x = %d\n", cpu, offset, retval);
238 exit(-2);
239 }
240
241 close(fd);
242
243 return old_msr;
244}
245
246void print_msr(int cpu)
247{
248 printf("cpu%d: 0x%016llx\n",
249 cpu, get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS));
250}
251
252void update_msr(int cpu)
253{
254 unsigned long long previous_msr;
255
256 previous_msr = put_msr(cpu, new_bias, MSR_IA32_ENERGY_PERF_BIAS);
257
258 if (verbose)
259 printf("cpu%d msr0x%x 0x%016llx -> 0x%016llx\n",
260 cpu, MSR_IA32_ENERGY_PERF_BIAS, previous_msr, new_bias);
261
262 return;
263}
264
265char *proc_stat = "/proc/stat";
266/*
267 * run func() on every cpu in /dev/cpu
268 */
269void for_every_cpu(void (func)(int))
270{
271 FILE *fp;
272 int retval;
273
274 fp = fopen(proc_stat, "r");
275 if (fp == NULL) {
276 perror(proc_stat);
277 exit(1);
278 }
279
280 retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
281 if (retval != 0) {
282 perror("/proc/stat format");
283 exit(1);
284 }
285
286 while (1) {
287 int cpu;
288
289 retval = fscanf(fp,
290 "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n",
291 &cpu);
292 if (retval != 1)
293 return;
294
295 func(cpu);
296 }
297 fclose(fp);
298}
299
300int main(int argc, char **argv)
301{
302 cmdline(argc, argv);
303
304 if (verbose > 1)
305 printf("x86_energy_perf_policy Nov 24, 2010"
306 " - Len Brown <lenb@kernel.org>\n");
307 if (verbose > 1 && !read_only)
308 printf("new_bias %lld\n", new_bias);
309
310 validate_cpuid();
311
312 if (cpu != -1) {
313 if (read_only)
314 print_msr(cpu);
315 else
316 update_msr(cpu);
317 } else {
318 if (read_only)
319 for_every_cpu(print_msr);
320 else
321 for_every_cpu(update_msr);
322 }
323
324 return 0;
325}
diff --git a/tools/slub/slabinfo.c b/tools/slub/slabinfo.c
new file mode 100644
index 000000000000..516551c9f172
--- /dev/null
+++ b/tools/slub/slabinfo.c
@@ -0,0 +1,1364 @@
1/*
2 * Slabinfo: Tool to get reports about slabs
3 *
4 * (C) 2007 sgi, Christoph Lameter
5 *
6 * Compile by:
7 *
8 * gcc -o slabinfo slabinfo.c
9 */
10#include <stdio.h>
11#include <stdlib.h>
12#include <sys/types.h>
13#include <dirent.h>
14#include <strings.h>
15#include <string.h>
16#include <unistd.h>
17#include <stdarg.h>
18#include <getopt.h>
19#include <regex.h>
20#include <errno.h>
21
22#define MAX_SLABS 500
23#define MAX_ALIASES 500
24#define MAX_NODES 1024
25
26struct slabinfo {
27 char *name;
28 int alias;
29 int refs;
30 int aliases, align, cache_dma, cpu_slabs, destroy_by_rcu;
31 int hwcache_align, object_size, objs_per_slab;
32 int sanity_checks, slab_size, store_user, trace;
33 int order, poison, reclaim_account, red_zone;
34 unsigned long partial, objects, slabs, objects_partial, objects_total;
35 unsigned long alloc_fastpath, alloc_slowpath;
36 unsigned long free_fastpath, free_slowpath;
37 unsigned long free_frozen, free_add_partial, free_remove_partial;
38 unsigned long alloc_from_partial, alloc_slab, free_slab, alloc_refill;
39 unsigned long cpuslab_flush, deactivate_full, deactivate_empty;
40 unsigned long deactivate_to_head, deactivate_to_tail;
41 unsigned long deactivate_remote_frees, order_fallback;
42 int numa[MAX_NODES];
43 int numa_partial[MAX_NODES];
44} slabinfo[MAX_SLABS];
45
46struct aliasinfo {
47 char *name;
48 char *ref;
49 struct slabinfo *slab;
50} aliasinfo[MAX_ALIASES];
51
52int slabs = 0;
53int actual_slabs = 0;
54int aliases = 0;
55int alias_targets = 0;
56int highest_node = 0;
57
58char buffer[4096];
59
60int show_empty = 0;
61int show_report = 0;
62int show_alias = 0;
63int show_slab = 0;
64int skip_zero = 1;
65int show_numa = 0;
66int show_track = 0;
67int show_first_alias = 0;
68int validate = 0;
69int shrink = 0;
70int show_inverted = 0;
71int show_single_ref = 0;
72int show_totals = 0;
73int sort_size = 0;
74int sort_active = 0;
75int set_debug = 0;
76int show_ops = 0;
77int show_activity = 0;
78
79/* Debug options */
80int sanity = 0;
81int redzone = 0;
82int poison = 0;
83int tracking = 0;
84int tracing = 0;
85
86int page_size;
87
88regex_t pattern;
89
90static void fatal(const char *x, ...)
91{
92 va_list ap;
93
94 va_start(ap, x);
95 vfprintf(stderr, x, ap);
96 va_end(ap);
97 exit(EXIT_FAILURE);
98}
99
100static void usage(void)
101{
102 printf("slabinfo 5/7/2007. (c) 2007 sgi.\n\n"
103 "slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]\n"
104 "-a|--aliases Show aliases\n"
105 "-A|--activity Most active slabs first\n"
106 "-d<options>|--debug=<options> Set/Clear Debug options\n"
107 "-D|--display-active Switch line format to activity\n"
108 "-e|--empty Show empty slabs\n"
109 "-f|--first-alias Show first alias\n"
110 "-h|--help Show usage information\n"
111 "-i|--inverted Inverted list\n"
112 "-l|--slabs Show slabs\n"
113 "-n|--numa Show NUMA information\n"
114 "-o|--ops Show kmem_cache_ops\n"
115 "-s|--shrink Shrink slabs\n"
116 "-r|--report Detailed report on single slabs\n"
117 "-S|--Size Sort by size\n"
118 "-t|--tracking Show alloc/free information\n"
119 "-T|--Totals Show summary information\n"
120 "-v|--validate Validate slabs\n"
121 "-z|--zero Include empty slabs\n"
122 "-1|--1ref Single reference\n"
123 "\nValid debug options (FZPUT may be combined)\n"
124 "a / A Switch on all debug options (=FZUP)\n"
125 "- Switch off all debug options\n"
126 "f / F Sanity Checks (SLAB_DEBUG_FREE)\n"
127 "z / Z Redzoning\n"
128 "p / P Poisoning\n"
129 "u / U Tracking\n"
130 "t / T Tracing\n"
131 );
132}
133
134static unsigned long read_obj(const char *name)
135{
136 FILE *f = fopen(name, "r");
137
138 if (!f)
139 buffer[0] = 0;
140 else {
141 if (!fgets(buffer, sizeof(buffer), f))
142 buffer[0] = 0;
143 fclose(f);
144 if (buffer[strlen(buffer)] == '\n')
145 buffer[strlen(buffer)] = 0;
146 }
147 return strlen(buffer);
148}
149
150
151/*
152 * Get the contents of an attribute
153 */
154static unsigned long get_obj(const char *name)
155{
156 if (!read_obj(name))
157 return 0;
158
159 return atol(buffer);
160}
161
162static unsigned long get_obj_and_str(const char *name, char **x)
163{
164 unsigned long result = 0;
165 char *p;
166
167 *x = NULL;
168
169 if (!read_obj(name)) {
170 x = NULL;
171 return 0;
172 }
173 result = strtoul(buffer, &p, 10);
174 while (*p == ' ')
175 p++;
176 if (*p)
177 *x = strdup(p);
178 return result;
179}
180
181static void set_obj(struct slabinfo *s, const char *name, int n)
182{
183 char x[100];
184 FILE *f;
185
186 snprintf(x, 100, "%s/%s", s->name, name);
187 f = fopen(x, "w");
188 if (!f)
189 fatal("Cannot write to %s\n", x);
190
191 fprintf(f, "%d\n", n);
192 fclose(f);
193}
194
195static unsigned long read_slab_obj(struct slabinfo *s, const char *name)
196{
197 char x[100];
198 FILE *f;
199 size_t l;
200
201 snprintf(x, 100, "%s/%s", s->name, name);
202 f = fopen(x, "r");
203 if (!f) {
204 buffer[0] = 0;
205 l = 0;
206 } else {
207 l = fread(buffer, 1, sizeof(buffer), f);
208 buffer[l] = 0;
209 fclose(f);
210 }
211 return l;
212}
213
214
215/*
216 * Put a size string together
217 */
218static int store_size(char *buffer, unsigned long value)
219{
220 unsigned long divisor = 1;
221 char trailer = 0;
222 int n;
223
224 if (value > 1000000000UL) {
225 divisor = 100000000UL;
226 trailer = 'G';
227 } else if (value > 1000000UL) {
228 divisor = 100000UL;
229 trailer = 'M';
230 } else if (value > 1000UL) {
231 divisor = 100;
232 trailer = 'K';
233 }
234
235 value /= divisor;
236 n = sprintf(buffer, "%ld",value);
237 if (trailer) {
238 buffer[n] = trailer;
239 n++;
240 buffer[n] = 0;
241 }
242 if (divisor != 1) {
243 memmove(buffer + n - 2, buffer + n - 3, 4);
244 buffer[n-2] = '.';
245 n++;
246 }
247 return n;
248}
249
250static void decode_numa_list(int *numa, char *t)
251{
252 int node;
253 int nr;
254
255 memset(numa, 0, MAX_NODES * sizeof(int));
256
257 if (!t)
258 return;
259
260 while (*t == 'N') {
261 t++;
262 node = strtoul(t, &t, 10);
263 if (*t == '=') {
264 t++;
265 nr = strtoul(t, &t, 10);
266 numa[node] = nr;
267 if (node > highest_node)
268 highest_node = node;
269 }
270 while (*t == ' ')
271 t++;
272 }
273}
274
275static void slab_validate(struct slabinfo *s)
276{
277 if (strcmp(s->name, "*") == 0)
278 return;
279
280 set_obj(s, "validate", 1);
281}
282
283static void slab_shrink(struct slabinfo *s)
284{
285 if (strcmp(s->name, "*") == 0)
286 return;
287
288 set_obj(s, "shrink", 1);
289}
290
291int line = 0;
292
293static void first_line(void)
294{
295 if (show_activity)
296 printf("Name Objects Alloc Free %%Fast Fallb O\n");
297 else
298 printf("Name Objects Objsize Space "
299 "Slabs/Part/Cpu O/S O %%Fr %%Ef Flg\n");
300}
301
302/*
303 * Find the shortest alias of a slab
304 */
305static struct aliasinfo *find_one_alias(struct slabinfo *find)
306{
307 struct aliasinfo *a;
308 struct aliasinfo *best = NULL;
309
310 for(a = aliasinfo;a < aliasinfo + aliases; a++) {
311 if (a->slab == find &&
312 (!best || strlen(best->name) < strlen(a->name))) {
313 best = a;
314 if (strncmp(a->name,"kmall", 5) == 0)
315 return best;
316 }
317 }
318 return best;
319}
320
321static unsigned long slab_size(struct slabinfo *s)
322{
323 return s->slabs * (page_size << s->order);
324}
325
326static unsigned long slab_activity(struct slabinfo *s)
327{
328 return s->alloc_fastpath + s->free_fastpath +
329 s->alloc_slowpath + s->free_slowpath;
330}
331
332static void slab_numa(struct slabinfo *s, int mode)
333{
334 int node;
335
336 if (strcmp(s->name, "*") == 0)
337 return;
338
339 if (!highest_node) {
340 printf("\n%s: No NUMA information available.\n", s->name);
341 return;
342 }
343
344 if (skip_zero && !s->slabs)
345 return;
346
347 if (!line) {
348 printf("\n%-21s:", mode ? "NUMA nodes" : "Slab");
349 for(node = 0; node <= highest_node; node++)
350 printf(" %4d", node);
351 printf("\n----------------------");
352 for(node = 0; node <= highest_node; node++)
353 printf("-----");
354 printf("\n");
355 }
356 printf("%-21s ", mode ? "All slabs" : s->name);
357 for(node = 0; node <= highest_node; node++) {
358 char b[20];
359
360 store_size(b, s->numa[node]);
361 printf(" %4s", b);
362 }
363 printf("\n");
364 if (mode) {
365 printf("%-21s ", "Partial slabs");
366 for(node = 0; node <= highest_node; node++) {
367 char b[20];
368
369 store_size(b, s->numa_partial[node]);
370 printf(" %4s", b);
371 }
372 printf("\n");
373 }
374 line++;
375}
376
377static void show_tracking(struct slabinfo *s)
378{
379 printf("\n%s: Kernel object allocation\n", s->name);
380 printf("-----------------------------------------------------------------------\n");
381 if (read_slab_obj(s, "alloc_calls"))
382 printf(buffer);
383 else
384 printf("No Data\n");
385
386 printf("\n%s: Kernel object freeing\n", s->name);
387 printf("------------------------------------------------------------------------\n");
388 if (read_slab_obj(s, "free_calls"))
389 printf(buffer);
390 else
391 printf("No Data\n");
392
393}
394
395static void ops(struct slabinfo *s)
396{
397 if (strcmp(s->name, "*") == 0)
398 return;
399
400 if (read_slab_obj(s, "ops")) {
401 printf("\n%s: kmem_cache operations\n", s->name);
402 printf("--------------------------------------------\n");
403 printf(buffer);
404 } else
405 printf("\n%s has no kmem_cache operations\n", s->name);
406}
407
408static const char *onoff(int x)
409{
410 if (x)
411 return "On ";
412 return "Off";
413}
414
415static void slab_stats(struct slabinfo *s)
416{
417 unsigned long total_alloc;
418 unsigned long total_free;
419 unsigned long total;
420
421 if (!s->alloc_slab)
422 return;
423
424 total_alloc = s->alloc_fastpath + s->alloc_slowpath;
425 total_free = s->free_fastpath + s->free_slowpath;
426
427 if (!total_alloc)
428 return;
429
430 printf("\n");
431 printf("Slab Perf Counter Alloc Free %%Al %%Fr\n");
432 printf("--------------------------------------------------\n");
433 printf("Fastpath %8lu %8lu %3lu %3lu\n",
434 s->alloc_fastpath, s->free_fastpath,
435 s->alloc_fastpath * 100 / total_alloc,
436 s->free_fastpath * 100 / total_free);
437 printf("Slowpath %8lu %8lu %3lu %3lu\n",
438 total_alloc - s->alloc_fastpath, s->free_slowpath,
439 (total_alloc - s->alloc_fastpath) * 100 / total_alloc,
440 s->free_slowpath * 100 / total_free);
441 printf("Page Alloc %8lu %8lu %3lu %3lu\n",
442 s->alloc_slab, s->free_slab,
443 s->alloc_slab * 100 / total_alloc,
444 s->free_slab * 100 / total_free);
445 printf("Add partial %8lu %8lu %3lu %3lu\n",
446 s->deactivate_to_head + s->deactivate_to_tail,
447 s->free_add_partial,
448 (s->deactivate_to_head + s->deactivate_to_tail) * 100 / total_alloc,
449 s->free_add_partial * 100 / total_free);
450 printf("Remove partial %8lu %8lu %3lu %3lu\n",
451 s->alloc_from_partial, s->free_remove_partial,
452 s->alloc_from_partial * 100 / total_alloc,
453 s->free_remove_partial * 100 / total_free);
454
455 printf("RemoteObj/SlabFrozen %8lu %8lu %3lu %3lu\n",
456 s->deactivate_remote_frees, s->free_frozen,
457 s->deactivate_remote_frees * 100 / total_alloc,
458 s->free_frozen * 100 / total_free);
459
460 printf("Total %8lu %8lu\n\n", total_alloc, total_free);
461
462 if (s->cpuslab_flush)
463 printf("Flushes %8lu\n", s->cpuslab_flush);
464
465 if (s->alloc_refill)
466 printf("Refill %8lu\n", s->alloc_refill);
467
468 total = s->deactivate_full + s->deactivate_empty +
469 s->deactivate_to_head + s->deactivate_to_tail;
470
471 if (total)
472 printf("Deactivate Full=%lu(%lu%%) Empty=%lu(%lu%%) "
473 "ToHead=%lu(%lu%%) ToTail=%lu(%lu%%)\n",
474 s->deactivate_full, (s->deactivate_full * 100) / total,
475 s->deactivate_empty, (s->deactivate_empty * 100) / total,
476 s->deactivate_to_head, (s->deactivate_to_head * 100) / total,
477 s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total);
478}
479
480static void report(struct slabinfo *s)
481{
482 if (strcmp(s->name, "*") == 0)
483 return;
484
485 printf("\nSlabcache: %-20s Aliases: %2d Order : %2d Objects: %lu\n",
486 s->name, s->aliases, s->order, s->objects);
487 if (s->hwcache_align)
488 printf("** Hardware cacheline aligned\n");
489 if (s->cache_dma)
490 printf("** Memory is allocated in a special DMA zone\n");
491 if (s->destroy_by_rcu)
492 printf("** Slabs are destroyed via RCU\n");
493 if (s->reclaim_account)
494 printf("** Reclaim accounting active\n");
495
496 printf("\nSizes (bytes) Slabs Debug Memory\n");
497 printf("------------------------------------------------------------------------\n");
498 printf("Object : %7d Total : %7ld Sanity Checks : %s Total: %7ld\n",
499 s->object_size, s->slabs, onoff(s->sanity_checks),
500 s->slabs * (page_size << s->order));
501 printf("SlabObj: %7d Full : %7ld Redzoning : %s Used : %7ld\n",
502 s->slab_size, s->slabs - s->partial - s->cpu_slabs,
503 onoff(s->red_zone), s->objects * s->object_size);
504 printf("SlabSiz: %7d Partial: %7ld Poisoning : %s Loss : %7ld\n",
505 page_size << s->order, s->partial, onoff(s->poison),
506 s->slabs * (page_size << s->order) - s->objects * s->object_size);
507 printf("Loss : %7d CpuSlab: %7d Tracking : %s Lalig: %7ld\n",
508 s->slab_size - s->object_size, s->cpu_slabs, onoff(s->store_user),
509 (s->slab_size - s->object_size) * s->objects);
510 printf("Align : %7d Objects: %7d Tracing : %s Lpadd: %7ld\n",
511 s->align, s->objs_per_slab, onoff(s->trace),
512 ((page_size << s->order) - s->objs_per_slab * s->slab_size) *
513 s->slabs);
514
515 ops(s);
516 show_tracking(s);
517 slab_numa(s, 1);
518 slab_stats(s);
519}
520
521static void slabcache(struct slabinfo *s)
522{
523 char size_str[20];
524 char dist_str[40];
525 char flags[20];
526 char *p = flags;
527
528 if (strcmp(s->name, "*") == 0)
529 return;
530
531 if (actual_slabs == 1) {
532 report(s);
533 return;
534 }
535
536 if (skip_zero && !show_empty && !s->slabs)
537 return;
538
539 if (show_empty && s->slabs)
540 return;
541
542 store_size(size_str, slab_size(s));
543 snprintf(dist_str, 40, "%lu/%lu/%d", s->slabs - s->cpu_slabs,
544 s->partial, s->cpu_slabs);
545
546 if (!line++)
547 first_line();
548
549 if (s->aliases)
550 *p++ = '*';
551 if (s->cache_dma)
552 *p++ = 'd';
553 if (s->hwcache_align)
554 *p++ = 'A';
555 if (s->poison)
556 *p++ = 'P';
557 if (s->reclaim_account)
558 *p++ = 'a';
559 if (s->red_zone)
560 *p++ = 'Z';
561 if (s->sanity_checks)
562 *p++ = 'F';
563 if (s->store_user)
564 *p++ = 'U';
565 if (s->trace)
566 *p++ = 'T';
567
568 *p = 0;
569 if (show_activity) {
570 unsigned long total_alloc;
571 unsigned long total_free;
572
573 total_alloc = s->alloc_fastpath + s->alloc_slowpath;
574 total_free = s->free_fastpath + s->free_slowpath;
575
576 printf("%-21s %8ld %10ld %10ld %3ld %3ld %5ld %1d\n",
577 s->name, s->objects,
578 total_alloc, total_free,
579 total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0,
580 total_free ? (s->free_fastpath * 100 / total_free) : 0,
581 s->order_fallback, s->order);
582 }
583 else
584 printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n",
585 s->name, s->objects, s->object_size, size_str, dist_str,
586 s->objs_per_slab, s->order,
587 s->slabs ? (s->partial * 100) / s->slabs : 100,
588 s->slabs ? (s->objects * s->object_size * 100) /
589 (s->slabs * (page_size << s->order)) : 100,
590 flags);
591}
592
593/*
594 * Analyze debug options. Return false if something is amiss.
595 */
596static int debug_opt_scan(char *opt)
597{
598 if (!opt || !opt[0] || strcmp(opt, "-") == 0)
599 return 1;
600
601 if (strcasecmp(opt, "a") == 0) {
602 sanity = 1;
603 poison = 1;
604 redzone = 1;
605 tracking = 1;
606 return 1;
607 }
608
609 for ( ; *opt; opt++)
610 switch (*opt) {
611 case 'F' : case 'f':
612 if (sanity)
613 return 0;
614 sanity = 1;
615 break;
616 case 'P' : case 'p':
617 if (poison)
618 return 0;
619 poison = 1;
620 break;
621
622 case 'Z' : case 'z':
623 if (redzone)
624 return 0;
625 redzone = 1;
626 break;
627
628 case 'U' : case 'u':
629 if (tracking)
630 return 0;
631 tracking = 1;
632 break;
633
634 case 'T' : case 't':
635 if (tracing)
636 return 0;
637 tracing = 1;
638 break;
639 default:
640 return 0;
641 }
642 return 1;
643}
644
645static int slab_empty(struct slabinfo *s)
646{
647 if (s->objects > 0)
648 return 0;
649
650 /*
651 * We may still have slabs even if there are no objects. Shrinking will
652 * remove them.
653 */
654 if (s->slabs != 0)
655 set_obj(s, "shrink", 1);
656
657 return 1;
658}
659
660static void slab_debug(struct slabinfo *s)
661{
662 if (strcmp(s->name, "*") == 0)
663 return;
664
665 if (sanity && !s->sanity_checks) {
666 set_obj(s, "sanity", 1);
667 }
668 if (!sanity && s->sanity_checks) {
669 if (slab_empty(s))
670 set_obj(s, "sanity", 0);
671 else
672 fprintf(stderr, "%s not empty cannot disable sanity checks\n", s->name);
673 }
674 if (redzone && !s->red_zone) {
675 if (slab_empty(s))
676 set_obj(s, "red_zone", 1);
677 else
678 fprintf(stderr, "%s not empty cannot enable redzoning\n", s->name);
679 }
680 if (!redzone && s->red_zone) {
681 if (slab_empty(s))
682 set_obj(s, "red_zone", 0);
683 else
684 fprintf(stderr, "%s not empty cannot disable redzoning\n", s->name);
685 }
686 if (poison && !s->poison) {
687 if (slab_empty(s))
688 set_obj(s, "poison", 1);
689 else
690 fprintf(stderr, "%s not empty cannot enable poisoning\n", s->name);
691 }
692 if (!poison && s->poison) {
693 if (slab_empty(s))
694 set_obj(s, "poison", 0);
695 else
696 fprintf(stderr, "%s not empty cannot disable poisoning\n", s->name);
697 }
698 if (tracking && !s->store_user) {
699 if (slab_empty(s))
700 set_obj(s, "store_user", 1);
701 else
702 fprintf(stderr, "%s not empty cannot enable tracking\n", s->name);
703 }
704 if (!tracking && s->store_user) {
705 if (slab_empty(s))
706 set_obj(s, "store_user", 0);
707 else
708 fprintf(stderr, "%s not empty cannot disable tracking\n", s->name);
709 }
710 if (tracing && !s->trace) {
711 if (slabs == 1)
712 set_obj(s, "trace", 1);
713 else
714 fprintf(stderr, "%s can only enable trace for one slab at a time\n", s->name);
715 }
716 if (!tracing && s->trace)
717 set_obj(s, "trace", 1);
718}
719
720static void totals(void)
721{
722 struct slabinfo *s;
723
724 int used_slabs = 0;
725 char b1[20], b2[20], b3[20], b4[20];
726 unsigned long long max = 1ULL << 63;
727
728 /* Object size */
729 unsigned long long min_objsize = max, max_objsize = 0, avg_objsize;
730
731 /* Number of partial slabs in a slabcache */
732 unsigned long long min_partial = max, max_partial = 0,
733 avg_partial, total_partial = 0;
734
735 /* Number of slabs in a slab cache */
736 unsigned long long min_slabs = max, max_slabs = 0,
737 avg_slabs, total_slabs = 0;
738
739 /* Size of the whole slab */
740 unsigned long long min_size = max, max_size = 0,
741 avg_size, total_size = 0;
742
743 /* Bytes used for object storage in a slab */
744 unsigned long long min_used = max, max_used = 0,
745 avg_used, total_used = 0;
746
747 /* Waste: Bytes used for alignment and padding */
748 unsigned long long min_waste = max, max_waste = 0,
749 avg_waste, total_waste = 0;
750 /* Number of objects in a slab */
751 unsigned long long min_objects = max, max_objects = 0,
752 avg_objects, total_objects = 0;
753 /* Waste per object */
754 unsigned long long min_objwaste = max,
755 max_objwaste = 0, avg_objwaste,
756 total_objwaste = 0;
757
758 /* Memory per object */
759 unsigned long long min_memobj = max,
760 max_memobj = 0, avg_memobj,
761 total_objsize = 0;
762
763 /* Percentage of partial slabs per slab */
764 unsigned long min_ppart = 100, max_ppart = 0,
765 avg_ppart, total_ppart = 0;
766
767 /* Number of objects in partial slabs */
768 unsigned long min_partobj = max, max_partobj = 0,
769 avg_partobj, total_partobj = 0;
770
771 /* Percentage of partial objects of all objects in a slab */
772 unsigned long min_ppartobj = 100, max_ppartobj = 0,
773 avg_ppartobj, total_ppartobj = 0;
774
775
776 for (s = slabinfo; s < slabinfo + slabs; s++) {
777 unsigned long long size;
778 unsigned long used;
779 unsigned long long wasted;
780 unsigned long long objwaste;
781 unsigned long percentage_partial_slabs;
782 unsigned long percentage_partial_objs;
783
784 if (!s->slabs || !s->objects)
785 continue;
786
787 used_slabs++;
788
789 size = slab_size(s);
790 used = s->objects * s->object_size;
791 wasted = size - used;
792 objwaste = s->slab_size - s->object_size;
793
794 percentage_partial_slabs = s->partial * 100 / s->slabs;
795 if (percentage_partial_slabs > 100)
796 percentage_partial_slabs = 100;
797
798 percentage_partial_objs = s->objects_partial * 100
799 / s->objects;
800
801 if (percentage_partial_objs > 100)
802 percentage_partial_objs = 100;
803
804 if (s->object_size < min_objsize)
805 min_objsize = s->object_size;
806 if (s->partial < min_partial)
807 min_partial = s->partial;
808 if (s->slabs < min_slabs)
809 min_slabs = s->slabs;
810 if (size < min_size)
811 min_size = size;
812 if (wasted < min_waste)
813 min_waste = wasted;
814 if (objwaste < min_objwaste)
815 min_objwaste = objwaste;
816 if (s->objects < min_objects)
817 min_objects = s->objects;
818 if (used < min_used)
819 min_used = used;
820 if (s->objects_partial < min_partobj)
821 min_partobj = s->objects_partial;
822 if (percentage_partial_slabs < min_ppart)
823 min_ppart = percentage_partial_slabs;
824 if (percentage_partial_objs < min_ppartobj)
825 min_ppartobj = percentage_partial_objs;
826 if (s->slab_size < min_memobj)
827 min_memobj = s->slab_size;
828
829 if (s->object_size > max_objsize)
830 max_objsize = s->object_size;
831 if (s->partial > max_partial)
832 max_partial = s->partial;
833 if (s->slabs > max_slabs)
834 max_slabs = s->slabs;
835 if (size > max_size)
836 max_size = size;
837 if (wasted > max_waste)
838 max_waste = wasted;
839 if (objwaste > max_objwaste)
840 max_objwaste = objwaste;
841 if (s->objects > max_objects)
842 max_objects = s->objects;
843 if (used > max_used)
844 max_used = used;
845 if (s->objects_partial > max_partobj)
846 max_partobj = s->objects_partial;
847 if (percentage_partial_slabs > max_ppart)
848 max_ppart = percentage_partial_slabs;
849 if (percentage_partial_objs > max_ppartobj)
850 max_ppartobj = percentage_partial_objs;
851 if (s->slab_size > max_memobj)
852 max_memobj = s->slab_size;
853
854 total_partial += s->partial;
855 total_slabs += s->slabs;
856 total_size += size;
857 total_waste += wasted;
858
859 total_objects += s->objects;
860 total_used += used;
861 total_partobj += s->objects_partial;
862 total_ppart += percentage_partial_slabs;
863 total_ppartobj += percentage_partial_objs;
864
865 total_objwaste += s->objects * objwaste;
866 total_objsize += s->objects * s->slab_size;
867 }
868
869 if (!total_objects) {
870 printf("No objects\n");
871 return;
872 }
873 if (!used_slabs) {
874 printf("No slabs\n");
875 return;
876 }
877
878 /* Per slab averages */
879 avg_partial = total_partial / used_slabs;
880 avg_slabs = total_slabs / used_slabs;
881 avg_size = total_size / used_slabs;
882 avg_waste = total_waste / used_slabs;
883
884 avg_objects = total_objects / used_slabs;
885 avg_used = total_used / used_slabs;
886 avg_partobj = total_partobj / used_slabs;
887 avg_ppart = total_ppart / used_slabs;
888 avg_ppartobj = total_ppartobj / used_slabs;
889
890 /* Per object object sizes */
891 avg_objsize = total_used / total_objects;
892 avg_objwaste = total_objwaste / total_objects;
893 avg_partobj = total_partobj * 100 / total_objects;
894 avg_memobj = total_objsize / total_objects;
895
896 printf("Slabcache Totals\n");
897 printf("----------------\n");
898 printf("Slabcaches : %3d Aliases : %3d->%-3d Active: %3d\n",
899 slabs, aliases, alias_targets, used_slabs);
900
901 store_size(b1, total_size);store_size(b2, total_waste);
902 store_size(b3, total_waste * 100 / total_used);
903 printf("Memory used: %6s # Loss : %6s MRatio:%6s%%\n", b1, b2, b3);
904
905 store_size(b1, total_objects);store_size(b2, total_partobj);
906 store_size(b3, total_partobj * 100 / total_objects);
907 printf("# Objects : %6s # PartObj: %6s ORatio:%6s%%\n", b1, b2, b3);
908
909 printf("\n");
910 printf("Per Cache Average Min Max Total\n");
911 printf("---------------------------------------------------------\n");
912
913 store_size(b1, avg_objects);store_size(b2, min_objects);
914 store_size(b3, max_objects);store_size(b4, total_objects);
915 printf("#Objects %10s %10s %10s %10s\n",
916 b1, b2, b3, b4);
917
918 store_size(b1, avg_slabs);store_size(b2, min_slabs);
919 store_size(b3, max_slabs);store_size(b4, total_slabs);
920 printf("#Slabs %10s %10s %10s %10s\n",
921 b1, b2, b3, b4);
922
923 store_size(b1, avg_partial);store_size(b2, min_partial);
924 store_size(b3, max_partial);store_size(b4, total_partial);
925 printf("#PartSlab %10s %10s %10s %10s\n",
926 b1, b2, b3, b4);
927 store_size(b1, avg_ppart);store_size(b2, min_ppart);
928 store_size(b3, max_ppart);
929 store_size(b4, total_partial * 100 / total_slabs);
930 printf("%%PartSlab%10s%% %10s%% %10s%% %10s%%\n",
931 b1, b2, b3, b4);
932
933 store_size(b1, avg_partobj);store_size(b2, min_partobj);
934 store_size(b3, max_partobj);
935 store_size(b4, total_partobj);
936 printf("PartObjs %10s %10s %10s %10s\n",
937 b1, b2, b3, b4);
938
939 store_size(b1, avg_ppartobj);store_size(b2, min_ppartobj);
940 store_size(b3, max_ppartobj);
941 store_size(b4, total_partobj * 100 / total_objects);
942 printf("%% PartObj%10s%% %10s%% %10s%% %10s%%\n",
943 b1, b2, b3, b4);
944
945 store_size(b1, avg_size);store_size(b2, min_size);
946 store_size(b3, max_size);store_size(b4, total_size);
947 printf("Memory %10s %10s %10s %10s\n",
948 b1, b2, b3, b4);
949
950 store_size(b1, avg_used);store_size(b2, min_used);
951 store_size(b3, max_used);store_size(b4, total_used);
952 printf("Used %10s %10s %10s %10s\n",
953 b1, b2, b3, b4);
954
955 store_size(b1, avg_waste);store_size(b2, min_waste);
956 store_size(b3, max_waste);store_size(b4, total_waste);
957 printf("Loss %10s %10s %10s %10s\n",
958 b1, b2, b3, b4);
959
960 printf("\n");
961 printf("Per Object Average Min Max\n");
962 printf("---------------------------------------------\n");
963
964 store_size(b1, avg_memobj);store_size(b2, min_memobj);
965 store_size(b3, max_memobj);
966 printf("Memory %10s %10s %10s\n",
967 b1, b2, b3);
968 store_size(b1, avg_objsize);store_size(b2, min_objsize);
969 store_size(b3, max_objsize);
970 printf("User %10s %10s %10s\n",
971 b1, b2, b3);
972
973 store_size(b1, avg_objwaste);store_size(b2, min_objwaste);
974 store_size(b3, max_objwaste);
975 printf("Loss %10s %10s %10s\n",
976 b1, b2, b3);
977}
978
979static void sort_slabs(void)
980{
981 struct slabinfo *s1,*s2;
982
983 for (s1 = slabinfo; s1 < slabinfo + slabs; s1++) {
984 for (s2 = s1 + 1; s2 < slabinfo + slabs; s2++) {
985 int result;
986
987 if (sort_size)
988 result = slab_size(s1) < slab_size(s2);
989 else if (sort_active)
990 result = slab_activity(s1) < slab_activity(s2);
991 else
992 result = strcasecmp(s1->name, s2->name);
993
994 if (show_inverted)
995 result = -result;
996
997 if (result > 0) {
998 struct slabinfo t;
999
1000 memcpy(&t, s1, sizeof(struct slabinfo));
1001 memcpy(s1, s2, sizeof(struct slabinfo));
1002 memcpy(s2, &t, sizeof(struct slabinfo));
1003 }
1004 }
1005 }
1006}
1007
1008static void sort_aliases(void)
1009{
1010 struct aliasinfo *a1,*a2;
1011
1012 for (a1 = aliasinfo; a1 < aliasinfo + aliases; a1++) {
1013 for (a2 = a1 + 1; a2 < aliasinfo + aliases; a2++) {
1014 char *n1, *n2;
1015
1016 n1 = a1->name;
1017 n2 = a2->name;
1018 if (show_alias && !show_inverted) {
1019 n1 = a1->ref;
1020 n2 = a2->ref;
1021 }
1022 if (strcasecmp(n1, n2) > 0) {
1023 struct aliasinfo t;
1024
1025 memcpy(&t, a1, sizeof(struct aliasinfo));
1026 memcpy(a1, a2, sizeof(struct aliasinfo));
1027 memcpy(a2, &t, sizeof(struct aliasinfo));
1028 }
1029 }
1030 }
1031}
1032
1033static void link_slabs(void)
1034{
1035 struct aliasinfo *a;
1036 struct slabinfo *s;
1037
1038 for (a = aliasinfo; a < aliasinfo + aliases; a++) {
1039
1040 for (s = slabinfo; s < slabinfo + slabs; s++)
1041 if (strcmp(a->ref, s->name) == 0) {
1042 a->slab = s;
1043 s->refs++;
1044 break;
1045 }
1046 if (s == slabinfo + slabs)
1047 fatal("Unresolved alias %s\n", a->ref);
1048 }
1049}
1050
1051static void alias(void)
1052{
1053 struct aliasinfo *a;
1054 char *active = NULL;
1055
1056 sort_aliases();
1057 link_slabs();
1058
1059 for(a = aliasinfo; a < aliasinfo + aliases; a++) {
1060
1061 if (!show_single_ref && a->slab->refs == 1)
1062 continue;
1063
1064 if (!show_inverted) {
1065 if (active) {
1066 if (strcmp(a->slab->name, active) == 0) {
1067 printf(" %s", a->name);
1068 continue;
1069 }
1070 }
1071 printf("\n%-12s <- %s", a->slab->name, a->name);
1072 active = a->slab->name;
1073 }
1074 else
1075 printf("%-20s -> %s\n", a->name, a->slab->name);
1076 }
1077 if (active)
1078 printf("\n");
1079}
1080
1081
1082static void rename_slabs(void)
1083{
1084 struct slabinfo *s;
1085 struct aliasinfo *a;
1086
1087 for (s = slabinfo; s < slabinfo + slabs; s++) {
1088 if (*s->name != ':')
1089 continue;
1090
1091 if (s->refs > 1 && !show_first_alias)
1092 continue;
1093
1094 a = find_one_alias(s);
1095
1096 if (a)
1097 s->name = a->name;
1098 else {
1099 s->name = "*";
1100 actual_slabs--;
1101 }
1102 }
1103}
1104
1105static int slab_mismatch(char *slab)
1106{
1107 return regexec(&pattern, slab, 0, NULL, 0);
1108}
1109
1110static void read_slab_dir(void)
1111{
1112 DIR *dir;
1113 struct dirent *de;
1114 struct slabinfo *slab = slabinfo;
1115 struct aliasinfo *alias = aliasinfo;
1116 char *p;
1117 char *t;
1118 int count;
1119
1120 if (chdir("/sys/kernel/slab") && chdir("/sys/slab"))
1121 fatal("SYSFS support for SLUB not active\n");
1122
1123 dir = opendir(".");
1124 while ((de = readdir(dir))) {
1125 if (de->d_name[0] == '.' ||
1126 (de->d_name[0] != ':' && slab_mismatch(de->d_name)))
1127 continue;
1128 switch (de->d_type) {
1129 case DT_LNK:
1130 alias->name = strdup(de->d_name);
1131 count = readlink(de->d_name, buffer, sizeof(buffer));
1132
1133 if (count < 0)
1134 fatal("Cannot read symlink %s\n", de->d_name);
1135
1136 buffer[count] = 0;
1137 p = buffer + count;
1138 while (p > buffer && p[-1] != '/')
1139 p--;
1140 alias->ref = strdup(p);
1141 alias++;
1142 break;
1143 case DT_DIR:
1144 if (chdir(de->d_name))
1145 fatal("Unable to access slab %s\n", slab->name);
1146 slab->name = strdup(de->d_name);
1147 slab->alias = 0;
1148 slab->refs = 0;
1149 slab->aliases = get_obj("aliases");
1150 slab->align = get_obj("align");
1151 slab->cache_dma = get_obj("cache_dma");
1152 slab->cpu_slabs = get_obj("cpu_slabs");
1153 slab->destroy_by_rcu = get_obj("destroy_by_rcu");
1154 slab->hwcache_align = get_obj("hwcache_align");
1155 slab->object_size = get_obj("object_size");
1156 slab->objects = get_obj("objects");
1157 slab->objects_partial = get_obj("objects_partial");
1158 slab->objects_total = get_obj("objects_total");
1159 slab->objs_per_slab = get_obj("objs_per_slab");
1160 slab->order = get_obj("order");
1161 slab->partial = get_obj("partial");
1162 slab->partial = get_obj_and_str("partial", &t);
1163 decode_numa_list(slab->numa_partial, t);
1164 free(t);
1165 slab->poison = get_obj("poison");
1166 slab->reclaim_account = get_obj("reclaim_account");
1167 slab->red_zone = get_obj("red_zone");
1168 slab->sanity_checks = get_obj("sanity_checks");
1169 slab->slab_size = get_obj("slab_size");
1170 slab->slabs = get_obj_and_str("slabs", &t);
1171 decode_numa_list(slab->numa, t);
1172 free(t);
1173 slab->store_user = get_obj("store_user");
1174 slab->trace = get_obj("trace");
1175 slab->alloc_fastpath = get_obj("alloc_fastpath");
1176 slab->alloc_slowpath = get_obj("alloc_slowpath");
1177 slab->free_fastpath = get_obj("free_fastpath");
1178 slab->free_slowpath = get_obj("free_slowpath");
1179 slab->free_frozen= get_obj("free_frozen");
1180 slab->free_add_partial = get_obj("free_add_partial");
1181 slab->free_remove_partial = get_obj("free_remove_partial");
1182 slab->alloc_from_partial = get_obj("alloc_from_partial");
1183 slab->alloc_slab = get_obj("alloc_slab");
1184 slab->alloc_refill = get_obj("alloc_refill");
1185 slab->free_slab = get_obj("free_slab");
1186 slab->cpuslab_flush = get_obj("cpuslab_flush");
1187 slab->deactivate_full = get_obj("deactivate_full");
1188 slab->deactivate_empty = get_obj("deactivate_empty");
1189 slab->deactivate_to_head = get_obj("deactivate_to_head");
1190 slab->deactivate_to_tail = get_obj("deactivate_to_tail");
1191 slab->deactivate_remote_frees = get_obj("deactivate_remote_frees");
1192 slab->order_fallback = get_obj("order_fallback");
1193 chdir("..");
1194 if (slab->name[0] == ':')
1195 alias_targets++;
1196 slab++;
1197 break;
1198 default :
1199 fatal("Unknown file type %lx\n", de->d_type);
1200 }
1201 }
1202 closedir(dir);
1203 slabs = slab - slabinfo;
1204 actual_slabs = slabs;
1205 aliases = alias - aliasinfo;
1206 if (slabs > MAX_SLABS)
1207 fatal("Too many slabs\n");
1208 if (aliases > MAX_ALIASES)
1209 fatal("Too many aliases\n");
1210}
1211
1212static void output_slabs(void)
1213{
1214 struct slabinfo *slab;
1215
1216 for (slab = slabinfo; slab < slabinfo + slabs; slab++) {
1217
1218 if (slab->alias)
1219 continue;
1220
1221
1222 if (show_numa)
1223 slab_numa(slab, 0);
1224 else if (show_track)
1225 show_tracking(slab);
1226 else if (validate)
1227 slab_validate(slab);
1228 else if (shrink)
1229 slab_shrink(slab);
1230 else if (set_debug)
1231 slab_debug(slab);
1232 else if (show_ops)
1233 ops(slab);
1234 else if (show_slab)
1235 slabcache(slab);
1236 else if (show_report)
1237 report(slab);
1238 }
1239}
1240
1241struct option opts[] = {
1242 { "aliases", 0, NULL, 'a' },
1243 { "activity", 0, NULL, 'A' },
1244 { "debug", 2, NULL, 'd' },
1245 { "display-activity", 0, NULL, 'D' },
1246 { "empty", 0, NULL, 'e' },
1247 { "first-alias", 0, NULL, 'f' },
1248 { "help", 0, NULL, 'h' },
1249 { "inverted", 0, NULL, 'i'},
1250 { "numa", 0, NULL, 'n' },
1251 { "ops", 0, NULL, 'o' },
1252 { "report", 0, NULL, 'r' },
1253 { "shrink", 0, NULL, 's' },
1254 { "slabs", 0, NULL, 'l' },
1255 { "track", 0, NULL, 't'},
1256 { "validate", 0, NULL, 'v' },
1257 { "zero", 0, NULL, 'z' },
1258 { "1ref", 0, NULL, '1'},
1259 { NULL, 0, NULL, 0 }
1260};
1261
1262int main(int argc, char *argv[])
1263{
1264 int c;
1265 int err;
1266 char *pattern_source;
1267
1268 page_size = getpagesize();
1269
1270 while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTS",
1271 opts, NULL)) != -1)
1272 switch (c) {
1273 case '1':
1274 show_single_ref = 1;
1275 break;
1276 case 'a':
1277 show_alias = 1;
1278 break;
1279 case 'A':
1280 sort_active = 1;
1281 break;
1282 case 'd':
1283 set_debug = 1;
1284 if (!debug_opt_scan(optarg))
1285 fatal("Invalid debug option '%s'\n", optarg);
1286 break;
1287 case 'D':
1288 show_activity = 1;
1289 break;
1290 case 'e':
1291 show_empty = 1;
1292 break;
1293 case 'f':
1294 show_first_alias = 1;
1295 break;
1296 case 'h':
1297 usage();
1298 return 0;
1299 case 'i':
1300 show_inverted = 1;
1301 break;
1302 case 'n':
1303 show_numa = 1;
1304 break;
1305 case 'o':
1306 show_ops = 1;
1307 break;
1308 case 'r':
1309 show_report = 1;
1310 break;
1311 case 's':
1312 shrink = 1;
1313 break;
1314 case 'l':
1315 show_slab = 1;
1316 break;
1317 case 't':
1318 show_track = 1;
1319 break;
1320 case 'v':
1321 validate = 1;
1322 break;
1323 case 'z':
1324 skip_zero = 0;
1325 break;
1326 case 'T':
1327 show_totals = 1;
1328 break;
1329 case 'S':
1330 sort_size = 1;
1331 break;
1332
1333 default:
1334 fatal("%s: Invalid option '%c'\n", argv[0], optopt);
1335
1336 }
1337
1338 if (!show_slab && !show_alias && !show_track && !show_report
1339 && !validate && !shrink && !set_debug && !show_ops)
1340 show_slab = 1;
1341
1342 if (argc > optind)
1343 pattern_source = argv[optind];
1344 else
1345 pattern_source = ".*";
1346
1347 err = regcomp(&pattern, pattern_source, REG_ICASE|REG_NOSUB);
1348 if (err)
1349 fatal("%s: Invalid pattern '%s' code %d\n",
1350 argv[0], pattern_source, err);
1351 read_slab_dir();
1352 if (show_alias)
1353 alias();
1354 else
1355 if (show_totals)
1356 totals();
1357 else {
1358 link_slabs();
1359 rename_slabs();
1360 sort_slabs();
1361 output_slabs();
1362 }
1363 return 0;
1364}
diff --git a/tools/testing/ktest/compare-ktest-sample.pl b/tools/testing/ktest/compare-ktest-sample.pl
new file mode 100755
index 000000000000..9a571e71683c
--- /dev/null
+++ b/tools/testing/ktest/compare-ktest-sample.pl
@@ -0,0 +1,30 @@
1#!/usr/bin/perl
2
3open (IN,"ktest.pl");
4while (<IN>) {
5 if (/\$opt\{"?([A-Z].*?)(\[.*\])?"?\}/ ||
6 /set_test_option\("(.*?)"/) {
7 $opt{$1} = 1;
8 }
9}
10close IN;
11
12open (IN, "sample.conf");
13while (<IN>) {
14 if (/^\s*#?\s*(\S+)\s*=/) {
15 $samp{$1} = 1;
16 }
17}
18close IN;
19
20foreach $opt (keys %opt) {
21 if (!defined($samp{$opt})) {
22 print "opt = $opt\n";
23 }
24}
25
26foreach $samp (keys %samp) {
27 if (!defined($opt{$samp})) {
28 print "samp = $samp\n";
29 }
30}
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
new file mode 100755
index 000000000000..e1c62eeb88f5
--- /dev/null
+++ b/tools/testing/ktest/ktest.pl
@@ -0,0 +1,2023 @@
1#!/usr/bin/perl -w
2#
3# Copywrite 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4# Licensed under the terms of the GNU GPL License version 2
5#
6
7use strict;
8use IPC::Open2;
9use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10use File::Path qw(mkpath);
11use File::Copy qw(cp);
12use FileHandle;
13
14my $VERSION = "0.2";
15
16$| = 1;
17
18my %opt;
19my %repeat_tests;
20my %repeats;
21my %default;
22
23#default opts
24$default{"NUM_TESTS"} = 1;
25$default{"REBOOT_TYPE"} = "grub";
26$default{"TEST_TYPE"} = "test";
27$default{"BUILD_TYPE"} = "randconfig";
28$default{"MAKE_CMD"} = "make";
29$default{"TIMEOUT"} = 120;
30$default{"TMP_DIR"} = "/tmp/ktest";
31$default{"SLEEP_TIME"} = 60; # sleep time between tests
32$default{"BUILD_NOCLEAN"} = 0;
33$default{"REBOOT_ON_ERROR"} = 0;
34$default{"POWEROFF_ON_ERROR"} = 0;
35$default{"REBOOT_ON_SUCCESS"} = 1;
36$default{"POWEROFF_ON_SUCCESS"} = 0;
37$default{"BUILD_OPTIONS"} = "";
38$default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects
39$default{"CLEAR_LOG"} = 0;
40$default{"SUCCESS_LINE"} = "login:";
41$default{"BOOTED_TIMEOUT"} = 1;
42$default{"DIE_ON_FAILURE"} = 1;
43$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
44$default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
45$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
46$default{"STOP_AFTER_SUCCESS"} = 10;
47$default{"STOP_AFTER_FAILURE"} = 60;
48$default{"LOCALVERSION"} = "-test";
49
50my $ktest_config;
51my $version;
52my $machine;
53my $ssh_user;
54my $tmpdir;
55my $builddir;
56my $outputdir;
57my $output_config;
58my $test_type;
59my $build_type;
60my $build_options;
61my $reboot_type;
62my $reboot_script;
63my $power_cycle;
64my $reboot;
65my $reboot_on_error;
66my $poweroff_on_error;
67my $die_on_failure;
68my $powercycle_after_reboot;
69my $poweroff_after_halt;
70my $ssh_exec;
71my $scp_to_target;
72my $power_off;
73my $grub_menu;
74my $grub_number;
75my $target;
76my $make;
77my $post_install;
78my $noclean;
79my $minconfig;
80my $addconfig;
81my $in_bisect = 0;
82my $bisect_bad = "";
83my $reverse_bisect;
84my $in_patchcheck = 0;
85my $run_test;
86my $redirect;
87my $buildlog;
88my $dmesg;
89my $monitor_fp;
90my $monitor_pid;
91my $monitor_cnt = 0;
92my $sleep_time;
93my $bisect_sleep_time;
94my $store_failures;
95my $timeout;
96my $booted_timeout;
97my $console;
98my $success_line;
99my $stop_after_success;
100my $stop_after_failure;
101my $build_target;
102my $target_image;
103my $localversion;
104my $iteration = 0;
105my $successes = 0;
106
107my %entered_configs;
108my %config_help;
109
110$config_help{"MACHINE"} = << "EOF"
111 The machine hostname that you will test.
112EOF
113 ;
114$config_help{"SSH_USER"} = << "EOF"
115 The box is expected to have ssh on normal bootup, provide the user
116 (most likely root, since you need privileged operations)
117EOF
118 ;
119$config_help{"BUILD_DIR"} = << "EOF"
120 The directory that contains the Linux source code (full path).
121EOF
122 ;
123$config_help{"OUTPUT_DIR"} = << "EOF"
124 The directory that the objects will be built (full path).
125 (can not be same as BUILD_DIR)
126EOF
127 ;
128$config_help{"BUILD_TARGET"} = << "EOF"
129 The location of the compiled file to copy to the target.
130 (relative to OUTPUT_DIR)
131EOF
132 ;
133$config_help{"TARGET_IMAGE"} = << "EOF"
134 The place to put your image on the test machine.
135EOF
136 ;
137$config_help{"POWER_CYCLE"} = << "EOF"
138 A script or command to reboot the box.
139
140 Here is a digital loggers power switch example
141 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
142
143 Here is an example to reboot a virtual box on the current host
144 with the name "Guest".
145 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
146EOF
147 ;
148$config_help{"CONSOLE"} = << "EOF"
149 The script or command that reads the console
150
151 If you use ttywatch server, something like the following would work.
152CONSOLE = nc -d localhost 3001
153
154 For a virtual machine with guest name "Guest".
155CONSOLE = virsh console Guest
156EOF
157 ;
158$config_help{"LOCALVERSION"} = << "EOF"
159 Required version ending to differentiate the test
160 from other linux builds on the system.
161EOF
162 ;
163$config_help{"REBOOT_TYPE"} = << "EOF"
164 Way to reboot the box to the test kernel.
165 Only valid options so far are "grub" and "script".
166
167 If you specify grub, it will assume grub version 1
168 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
169 and select that target to reboot to the kernel. If this is not
170 your setup, then specify "script" and have a command or script
171 specified in REBOOT_SCRIPT to boot to the target.
172
173 The entry in /boot/grub/menu.lst must be entered in manually.
174 The test will not modify that file.
175EOF
176 ;
177$config_help{"GRUB_MENU"} = << "EOF"
178 The grub title name for the test kernel to boot
179 (Only mandatory if REBOOT_TYPE = grub)
180
181 Note, ktest.pl will not update the grub menu.lst, you need to
182 manually add an option for the test. ktest.pl will search
183 the grub menu.lst for this option to find what kernel to
184 reboot into.
185
186 For example, if in the /boot/grub/menu.lst the test kernel title has:
187 title Test Kernel
188 kernel vmlinuz-test
189 GRUB_MENU = Test Kernel
190EOF
191 ;
192$config_help{"REBOOT_SCRIPT"} = << "EOF"
193 A script to reboot the target into the test kernel
194 (Only mandatory if REBOOT_TYPE = script)
195EOF
196 ;
197
198
199sub get_ktest_config {
200 my ($config) = @_;
201
202 return if (defined($opt{$config}));
203
204 if (defined($config_help{$config})) {
205 print "\n";
206 print $config_help{$config};
207 }
208
209 for (;;) {
210 print "$config = ";
211 if (defined($default{$config})) {
212 print "\[$default{$config}\] ";
213 }
214 $entered_configs{$config} = <STDIN>;
215 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
216 if ($entered_configs{$config} =~ /^\s*$/) {
217 if ($default{$config}) {
218 $entered_configs{$config} = $default{$config};
219 } else {
220 print "Your answer can not be blank\n";
221 next;
222 }
223 }
224 last;
225 }
226}
227
228sub get_ktest_configs {
229 get_ktest_config("MACHINE");
230 get_ktest_config("SSH_USER");
231 get_ktest_config("BUILD_DIR");
232 get_ktest_config("OUTPUT_DIR");
233 get_ktest_config("BUILD_TARGET");
234 get_ktest_config("TARGET_IMAGE");
235 get_ktest_config("POWER_CYCLE");
236 get_ktest_config("CONSOLE");
237 get_ktest_config("LOCALVERSION");
238
239 my $rtype = $opt{"REBOOT_TYPE"};
240
241 if (!defined($rtype)) {
242 if (!defined($opt{"GRUB_MENU"})) {
243 get_ktest_config("REBOOT_TYPE");
244 $rtype = $entered_configs{"REBOOT_TYPE"};
245 } else {
246 $rtype = "grub";
247 }
248 }
249
250 if ($rtype eq "grub") {
251 get_ktest_config("GRUB_MENU");
252 } else {
253 get_ktest_config("REBOOT_SCRIPT");
254 }
255}
256
257sub set_value {
258 my ($lvalue, $rvalue) = @_;
259
260 if (defined($opt{$lvalue})) {
261 die "Error: Option $lvalue defined more than once!\n";
262 }
263 if ($rvalue =~ /^\s*$/) {
264 delete $opt{$lvalue};
265 } else {
266 $opt{$lvalue} = $rvalue;
267 }
268}
269
270sub read_config {
271 my ($config) = @_;
272
273 open(IN, $config) || die "can't read file $config";
274
275 my $name = $config;
276 $name =~ s,.*/(.*),$1,;
277
278 my $test_num = 0;
279 my $default = 1;
280 my $repeat = 1;
281 my $num_tests_set = 0;
282 my $skip = 0;
283 my $rest;
284
285 while (<IN>) {
286
287 # ignore blank lines and comments
288 next if (/^\s*$/ || /\s*\#/);
289
290 if (/^\s*TEST_START(.*)/) {
291
292 $rest = $1;
293
294 if ($num_tests_set) {
295 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
296 }
297
298 my $old_test_num = $test_num;
299 my $old_repeat = $repeat;
300
301 $test_num += $repeat;
302 $default = 0;
303 $repeat = 1;
304
305 if ($rest =~ /\s+SKIP(.*)/) {
306 $rest = $1;
307 $skip = 1;
308 } else {
309 $skip = 0;
310 }
311
312 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
313 $repeat = $1;
314 $rest = $2;
315 $repeat_tests{"$test_num"} = $repeat;
316 }
317
318 if ($rest =~ /\s+SKIP(.*)/) {
319 $rest = $1;
320 $skip = 1;
321 }
322
323 if ($rest !~ /^\s*$/) {
324 die "$name: $.: Gargbage found after TEST_START\n$_";
325 }
326
327 if ($skip) {
328 $test_num = $old_test_num;
329 $repeat = $old_repeat;
330 }
331
332 } elsif (/^\s*DEFAULTS(.*)$/) {
333 $default = 1;
334
335 $rest = $1;
336
337 if ($rest =~ /\s+SKIP(.*)/) {
338 $rest = $1;
339 $skip = 1;
340 } else {
341 $skip = 0;
342 }
343
344 if ($rest !~ /^\s*$/) {
345 die "$name: $.: Gargbage found after DEFAULTS\n$_";
346 }
347
348 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
349
350 next if ($skip);
351
352 my $lvalue = $1;
353 my $rvalue = $2;
354
355 if (!$default &&
356 ($lvalue eq "NUM_TESTS" ||
357 $lvalue eq "LOG_FILE" ||
358 $lvalue eq "CLEAR_LOG")) {
359 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
360 }
361
362 if ($lvalue eq "NUM_TESTS") {
363 if ($test_num) {
364 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
365 }
366 if (!$default) {
367 die "$name: $.: NUM_TESTS must be set in default section\n";
368 }
369 $num_tests_set = 1;
370 }
371
372 if ($default || $lvalue =~ /\[\d+\]$/) {
373 set_value($lvalue, $rvalue);
374 } else {
375 my $val = "$lvalue\[$test_num\]";
376 set_value($val, $rvalue);
377
378 if ($repeat > 1) {
379 $repeats{$val} = $repeat;
380 }
381 }
382 } else {
383 die "$name: $.: Garbage found in config\n$_";
384 }
385 }
386
387 close(IN);
388
389 if ($test_num) {
390 $test_num += $repeat - 1;
391 $opt{"NUM_TESTS"} = $test_num;
392 }
393
394 # make sure we have all mandatory configs
395 get_ktest_configs;
396
397 # set any defaults
398
399 foreach my $default (keys %default) {
400 if (!defined($opt{$default})) {
401 $opt{$default} = $default{$default};
402 }
403 }
404}
405
406sub _logit {
407 if (defined($opt{"LOG_FILE"})) {
408 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
409 print OUT @_;
410 close(OUT);
411 }
412}
413
414sub logit {
415 if (defined($opt{"LOG_FILE"})) {
416 _logit @_;
417 } else {
418 print @_;
419 }
420}
421
422sub doprint {
423 print @_;
424 _logit @_;
425}
426
427sub run_command;
428
429sub reboot {
430 # try to reboot normally
431 if (run_command $reboot) {
432 if (defined($powercycle_after_reboot)) {
433 sleep $powercycle_after_reboot;
434 run_command "$power_cycle";
435 }
436 } else {
437 # nope? power cycle it.
438 run_command "$power_cycle";
439 }
440}
441
442sub do_not_reboot {
443 my $i = $iteration;
444
445 return $test_type eq "build" ||
446 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
447 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
448}
449
450sub dodie {
451 doprint "CRITICAL FAILURE... ", @_, "\n";
452
453 my $i = $iteration;
454
455 if ($reboot_on_error && !do_not_reboot) {
456
457 doprint "REBOOTING\n";
458 reboot;
459
460 } elsif ($poweroff_on_error && defined($power_off)) {
461 doprint "POWERING OFF\n";
462 `$power_off`;
463 }
464
465 die @_, "\n";
466}
467
468sub open_console {
469 my ($fp) = @_;
470
471 my $flags;
472
473 my $pid = open($fp, "$console|") or
474 dodie "Can't open console $console";
475
476 $flags = fcntl($fp, F_GETFL, 0) or
477 dodie "Can't get flags for the socket: $!";
478 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
479 dodie "Can't set flags for the socket: $!";
480
481 return $pid;
482}
483
484sub close_console {
485 my ($fp, $pid) = @_;
486
487 doprint "kill child process $pid\n";
488 kill 2, $pid;
489
490 print "closing!\n";
491 close($fp);
492}
493
494sub start_monitor {
495 if ($monitor_cnt++) {
496 return;
497 }
498 $monitor_fp = \*MONFD;
499 $monitor_pid = open_console $monitor_fp;
500
501 return;
502
503 open(MONFD, "Stop perl from warning about single use of MONFD");
504}
505
506sub end_monitor {
507 if (--$monitor_cnt) {
508 return;
509 }
510 close_console($monitor_fp, $monitor_pid);
511}
512
513sub wait_for_monitor {
514 my ($time) = @_;
515 my $line;
516
517 doprint "** Wait for monitor to settle down **\n";
518
519 # read the monitor and wait for the system to calm down
520 do {
521 $line = wait_for_input($monitor_fp, $time);
522 print "$line" if (defined($line));
523 } while (defined($line));
524 print "** Monitor flushed **\n";
525}
526
527sub fail {
528
529 if ($die_on_failure) {
530 dodie @_;
531 }
532
533 doprint "FAILED\n";
534
535 my $i = $iteration;
536
537 # no need to reboot for just building.
538 if (!do_not_reboot) {
539 doprint "REBOOTING\n";
540 reboot;
541 start_monitor;
542 wait_for_monitor $sleep_time;
543 end_monitor;
544 }
545
546 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
547 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
548 doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n";
549 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
550 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
551
552 return 1 if (!defined($store_failures));
553
554 my @t = localtime;
555 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
556 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
557
558 my $type = $build_type;
559 if ($type =~ /useconfig/) {
560 $type = "useconfig";
561 }
562
563 my $dir = "$machine-$test_type-$type-fail-$date";
564 my $faildir = "$store_failures/$dir";
565
566 if (!-d $faildir) {
567 mkpath($faildir) or
568 die "can't create $faildir";
569 }
570 if (-f "$output_config") {
571 cp "$output_config", "$faildir/config" or
572 die "failed to copy .config";
573 }
574 if (-f $buildlog) {
575 cp $buildlog, "$faildir/buildlog" or
576 die "failed to move $buildlog";
577 }
578 if (-f $dmesg) {
579 cp $dmesg, "$faildir/dmesg" or
580 die "failed to move $dmesg";
581 }
582
583 doprint "*** Saved info to $faildir ***\n";
584
585 return 1;
586}
587
588sub run_command {
589 my ($command) = @_;
590 my $dolog = 0;
591 my $dord = 0;
592 my $pid;
593
594 $command =~ s/\$SSH_USER/$ssh_user/g;
595 $command =~ s/\$MACHINE/$machine/g;
596
597 doprint("$command ... ");
598
599 $pid = open(CMD, "$command 2>&1 |") or
600 (fail "unable to exec $command" and return 0);
601
602 if (defined($opt{"LOG_FILE"})) {
603 open(LOG, ">>$opt{LOG_FILE}") or
604 dodie "failed to write to log";
605 $dolog = 1;
606 }
607
608 if (defined($redirect)) {
609 open (RD, ">$redirect") or
610 dodie "failed to write to redirect $redirect";
611 $dord = 1;
612 }
613
614 while (<CMD>) {
615 print LOG if ($dolog);
616 print RD if ($dord);
617 }
618
619 waitpid($pid, 0);
620 my $failed = $?;
621
622 close(CMD);
623 close(LOG) if ($dolog);
624 close(RD) if ($dord);
625
626 if ($failed) {
627 doprint "FAILED!\n";
628 } else {
629 doprint "SUCCESS\n";
630 }
631
632 return !$failed;
633}
634
635sub run_ssh {
636 my ($cmd) = @_;
637 my $cp_exec = $ssh_exec;
638
639 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
640 return run_command "$cp_exec";
641}
642
643sub run_scp {
644 my ($src, $dst) = @_;
645 my $cp_scp = $scp_to_target;
646
647 $cp_scp =~ s/\$SRC_FILE/$src/g;
648 $cp_scp =~ s/\$DST_FILE/$dst/g;
649
650 return run_command "$cp_scp";
651}
652
653sub get_grub_index {
654
655 if ($reboot_type ne "grub") {
656 return;
657 }
658 return if (defined($grub_number));
659
660 doprint "Find grub menu ... ";
661 $grub_number = -1;
662
663 my $ssh_grub = $ssh_exec;
664 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
665
666 open(IN, "$ssh_grub |")
667 or die "unable to get menu.lst";
668
669 while (<IN>) {
670 if (/^\s*title\s+$grub_menu\s*$/) {
671 $grub_number++;
672 last;
673 } elsif (/^\s*title\s/) {
674 $grub_number++;
675 }
676 }
677 close(IN);
678
679 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
680 if ($grub_number < 0);
681 doprint "$grub_number\n";
682}
683
684sub wait_for_input
685{
686 my ($fp, $time) = @_;
687 my $rin;
688 my $ready;
689 my $line;
690 my $ch;
691
692 if (!defined($time)) {
693 $time = $timeout;
694 }
695
696 $rin = '';
697 vec($rin, fileno($fp), 1) = 1;
698 $ready = select($rin, undef, undef, $time);
699
700 $line = "";
701
702 # try to read one char at a time
703 while (sysread $fp, $ch, 1) {
704 $line .= $ch;
705 last if ($ch eq "\n");
706 }
707
708 if (!length($line)) {
709 return undef;
710 }
711
712 return $line;
713}
714
715sub reboot_to {
716 if ($reboot_type eq "grub") {
717 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
718 return;
719 }
720
721 run_command "$reboot_script";
722}
723
724sub get_sha1 {
725 my ($commit) = @_;
726
727 doprint "git rev-list --max-count=1 $commit ... ";
728 my $sha1 = `git rev-list --max-count=1 $commit`;
729 my $ret = $?;
730
731 logit $sha1;
732
733 if ($ret) {
734 doprint "FAILED\n";
735 dodie "Failed to get git $commit";
736 }
737
738 print "SUCCESS\n";
739
740 chomp $sha1;
741
742 return $sha1;
743}
744
745sub monitor {
746 my $booted = 0;
747 my $bug = 0;
748 my $skip_call_trace = 0;
749 my $loops;
750
751 wait_for_monitor 5;
752
753 my $line;
754 my $full_line = "";
755
756 open(DMESG, "> $dmesg") or
757 die "unable to write to $dmesg";
758
759 reboot_to;
760
761 my $success_start;
762 my $failure_start;
763
764 for (;;) {
765
766 if ($booted) {
767 $line = wait_for_input($monitor_fp, $booted_timeout);
768 } else {
769 $line = wait_for_input($monitor_fp);
770 }
771
772 last if (!defined($line));
773
774 doprint $line;
775 print DMESG $line;
776
777 # we are not guaranteed to get a full line
778 $full_line .= $line;
779
780 if ($full_line =~ /$success_line/) {
781 $booted = 1;
782 $success_start = time;
783 }
784
785 if ($booted && defined($stop_after_success) &&
786 $stop_after_success >= 0) {
787 my $now = time;
788 if ($now - $success_start >= $stop_after_success) {
789 doprint "Test forced to stop after $stop_after_success seconds after success\n";
790 last;
791 }
792 }
793
794 if ($full_line =~ /\[ backtrace testing \]/) {
795 $skip_call_trace = 1;
796 }
797
798 if ($full_line =~ /call trace:/i) {
799 if (!$skip_call_trace) {
800 $bug = 1;
801 $failure_start = time;
802 }
803 }
804
805 if ($bug && defined($stop_after_failure) &&
806 $stop_after_failure >= 0) {
807 my $now = time;
808 if ($now - $failure_start >= $stop_after_failure) {
809 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
810 last;
811 }
812 }
813
814 if ($full_line =~ /\[ end of backtrace testing \]/) {
815 $skip_call_trace = 0;
816 }
817
818 if ($full_line =~ /Kernel panic -/) {
819 $bug = 1;
820 }
821
822 if ($line =~ /\n/) {
823 $full_line = "";
824 }
825 }
826
827 close(DMESG);
828
829 if ($bug) {
830 return 0 if ($in_bisect);
831 fail "failed - got a bug report" and return 0;
832 }
833
834 if (!$booted) {
835 return 0 if ($in_bisect);
836 fail "failed - never got a boot prompt." and return 0;
837 }
838
839 return 1;
840}
841
842sub install {
843
844 run_scp "$outputdir/$build_target", "$target_image" or
845 dodie "failed to copy image";
846
847 my $install_mods = 0;
848
849 # should we process modules?
850 $install_mods = 0;
851 open(IN, "$output_config") or dodie("Can't read config file");
852 while (<IN>) {
853 if (/CONFIG_MODULES(=y)?/) {
854 $install_mods = 1 if (defined($1));
855 last;
856 }
857 }
858 close(IN);
859
860 if (!$install_mods) {
861 doprint "No modules needed\n";
862 return;
863 }
864
865 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
866 dodie "Failed to install modules";
867
868 my $modlib = "/lib/modules/$version";
869 my $modtar = "ktest-mods.tar.bz2";
870
871 run_ssh "rm -rf $modlib" or
872 dodie "failed to remove old mods: $modlib";
873
874 # would be nice if scp -r did not follow symbolic links
875 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
876 dodie "making tarball";
877
878 run_scp "$tmpdir/$modtar", "/tmp" or
879 dodie "failed to copy modules";
880
881 unlink "$tmpdir/$modtar";
882
883 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
884 dodie "failed to tar modules";
885
886 run_ssh "rm -f /tmp/$modtar";
887
888 return if (!defined($post_install));
889
890 my $cp_post_install = $post_install;
891 $cp_post_install = s/\$KERNEL_VERSION/$version/g;
892 run_command "$cp_post_install" or
893 dodie "Failed to run post install";
894}
895
896sub check_buildlog {
897 my ($patch) = @_;
898
899 my @files = `git show $patch | diffstat -l`;
900
901 open(IN, "git show $patch |") or
902 dodie "failed to show $patch";
903 while (<IN>) {
904 if (m,^--- a/(.*),) {
905 chomp $1;
906 $files[$#files] = $1;
907 }
908 }
909 close(IN);
910
911 open(IN, $buildlog) or dodie "Can't open $buildlog";
912 while (<IN>) {
913 if (/^\s*(.*?):.*(warning|error)/) {
914 my $err = $1;
915 foreach my $file (@files) {
916 my $fullpath = "$builddir/$file";
917 if ($file eq $err || $fullpath eq $err) {
918 fail "$file built with warnings" and return 0;
919 }
920 }
921 }
922 }
923 close(IN);
924
925 return 1;
926}
927
928sub build {
929 my ($type) = @_;
930 my $defconfig = "";
931
932 unlink $buildlog;
933
934 if ($type =~ /^useconfig:(.*)/) {
935 run_command "cp $1 $output_config" or
936 dodie "could not copy $1 to .config";
937
938 $type = "oldconfig";
939 }
940
941 # old config can ask questions
942 if ($type eq "oldconfig") {
943 $type = "oldnoconfig";
944
945 # allow for empty configs
946 run_command "touch $output_config";
947
948 run_command "mv $output_config $outputdir/config_temp" or
949 dodie "moving .config";
950
951 if (!$noclean && !run_command "$make mrproper") {
952 dodie "make mrproper";
953 }
954
955 run_command "mv $outputdir/config_temp $output_config" or
956 dodie "moving config_temp";
957
958 } elsif (!$noclean) {
959 unlink "$output_config";
960 run_command "$make mrproper" or
961 dodie "make mrproper";
962 }
963
964 # add something to distinguish this build
965 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
966 print OUT "$localversion\n";
967 close(OUT);
968
969 if (defined($minconfig)) {
970 $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
971 }
972
973 run_command "$defconfig $make $type" or
974 dodie "failed make config";
975
976 $redirect = "$buildlog";
977 if (!run_command "$make $build_options") {
978 undef $redirect;
979 # bisect may need this to pass
980 return 0 if ($in_bisect);
981 fail "failed build" and return 0;
982 }
983 undef $redirect;
984
985 return 1;
986}
987
988sub halt {
989 if (!run_ssh "halt" or defined($power_off)) {
990 if (defined($poweroff_after_halt)) {
991 sleep $poweroff_after_halt;
992 run_command "$power_off";
993 }
994 } else {
995 # nope? the zap it!
996 run_command "$power_off";
997 }
998}
999
1000sub success {
1001 my ($i) = @_;
1002
1003 $successes++;
1004
1005 doprint "\n\n*******************************************\n";
1006 doprint "*******************************************\n";
1007 doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n";
1008 doprint "*******************************************\n";
1009 doprint "*******************************************\n";
1010
1011 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1012 doprint "Reboot and wait $sleep_time seconds\n";
1013 reboot;
1014 start_monitor;
1015 wait_for_monitor $sleep_time;
1016 end_monitor;
1017 }
1018}
1019
1020sub get_version {
1021 # get the release name
1022 doprint "$make kernelrelease ... ";
1023 $version = `$make kernelrelease | tail -1`;
1024 chomp($version);
1025 doprint "$version\n";
1026}
1027
1028sub child_run_test {
1029 my $failed = 0;
1030
1031 # child should have no power
1032 $reboot_on_error = 0;
1033 $poweroff_on_error = 0;
1034 $die_on_failure = 1;
1035
1036 run_command $run_test or $failed = 1;
1037 exit $failed;
1038}
1039
1040my $child_done;
1041
1042sub child_finished {
1043 $child_done = 1;
1044}
1045
1046sub do_run_test {
1047 my $child_pid;
1048 my $child_exit;
1049 my $line;
1050 my $full_line;
1051 my $bug = 0;
1052
1053 wait_for_monitor 1;
1054
1055 doprint "run test $run_test\n";
1056
1057 $child_done = 0;
1058
1059 $SIG{CHLD} = qw(child_finished);
1060
1061 $child_pid = fork;
1062
1063 child_run_test if (!$child_pid);
1064
1065 $full_line = "";
1066
1067 do {
1068 $line = wait_for_input($monitor_fp, 1);
1069 if (defined($line)) {
1070
1071 # we are not guaranteed to get a full line
1072 $full_line .= $line;
1073
1074 if ($full_line =~ /call trace:/i) {
1075 $bug = 1;
1076 }
1077
1078 if ($full_line =~ /Kernel panic -/) {
1079 $bug = 1;
1080 }
1081
1082 if ($line =~ /\n/) {
1083 $full_line = "";
1084 }
1085 }
1086 } while (!$child_done && !$bug);
1087
1088 if ($bug) {
1089 doprint "Detected kernel crash!\n";
1090 # kill the child with extreme prejudice
1091 kill 9, $child_pid;
1092 }
1093
1094 waitpid $child_pid, 0;
1095 $child_exit = $?;
1096
1097 if ($bug || $child_exit) {
1098 return 0 if $in_bisect;
1099 fail "test failed" and return 0;
1100 }
1101 return 1;
1102}
1103
1104sub run_git_bisect {
1105 my ($command) = @_;
1106
1107 doprint "$command ... ";
1108
1109 my $output = `$command 2>&1`;
1110 my $ret = $?;
1111
1112 logit $output;
1113
1114 if ($ret) {
1115 doprint "FAILED\n";
1116 dodie "Failed to git bisect";
1117 }
1118
1119 doprint "SUCCESS\n";
1120 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1121 doprint "$1 [$2]\n";
1122 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1123 $bisect_bad = $1;
1124 doprint "Found bad commit... $1\n";
1125 return 0;
1126 } else {
1127 # we already logged it, just print it now.
1128 print $output;
1129 }
1130
1131 return 1;
1132}
1133
1134# returns 1 on success, 0 on failure
1135sub run_bisect_test {
1136 my ($type, $buildtype) = @_;
1137
1138 my $failed = 0;
1139 my $result;
1140 my $output;
1141 my $ret;
1142
1143 $in_bisect = 1;
1144
1145 build $buildtype or $failed = 1;
1146
1147 if ($type ne "build") {
1148 dodie "Failed on build" if $failed;
1149
1150 # Now boot the box
1151 get_grub_index;
1152 get_version;
1153 install;
1154
1155 start_monitor;
1156 monitor or $failed = 1;
1157
1158 if ($type ne "boot") {
1159 dodie "Failed on boot" if $failed;
1160
1161 do_run_test or $failed = 1;
1162 }
1163 end_monitor;
1164 }
1165
1166 if ($failed) {
1167 $result = 0;
1168
1169 # reboot the box to a good kernel
1170 if ($type ne "build") {
1171 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1172 reboot;
1173 start_monitor;
1174 wait_for_monitor $bisect_sleep_time;
1175 end_monitor;
1176 }
1177 } else {
1178 $result = 1;
1179 }
1180 $in_bisect = 0;
1181
1182 return $result;
1183}
1184
1185sub run_bisect {
1186 my ($type) = @_;
1187 my $buildtype = "oldconfig";
1188
1189 # We should have a minconfig to use?
1190 if (defined($minconfig)) {
1191 $buildtype = "useconfig:$minconfig";
1192 }
1193
1194 my $ret = run_bisect_test $type, $buildtype;
1195
1196
1197 # Are we looking for where it worked, not failed?
1198 if ($reverse_bisect) {
1199 $ret = !$ret;
1200 }
1201
1202 if ($ret) {
1203 return "good";
1204 } else {
1205 return "bad";
1206 }
1207}
1208
1209sub bisect {
1210 my ($i) = @_;
1211
1212 my $result;
1213
1214 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1215 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1216 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1217
1218 my $good = $opt{"BISECT_GOOD[$i]"};
1219 my $bad = $opt{"BISECT_BAD[$i]"};
1220 my $type = $opt{"BISECT_TYPE[$i]"};
1221 my $start = $opt{"BISECT_START[$i]"};
1222 my $replay = $opt{"BISECT_REPLAY[$i]"};
1223
1224 # convert to true sha1's
1225 $good = get_sha1($good);
1226 $bad = get_sha1($bad);
1227
1228 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1229 $opt{"BISECT_REVERSE[$i]"} == 1) {
1230 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1231 $reverse_bisect = 1;
1232 } else {
1233 $reverse_bisect = 0;
1234 }
1235
1236 # Can't have a test without having a test to run
1237 if ($type eq "test" && !defined($run_test)) {
1238 $type = "boot";
1239 }
1240
1241 my $check = $opt{"BISECT_CHECK[$i]"};
1242 if (defined($check) && $check ne "0") {
1243
1244 # get current HEAD
1245 my $head = get_sha1("HEAD");
1246
1247 if ($check ne "good") {
1248 doprint "TESTING BISECT BAD [$bad]\n";
1249 run_command "git checkout $bad" or
1250 die "Failed to checkout $bad";
1251
1252 $result = run_bisect $type;
1253
1254 if ($result ne "bad") {
1255 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1256 }
1257 }
1258
1259 if ($check ne "bad") {
1260 doprint "TESTING BISECT GOOD [$good]\n";
1261 run_command "git checkout $good" or
1262 die "Failed to checkout $good";
1263
1264 $result = run_bisect $type;
1265
1266 if ($result ne "good") {
1267 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1268 }
1269 }
1270
1271 # checkout where we started
1272 run_command "git checkout $head" or
1273 die "Failed to checkout $head";
1274 }
1275
1276 run_command "git bisect start" or
1277 dodie "could not start bisect";
1278
1279 run_command "git bisect good $good" or
1280 dodie "could not set bisect good to $good";
1281
1282 run_git_bisect "git bisect bad $bad" or
1283 dodie "could not set bisect bad to $bad";
1284
1285 if (defined($replay)) {
1286 run_command "git bisect replay $replay" or
1287 dodie "failed to run replay";
1288 }
1289
1290 if (defined($start)) {
1291 run_command "git checkout $start" or
1292 dodie "failed to checkout $start";
1293 }
1294
1295 my $test;
1296 do {
1297 $result = run_bisect $type;
1298 $test = run_git_bisect "git bisect $result";
1299 } while ($test);
1300
1301 run_command "git bisect log" or
1302 dodie "could not capture git bisect log";
1303
1304 run_command "git bisect reset" or
1305 dodie "could not reset git bisect";
1306
1307 doprint "Bad commit was [$bisect_bad]\n";
1308
1309 success $i;
1310}
1311
1312my %config_ignore;
1313my %config_set;
1314
1315my %config_list;
1316my %null_config;
1317
1318my %dependency;
1319
1320sub process_config_ignore {
1321 my ($config) = @_;
1322
1323 open (IN, $config)
1324 or dodie "Failed to read $config";
1325
1326 while (<IN>) {
1327 if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1328 $config_ignore{$2} = $1;
1329 }
1330 }
1331
1332 close(IN);
1333}
1334
1335sub read_current_config {
1336 my ($config_ref) = @_;
1337
1338 %{$config_ref} = ();
1339 undef %{$config_ref};
1340
1341 my @key = keys %{$config_ref};
1342 if ($#key >= 0) {
1343 print "did not delete!\n";
1344 exit;
1345 }
1346 open (IN, "$output_config");
1347
1348 while (<IN>) {
1349 if (/^(CONFIG\S+)=(.*)/) {
1350 ${$config_ref}{$1} = $2;
1351 }
1352 }
1353 close(IN);
1354}
1355
1356sub get_dependencies {
1357 my ($config) = @_;
1358
1359 my $arr = $dependency{$config};
1360 if (!defined($arr)) {
1361 return ();
1362 }
1363
1364 my @deps = @{$arr};
1365
1366 foreach my $dep (@{$arr}) {
1367 print "ADD DEP $dep\n";
1368 @deps = (@deps, get_dependencies $dep);
1369 }
1370
1371 return @deps;
1372}
1373
1374sub create_config {
1375 my @configs = @_;
1376
1377 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1378
1379 foreach my $config (@configs) {
1380 print OUT "$config_set{$config}\n";
1381 my @deps = get_dependencies $config;
1382 foreach my $dep (@deps) {
1383 print OUT "$config_set{$dep}\n";
1384 }
1385 }
1386
1387 foreach my $config (keys %config_ignore) {
1388 print OUT "$config_ignore{$config}\n";
1389 }
1390 close(OUT);
1391
1392# exit;
1393 run_command "$make oldnoconfig" or
1394 dodie "failed make config oldconfig";
1395
1396}
1397
1398sub compare_configs {
1399 my (%a, %b) = @_;
1400
1401 foreach my $item (keys %a) {
1402 if (!defined($b{$item})) {
1403 print "diff $item\n";
1404 return 1;
1405 }
1406 delete $b{$item};
1407 }
1408
1409 my @keys = keys %b;
1410 if ($#keys) {
1411 print "diff2 $keys[0]\n";
1412 }
1413 return -1 if ($#keys >= 0);
1414
1415 return 0;
1416}
1417
1418sub run_config_bisect_test {
1419 my ($type) = @_;
1420
1421 return run_bisect_test $type, "oldconfig";
1422}
1423
1424sub process_passed {
1425 my (%configs) = @_;
1426
1427 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1428 # Passed! All these configs are part of a good compile.
1429 # Add them to the min options.
1430 foreach my $config (keys %configs) {
1431 if (defined($config_list{$config})) {
1432 doprint " removing $config\n";
1433 $config_ignore{$config} = $config_list{$config};
1434 delete $config_list{$config};
1435 }
1436 }
1437 doprint "config copied to $outputdir/config_good\n";
1438 run_command "cp -f $output_config $outputdir/config_good";
1439}
1440
1441sub process_failed {
1442 my ($config) = @_;
1443
1444 doprint "\n\n***************************************\n";
1445 doprint "Found bad config: $config\n";
1446 doprint "***************************************\n\n";
1447}
1448
1449sub run_config_bisect {
1450
1451 my @start_list = keys %config_list;
1452
1453 if ($#start_list < 0) {
1454 doprint "No more configs to test!!!\n";
1455 return -1;
1456 }
1457
1458 doprint "***** RUN TEST ***\n";
1459 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1460 my $ret;
1461 my %current_config;
1462
1463 my $count = $#start_list + 1;
1464 doprint " $count configs to test\n";
1465
1466 my $half = int($#start_list / 2);
1467
1468 do {
1469 my @tophalf = @start_list[0 .. $half];
1470
1471 create_config @tophalf;
1472 read_current_config \%current_config;
1473
1474 $count = $#tophalf + 1;
1475 doprint "Testing $count configs\n";
1476 my $found = 0;
1477 # make sure we test something
1478 foreach my $config (@tophalf) {
1479 if (defined($current_config{$config})) {
1480 logit " $config\n";
1481 $found = 1;
1482 }
1483 }
1484 if (!$found) {
1485 # try the other half
1486 doprint "Top half produced no set configs, trying bottom half\n";
1487 @tophalf = @start_list[$half .. $#start_list];
1488 create_config @tophalf;
1489 read_current_config \%current_config;
1490 foreach my $config (@tophalf) {
1491 if (defined($current_config{$config})) {
1492 logit " $config\n";
1493 $found = 1;
1494 }
1495 }
1496 if (!$found) {
1497 doprint "Failed: Can't make new config with current configs\n";
1498 foreach my $config (@start_list) {
1499 doprint " CONFIG: $config\n";
1500 }
1501 return -1;
1502 }
1503 $count = $#tophalf + 1;
1504 doprint "Testing $count configs\n";
1505 }
1506
1507 $ret = run_config_bisect_test $type;
1508
1509 if ($ret) {
1510 process_passed %current_config;
1511 return 0;
1512 }
1513
1514 doprint "This config had a failure.\n";
1515 doprint "Removing these configs that were not set in this config:\n";
1516 doprint "config copied to $outputdir/config_bad\n";
1517 run_command "cp -f $output_config $outputdir/config_bad";
1518
1519 # A config exists in this group that was bad.
1520 foreach my $config (keys %config_list) {
1521 if (!defined($current_config{$config})) {
1522 doprint " removing $config\n";
1523 delete $config_list{$config};
1524 }
1525 }
1526
1527 @start_list = @tophalf;
1528
1529 if ($#start_list == 0) {
1530 process_failed $start_list[0];
1531 return 1;
1532 }
1533
1534 # remove half the configs we are looking at and see if
1535 # they are good.
1536 $half = int($#start_list / 2);
1537 } while ($half > 0);
1538
1539 # we found a single config, try it again
1540 my @tophalf = @start_list[0 .. 0];
1541
1542 $ret = run_config_bisect_test $type;
1543 if ($ret) {
1544 process_passed %current_config;
1545 return 0;
1546 }
1547
1548 process_failed $start_list[0];
1549 return 1;
1550}
1551
1552sub config_bisect {
1553 my ($i) = @_;
1554
1555 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1556
1557 my $tmpconfig = "$tmpdir/use_config";
1558
1559 # Make the file with the bad config and the min config
1560 if (defined($minconfig)) {
1561 # read the min config for things to ignore
1562 run_command "cp $minconfig $tmpconfig" or
1563 dodie "failed to copy $minconfig to $tmpconfig";
1564 } else {
1565 unlink $tmpconfig;
1566 }
1567
1568 # Add other configs
1569 if (defined($addconfig)) {
1570 run_command "cat $addconfig >> $tmpconfig" or
1571 dodie "failed to append $addconfig";
1572 }
1573
1574 my $defconfig = "";
1575 if (-f $tmpconfig) {
1576 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1577 process_config_ignore $tmpconfig;
1578 }
1579
1580 # now process the start config
1581 run_command "cp $start_config $output_config" or
1582 dodie "failed to copy $start_config to $output_config";
1583
1584 # read directly what we want to check
1585 my %config_check;
1586 open (IN, $output_config)
1587 or dodie "faied to open $output_config";
1588
1589 while (<IN>) {
1590 if (/^((CONFIG\S*)=.*)/) {
1591 $config_check{$2} = $1;
1592 }
1593 }
1594 close(IN);
1595
1596 # Now run oldconfig with the minconfig (and addconfigs)
1597 run_command "$defconfig $make oldnoconfig" or
1598 dodie "failed make config oldconfig";
1599
1600 # check to see what we lost (or gained)
1601 open (IN, $output_config)
1602 or dodie "Failed to read $start_config";
1603
1604 my %removed_configs;
1605 my %added_configs;
1606
1607 while (<IN>) {
1608 if (/^((CONFIG\S*)=.*)/) {
1609 # save off all options
1610 $config_set{$2} = $1;
1611 if (defined($config_check{$2})) {
1612 if (defined($config_ignore{$2})) {
1613 $removed_configs{$2} = $1;
1614 } else {
1615 $config_list{$2} = $1;
1616 }
1617 } elsif (!defined($config_ignore{$2})) {
1618 $added_configs{$2} = $1;
1619 $config_list{$2} = $1;
1620 }
1621 }
1622 }
1623 close(IN);
1624
1625 my @confs = keys %removed_configs;
1626 if ($#confs >= 0) {
1627 doprint "Configs overridden by default configs and removed from check:\n";
1628 foreach my $config (@confs) {
1629 doprint " $config\n";
1630 }
1631 }
1632 @confs = keys %added_configs;
1633 if ($#confs >= 0) {
1634 doprint "Configs appearing in make oldconfig and added:\n";
1635 foreach my $config (@confs) {
1636 doprint " $config\n";
1637 }
1638 }
1639
1640 my %config_test;
1641 my $once = 0;
1642
1643 # Sometimes kconfig does weird things. We must make sure
1644 # that the config we autocreate has everything we need
1645 # to test, otherwise we may miss testing configs, or
1646 # may not be able to create a new config.
1647 # Here we create a config with everything set.
1648 create_config (keys %config_list);
1649 read_current_config \%config_test;
1650 foreach my $config (keys %config_list) {
1651 if (!defined($config_test{$config})) {
1652 if (!$once) {
1653 $once = 1;
1654 doprint "Configs not produced by kconfig (will not be checked):\n";
1655 }
1656 doprint " $config\n";
1657 delete $config_list{$config};
1658 }
1659 }
1660 my $ret;
1661 do {
1662 $ret = run_config_bisect;
1663 } while (!$ret);
1664
1665 return $ret if ($ret < 0);
1666
1667 success $i;
1668}
1669
1670sub patchcheck {
1671 my ($i) = @_;
1672
1673 die "PATCHCHECK_START[$i] not defined\n"
1674 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1675 die "PATCHCHECK_TYPE[$i] not defined\n"
1676 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1677
1678 my $start = $opt{"PATCHCHECK_START[$i]"};
1679
1680 my $end = "HEAD";
1681 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1682 $end = $opt{"PATCHCHECK_END[$i]"};
1683 }
1684
1685 # Get the true sha1's since we can use things like HEAD~3
1686 $start = get_sha1($start);
1687 $end = get_sha1($end);
1688
1689 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1690
1691 # Can't have a test without having a test to run
1692 if ($type eq "test" && !defined($run_test)) {
1693 $type = "boot";
1694 }
1695
1696 open (IN, "git log --pretty=oneline $end|") or
1697 dodie "could not get git list";
1698
1699 my @list;
1700
1701 while (<IN>) {
1702 chomp;
1703 $list[$#list+1] = $_;
1704 last if (/^$start/);
1705 }
1706 close(IN);
1707
1708 if ($list[$#list] !~ /^$start/) {
1709 fail "SHA1 $start not found";
1710 }
1711
1712 # go backwards in the list
1713 @list = reverse @list;
1714
1715 my $save_clean = $noclean;
1716
1717 $in_patchcheck = 1;
1718 foreach my $item (@list) {
1719 my $sha1 = $item;
1720 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1721
1722 doprint "\nProcessing commit $item\n\n";
1723
1724 run_command "git checkout $sha1" or
1725 die "Failed to checkout $sha1";
1726
1727 # only clean on the first and last patch
1728 if ($item eq $list[0] ||
1729 $item eq $list[$#list]) {
1730 $noclean = $save_clean;
1731 } else {
1732 $noclean = 1;
1733 }
1734
1735 if (defined($minconfig)) {
1736 build "useconfig:$minconfig" or return 0;
1737 } else {
1738 # ?? no config to use?
1739 build "oldconfig" or return 0;
1740 }
1741
1742 check_buildlog $sha1 or return 0;
1743
1744 next if ($type eq "build");
1745
1746 get_grub_index;
1747 get_version;
1748 install;
1749
1750 my $failed = 0;
1751
1752 start_monitor;
1753 monitor or $failed = 1;
1754
1755 if (!$failed && $type ne "boot"){
1756 do_run_test or $failed = 1;
1757 }
1758 end_monitor;
1759 return 0 if ($failed);
1760
1761 }
1762 $in_patchcheck = 0;
1763 success $i;
1764
1765 return 1;
1766}
1767
1768$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
1769
1770if ($#ARGV == 0) {
1771 $ktest_config = $ARGV[0];
1772 if (! -f $ktest_config) {
1773 print "$ktest_config does not exist.\n";
1774 my $ans;
1775 for (;;) {
1776 print "Create it? [Y/n] ";
1777 $ans = <STDIN>;
1778 chomp $ans;
1779 if ($ans =~ /^\s*$/) {
1780 $ans = "y";
1781 }
1782 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1783 print "Please answer either 'y' or 'n'.\n";
1784 }
1785 if ($ans !~ /^y$/i) {
1786 exit 0;
1787 }
1788 }
1789} else {
1790 $ktest_config = "ktest.conf";
1791}
1792
1793if (! -f $ktest_config) {
1794 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
1795 print OUT << "EOF"
1796# Generated by ktest.pl
1797#
1798# Define each test with TEST_START
1799# The config options below it will override the defaults
1800TEST_START
1801
1802DEFAULTS
1803EOF
1804;
1805 close(OUT);
1806}
1807read_config $ktest_config;
1808
1809# Append any configs entered in manually to the config file.
1810my @new_configs = keys %entered_configs;
1811if ($#new_configs >= 0) {
1812 print "\nAppending entered in configs to $ktest_config\n";
1813 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
1814 foreach my $config (@new_configs) {
1815 print OUT "$config = $entered_configs{$config}\n";
1816 $opt{$config} = $entered_configs{$config};
1817 }
1818}
1819
1820if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1821 unlink $opt{"LOG_FILE"};
1822}
1823
1824doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1825
1826for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1827
1828 if (!$i) {
1829 doprint "DEFAULT OPTIONS:\n";
1830 } else {
1831 doprint "\nTEST $i OPTIONS";
1832 if (defined($repeat_tests{$i})) {
1833 $repeat = $repeat_tests{$i};
1834 doprint " ITERATE $repeat";
1835 }
1836 doprint "\n";
1837 }
1838
1839 foreach my $option (sort keys %opt) {
1840
1841 if ($option =~ /\[(\d+)\]$/) {
1842 next if ($i != $1);
1843 } else {
1844 next if ($i);
1845 }
1846
1847 doprint "$option = $opt{$option}\n";
1848 }
1849}
1850
1851sub set_test_option {
1852 my ($name, $i) = @_;
1853
1854 my $option = "$name\[$i\]";
1855
1856 if (defined($opt{$option})) {
1857 return $opt{$option};
1858 }
1859
1860 foreach my $test (keys %repeat_tests) {
1861 if ($i >= $test &&
1862 $i < $test + $repeat_tests{$test}) {
1863 $option = "$name\[$test\]";
1864 if (defined($opt{$option})) {
1865 return $opt{$option};
1866 }
1867 }
1868 }
1869
1870 if (defined($opt{$name})) {
1871 return $opt{$name};
1872 }
1873
1874 return undef;
1875}
1876
1877# First we need to do is the builds
1878for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
1879
1880 $iteration = $i;
1881
1882 my $makecmd = set_test_option("MAKE_CMD", $i);
1883
1884 $machine = set_test_option("MACHINE", $i);
1885 $ssh_user = set_test_option("SSH_USER", $i);
1886 $tmpdir = set_test_option("TMP_DIR", $i);
1887 $outputdir = set_test_option("OUTPUT_DIR", $i);
1888 $builddir = set_test_option("BUILD_DIR", $i);
1889 $test_type = set_test_option("TEST_TYPE", $i);
1890 $build_type = set_test_option("BUILD_TYPE", $i);
1891 $build_options = set_test_option("BUILD_OPTIONS", $i);
1892 $power_cycle = set_test_option("POWER_CYCLE", $i);
1893 $reboot = set_test_option("REBOOT", $i);
1894 $noclean = set_test_option("BUILD_NOCLEAN", $i);
1895 $minconfig = set_test_option("MIN_CONFIG", $i);
1896 $run_test = set_test_option("TEST", $i);
1897 $addconfig = set_test_option("ADD_CONFIG", $i);
1898 $reboot_type = set_test_option("REBOOT_TYPE", $i);
1899 $grub_menu = set_test_option("GRUB_MENU", $i);
1900 $post_install = set_test_option("POST_INSTALL", $i);
1901 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1902 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
1903 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
1904 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
1905 $power_off = set_test_option("POWER_OFF", $i);
1906 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
1907 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
1908 $sleep_time = set_test_option("SLEEP_TIME", $i);
1909 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
1910 $store_failures = set_test_option("STORE_FAILURES", $i);
1911 $timeout = set_test_option("TIMEOUT", $i);
1912 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
1913 $console = set_test_option("CONSOLE", $i);
1914 $success_line = set_test_option("SUCCESS_LINE", $i);
1915 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
1916 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
1917 $build_target = set_test_option("BUILD_TARGET", $i);
1918 $ssh_exec = set_test_option("SSH_EXEC", $i);
1919 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
1920 $target_image = set_test_option("TARGET_IMAGE", $i);
1921 $localversion = set_test_option("LOCALVERSION", $i);
1922
1923 chdir $builddir || die "can't change directory to $builddir";
1924
1925 if (!-d $tmpdir) {
1926 mkpath($tmpdir) or
1927 die "can't create $tmpdir";
1928 }
1929
1930 $ENV{"SSH_USER"} = $ssh_user;
1931 $ENV{"MACHINE"} = $machine;
1932
1933 $target = "$ssh_user\@$machine";
1934
1935 $buildlog = "$tmpdir/buildlog-$machine";
1936 $dmesg = "$tmpdir/dmesg-$machine";
1937 $make = "$makecmd O=$outputdir";
1938 $output_config = "$outputdir/.config";
1939
1940 if ($reboot_type eq "grub") {
1941 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
1942 } elsif (!defined($reboot_script)) {
1943 dodie "REBOOT_SCRIPT not defined"
1944 }
1945
1946 my $run_type = $build_type;
1947 if ($test_type eq "patchcheck") {
1948 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
1949 } elsif ($test_type eq "bisect") {
1950 $run_type = $opt{"BISECT_TYPE[$i]"};
1951 } elsif ($test_type eq "config_bisect") {
1952 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
1953 }
1954
1955 # mistake in config file?
1956 if (!defined($run_type)) {
1957 $run_type = "ERROR";
1958 }
1959
1960 doprint "\n\n";
1961 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
1962
1963 unlink $dmesg;
1964 unlink $buildlog;
1965
1966 if (!defined($minconfig)) {
1967 $minconfig = $addconfig;
1968
1969 } elsif (defined($addconfig)) {
1970 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
1971 dodie "Failed to create temp config";
1972 $minconfig = "$tmpdir/add_config";
1973 }
1974
1975 my $checkout = $opt{"CHECKOUT[$i]"};
1976 if (defined($checkout)) {
1977 run_command "git checkout $checkout" or
1978 die "failed to checkout $checkout";
1979 }
1980
1981 if ($test_type eq "bisect") {
1982 bisect $i;
1983 next;
1984 } elsif ($test_type eq "config_bisect") {
1985 config_bisect $i;
1986 next;
1987 } elsif ($test_type eq "patchcheck") {
1988 patchcheck $i;
1989 next;
1990 }
1991
1992 if ($build_type ne "nobuild") {
1993 build $build_type or next;
1994 }
1995
1996 if ($test_type ne "build") {
1997 get_grub_index;
1998 get_version;
1999 install;
2000
2001 my $failed = 0;
2002 start_monitor;
2003 monitor or $failed = 1;;
2004
2005 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2006 do_run_test or $failed = 1;
2007 }
2008 end_monitor;
2009 next if ($failed);
2010 }
2011
2012 success $i;
2013}
2014
2015if ($opt{"POWEROFF_ON_SUCCESS"}) {
2016 halt;
2017} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
2018 reboot;
2019}
2020
2021doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2022
2023exit 0;
diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf
new file mode 100644
index 000000000000..3408c594b2de
--- /dev/null
+++ b/tools/testing/ktest/sample.conf
@@ -0,0 +1,622 @@
1#
2# Config file for ktest.pl
3#
4# Note, all paths must be absolute
5#
6
7# Options set in the beginning of the file are considered to be
8# default options. These options can be overriden by test specific
9# options, with the following exceptions:
10#
11# LOG_FILE
12# CLEAR_LOG
13# POWEROFF_ON_SUCCESS
14# REBOOT_ON_SUCCESS
15#
16# Test specific options are set after the label:
17#
18# TEST_START
19#
20# The options after a TEST_START label are specific to that test.
21# Each TEST_START label will set up a new test. If you want to
22# perform a test more than once, you can add the ITERATE label
23# to it followed by the number of times you want that test
24# to iterate. If the ITERATE is left off, the test will only
25# be performed once.
26#
27# TEST_START ITERATE 10
28#
29# You can skip a test by adding SKIP (before or after the ITERATE
30# and number)
31#
32# TEST_START SKIP
33#
34# TEST_START SKIP ITERATE 10
35#
36# TEST_START ITERATE 10 SKIP
37#
38# The SKIP label causes the options and the test itself to be ignored.
39# This is useful to set up several different tests in one config file, and
40# only enabling the ones you want to use for a current test run.
41#
42# You can add default options anywhere in the file as well
43# with the DEFAULTS tag. This allows you to have default options
44# after the test options to keep the test options at the top
45# of the file. You can even place the DEFAULTS tag between
46# test cases (but not in the middle of a single test case)
47#
48# TEST_START
49# MIN_CONFIG = /home/test/config-test1
50#
51# DEFAULTS
52# MIN_CONFIG = /home/test/config-default
53#
54# TEST_START ITERATE 10
55#
56# The above will run the first test with MIN_CONFIG set to
57# /home/test/config-test-1. Then 10 tests will be executed
58# with MIN_CONFIG with /home/test/config-default.
59#
60# You can also disable defaults with the SKIP option
61#
62# DEFAULTS SKIP
63# MIN_CONFIG = /home/test/config-use-sometimes
64#
65# DEFAULTS
66# MIN_CONFIG = /home/test/config-most-times
67#
68# The above will ignore the first MIN_CONFIG. If you want to
69# use the first MIN_CONFIG, remove the SKIP from the first
70# DEFAULTS tag and add it to the second. Be careful, options
71# may only be declared once per test or default. If you have
72# the same option name under the same test or as default
73# ktest will fail to execute, and no tests will run.
74#
75
76
77#### Mandatory Default Options ####
78
79# These options must be in the default section, although most
80# may be overridden by test options.
81
82# The machine hostname that you will test
83#MACHINE = target
84
85# The box is expected to have ssh on normal bootup, provide the user
86# (most likely root, since you need privileged operations)
87#SSH_USER = root
88
89# The directory that contains the Linux source code
90#BUILD_DIR = /home/test/linux.git
91
92# The directory that the objects will be built
93# (can not be same as BUILD_DIR)
94#OUTPUT_DIR = /home/test/build/target
95
96# The location of the compiled file to copy to the target
97# (relative to OUTPUT_DIR)
98#BUILD_TARGET = arch/x86/boot/bzImage
99
100# The place to put your image on the test machine
101#TARGET_IMAGE = /boot/vmlinuz-test
102
103# A script or command to reboot the box
104#
105# Here is a digital loggers power switch example
106#POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin@power/outlet?5=CCL'
107#
108# Here is an example to reboot a virtual box on the current host
109# with the name "Guest".
110#POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
111
112# The script or command that reads the console
113#
114# If you use ttywatch server, something like the following would work.
115#CONSOLE = nc -d localhost 3001
116#
117# For a virtual machine with guest name "Guest".
118#CONSOLE = virsh console Guest
119
120# Required version ending to differentiate the test
121# from other linux builds on the system.
122#LOCALVERSION = -test
123
124# The grub title name for the test kernel to boot
125# (Only mandatory if REBOOT_TYPE = grub)
126#
127# Note, ktest.pl will not update the grub menu.lst, you need to
128# manually add an option for the test. ktest.pl will search
129# the grub menu.lst for this option to find what kernel to
130# reboot into.
131#
132# For example, if in the /boot/grub/menu.lst the test kernel title has:
133# title Test Kernel
134# kernel vmlinuz-test
135#GRUB_MENU = Test Kernel
136
137# A script to reboot the target into the test kernel
138# (Only mandatory if REBOOT_TYPE = script)
139#REBOOT_SCRIPT =
140
141#### Optional Config Options (all have defaults) ####
142
143# Start a test setup. If you leave this off, all options
144# will be default and the test will run once.
145# This is a label and not really an option (it takes no value).
146# You can append ITERATE and a number after it to iterate the
147# test a number of times, or SKIP to ignore this test.
148#
149#TEST_START
150#TEST_START ITERATE 5
151#TEST_START SKIP
152
153# Have the following options as default again. Used after tests
154# have already been defined by TEST_START. Optionally, you can
155# just define all default options before the first TEST_START
156# and you do not need this option.
157#
158# This is a label and not really an option (it takes no value).
159# You can append SKIP to this label and the options within this
160# section will be ignored.
161#
162# DEFAULTS
163# DEFAULTS SKIP
164
165# The default test type (default test)
166# The test types may be:
167# build - only build the kernel, do nothing else
168# boot - build and boot the kernel
169# test - build, boot and if TEST is set, run the test script
170# (If TEST is not set, it defaults back to boot)
171# bisect - Perform a bisect on the kernel (see BISECT_TYPE below)
172# patchcheck - Do a test on a series of commits in git (see PATCHCHECK below)
173#TEST_TYPE = test
174
175# Test to run if there is a successful boot and TEST_TYPE is test.
176# Must exit with 0 on success and non zero on error
177# default (undefined)
178#TEST = ssh user@machine /root/run_test
179
180# The build type is any make config type or special command
181# (default randconfig)
182# nobuild - skip the clean and build step
183# useconfig:/path/to/config - use the given config and run
184# oldconfig on it.
185# This option is ignored if TEST_TYPE is patchcheck or bisect
186#BUILD_TYPE = randconfig
187
188# The make command (default make)
189# If you are building a 32bit x86 on a 64 bit host
190#MAKE_CMD = CC=i386-gcc AS=i386-as make ARCH=i386
191
192# Any build options for the make of the kernel (not for other makes, like configs)
193# (default "")
194#BUILD_OPTIONS = -j20
195
196# If you need an initrd, you can add a script or code here to install
197# it. The environment variable KERNEL_VERSION will be set to the
198# kernel version that is used. Remember to add the initrd line
199# to your grub menu.lst file.
200#
201# Here's a couple of examples to use:
202#POST_INSTALL = ssh user@target /sbin/mkinitrd --allow-missing -f /boot/initramfs-test.img $KERNEL_VERSION
203#
204# or on some systems:
205#POST_INSTALL = ssh user@target /sbin/dracut -f /boot/initramfs-test.img $KERNEL_VERSION
206
207# Way to reboot the box to the test kernel.
208# Only valid options so far are "grub" and "script"
209# (default grub)
210# If you specify grub, it will assume grub version 1
211# and will search in /boot/grub/menu.lst for the title $GRUB_MENU
212# and select that target to reboot to the kernel. If this is not
213# your setup, then specify "script" and have a command or script
214# specified in REBOOT_SCRIPT to boot to the target.
215#
216# The entry in /boot/grub/menu.lst must be entered in manually.
217# The test will not modify that file.
218#REBOOT_TYPE = grub
219
220# The min config that is needed to build for the machine
221# A nice way to create this is with the following:
222#
223# $ ssh target
224# $ lsmod > mymods
225# $ scp mymods host:/tmp
226# $ exit
227# $ cd linux.git
228# $ rm .config
229# $ make LSMOD=mymods localyesconfig
230# $ grep '^CONFIG' .config > /home/test/config-min
231#
232# If you want even less configs:
233#
234# log in directly to target (do not ssh)
235#
236# $ su
237# # lsmod | cut -d' ' -f1 | xargs rmmod
238#
239# repeat the above several times
240#
241# # lsmod > mymods
242# # reboot
243#
244# May need to reboot to get your network back to copy the mymods
245# to the host, and then remove the previous .config and run the
246# localyesconfig again. The CONFIG_MIN generated like this will
247# not guarantee network activity to the box so the TEST_TYPE of
248# test may fail.
249#
250# You might also want to set:
251# CONFIG_CMDLINE="<your options here>"
252# randconfig may set the above and override your real command
253# line options.
254# (default undefined)
255#MIN_CONFIG = /home/test/config-min
256
257# Sometimes there's options that just break the boot and
258# you do not care about. Here are a few:
259# # CONFIG_STAGING is not set
260# Staging drivers are horrible, and can break the build.
261# # CONFIG_SCSI_DEBUG is not set
262# SCSI_DEBUG may change your root partition
263# # CONFIG_KGDB_SERIAL_CONSOLE is not set
264# KGDB may cause oops waiting for a connection that's not there.
265# This option points to the file containing config options that will be prepended
266# to the MIN_CONFIG (or be the MIN_CONFIG if it is not set)
267#
268# Note, config options in MIN_CONFIG will override these options.
269#
270# (default undefined)
271#ADD_CONFIG = /home/test/config-broken
272
273# The location on the host where to write temp files
274# (default /tmp/ktest)
275#TMP_DIR = /tmp/ktest
276
277# Optional log file to write the status (recommended)
278# Note, this is a DEFAULT section only option.
279# (default undefined)
280#LOG_FILE = /home/test/logfiles/target.log
281
282# Remove old logfile if it exists before starting all tests.
283# Note, this is a DEFAULT section only option.
284# (default 0)
285#CLEAR_LOG = 0
286
287# Line to define a successful boot up in console output.
288# This is what the line contains, not the entire line. If you need
289# the entire line to match, then use regural expression syntax like:
290# (do not add any quotes around it)
291#
292# SUCCESS_LINE = ^MyBox Login:$
293#
294# (default "login:")
295#SUCCESS_LINE = login:
296
297# In case the console constantly fills the screen, having
298# a specified time to stop the test after success is recommended.
299# (in seconds)
300# (default 10)
301#STOP_AFTER_SUCCESS = 10
302
303# In case the console constantly fills the screen, having
304# a specified time to stop the test after failure is recommended.
305# (in seconds)
306# (default 60)
307#STOP_AFTER_FAILURE = 60
308
309# Stop testing if a build fails. If set, the script will end if
310# a failure is detected, otherwise it will save off the .config,
311# dmesg and bootlog in a directory called
312# MACHINE-TEST_TYPE_BUILD_TYPE-fail-yyyymmddhhmmss
313# if the STORE_FAILURES directory is set.
314# (default 1)
315# Note, even if this is set to zero, there are some errors that still
316# stop the tests.
317#DIE_ON_FAILURE = 1
318
319# Directory to store failure directories on failure. If this is not
320# set, DIE_ON_FAILURE=0 will not save off the .config, dmesg and
321# bootlog. This option is ignored if DIE_ON_FAILURE is not set.
322# (default undefined)
323#STORE_FAILURES = /home/test/failures
324
325# Build without doing a make mrproper, or removing .config
326# (default 0)
327#BUILD_NOCLEAN = 0
328
329# As the test reads the console, after it hits the SUCCESS_LINE
330# the time it waits for the monitor to settle down between reads
331# can usually be lowered.
332# (in seconds) (default 1)
333#BOOTED_TIMEOUT = 1
334
335# The timeout in seconds when we consider the box hung after
336# the console stop producing output. Be sure to leave enough
337# time here to get pass a reboot. Some machines may not produce
338# any console output for a long time during a reboot. You do
339# not want the test to fail just because the system was in
340# the process of rebooting to the test kernel.
341# (default 120)
342#TIMEOUT = 120
343
344# In between tests, a reboot of the box may occur, and this
345# is the time to wait for the console after it stops producing
346# output. Some machines may not produce a large lag on reboot
347# so this should accommodate it.
348# The difference between this and TIMEOUT, is that TIMEOUT happens
349# when rebooting to the test kernel. This sleep time happens
350# after a test has completed and we are about to start running
351# another test. If a reboot to the reliable kernel happens,
352# we wait SLEEP_TIME for the console to stop producing output
353# before starting the next test.
354# (default 60)
355#SLEEP_TIME = 60
356
357# The time in between bisects to sleep (in seconds)
358# (default 60)
359#BISECT_SLEEP_TIME = 60
360
361# Reboot the target box on error (default 0)
362#REBOOT_ON_ERROR = 0
363
364# Power off the target on error (ignored if REBOOT_ON_ERROR is set)
365# Note, this is a DEFAULT section only option.
366# (default 0)
367#POWEROFF_ON_ERROR = 0
368
369# Power off the target after all tests have completed successfully
370# Note, this is a DEFAULT section only option.
371# (default 0)
372#POWEROFF_ON_SUCCESS = 0
373
374# Reboot the target after all test completed successfully (default 1)
375# (ignored if POWEROFF_ON_SUCCESS is set)
376#REBOOT_ON_SUCCESS = 1
377
378# In case there are isses with rebooting, you can specify this
379# to always powercycle after this amount of time after calling
380# reboot.
381# Note, POWERCYCLE_AFTER_REBOOT = 0 does NOT disable it. It just
382# makes it powercycle immediately after rebooting. Do not define
383# it if you do not want it.
384# (default undefined)
385#POWERCYCLE_AFTER_REBOOT = 5
386
387# In case there's isses with halting, you can specify this
388# to always poweroff after this amount of time after calling
389# halt.
390# Note, POWEROFF_AFTER_HALT = 0 does NOT disable it. It just
391# makes it poweroff immediately after halting. Do not define
392# it if you do not want it.
393# (default undefined)
394#POWEROFF_AFTER_HALT = 20
395
396# A script or command to power off the box (default undefined)
397# Needed for POWEROFF_ON_ERROR and SUCCESS
398#
399# Example for digital loggers power switch:
400#POWER_OFF = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin@power/outlet?5=OFF'
401#
402# Example for a virtual guest call "Guest".
403#POWER_OFF = virsh destroy Guest
404
405# The way to execute a command on the target
406# (default ssh $SSH_USER@$MACHINE $SSH_COMMAND";)
407# The variables SSH_USER, MACHINE and SSH_COMMAND are defined
408#SSH_EXEC = ssh $SSH_USER@$MACHINE $SSH_COMMAND";
409
410# The way to copy a file to the target
411# (default scp $SRC_FILE $SSH_USER@$MACHINE:$DST_FILE)
412# The variables SSH_USER, MACHINE, SRC_FILE and DST_FILE are defined.
413#SCP_TO_TARGET = scp $SRC_FILE $SSH_USER@$MACHINE:$DST_FILE
414
415# The nice way to reboot the target
416# (default ssh $SSH_USER@$MACHINE reboot)
417# The variables SSH_USER and MACHINE are defined.
418#REBOOT = ssh $SSH_USER@$MACHINE reboot
419
420#### Per test run options ####
421# The following options are only allowed in TEST_START sections.
422# They are ignored in the DEFAULTS sections.
423#
424# All of these are optional and undefined by default, although
425# some of these options are required for TEST_TYPE of patchcheck
426# and bisect.
427#
428#
429# CHECKOUT = branch
430#
431# If the BUILD_DIR is a git repository, then you can set this option
432# to checkout the given branch before running the TEST. If you
433# specify this for the first run, that branch will be used for
434# all preceding tests until a new CHECKOUT is set.
435#
436#
437#
438# For TEST_TYPE = patchcheck
439#
440# This expects the BUILD_DIR to be a git repository, and
441# will checkout the PATCHCHECK_START commit.
442#
443# The option BUILD_TYPE will be ignored.
444#
445# The MIN_CONFIG will be used for all builds of the patchcheck. The build type
446# used for patchcheck is oldconfig.
447#
448# PATCHCHECK_START is required and is the first patch to
449# test (the SHA1 of the commit). You may also specify anything
450# that git checkout allows (branch name, tage, HEAD~3).
451#
452# PATCHCHECK_END is the last patch to check (default HEAD)
453#
454# PATCHCHECK_TYPE is required and is the type of test to run:
455# build, boot, test.
456#
457# Note, the build test will look for warnings, if a warning occurred
458# in a file that a commit touches, the build will fail.
459#
460# If BUILD_NOCLEAN is set, then make mrproper will not be run on
461# any of the builds, just like all other TEST_TYPE tests. But
462# what makes patchcheck different from the other tests, is if
463# BUILD_NOCLEAN is not set, only the first and last patch run
464# make mrproper. This helps speed up the test.
465#
466# Example:
467# TEST_START
468# TEST_TYPE = patchcheck
469# CHECKOUT = mybranch
470# PATCHCHECK_TYPE = boot
471# PATCHCHECK_START = 747e94ae3d1b4c9bf5380e569f614eb9040b79e7
472# PATCHCHECK_END = HEAD~2
473#
474#
475#
476# For TEST_TYPE = bisect
477#
478# You can specify a git bisect if the BUILD_DIR is a git repository.
479# The MIN_CONFIG will be used for all builds of the bisect. The build type
480# used for bisecting is oldconfig.
481#
482# The option BUILD_TYPE will be ignored.
483#
484# BISECT_TYPE is the type of test to perform:
485# build - bad fails to build
486# boot - bad builds but fails to boot
487# test - bad boots but fails a test
488#
489# BISECT_GOOD is the commit (SHA1) to label as good (accepts all git good commit types)
490# BISECT_BAD is the commit to label as bad (accepts all git bad commit types)
491#
492# The above three options are required for a bisect operation.
493#
494# BISECT_REPLAY = /path/to/replay/file (optional, default undefined)
495#
496# If an operation failed in the bisect that was not expected to
497# fail. Then the test ends. The state of the BUILD_DIR will be
498# left off at where the failure occurred. You can examine the
499# reason for the failure, and perhaps even find a git commit
500# that would work to continue with. You can run:
501#
502# git bisect log > /path/to/replay/file
503#
504# The adding:
505#
506# BISECT_REPLAY= /path/to/replay/file
507#
508# And running the test again. The test will perform the initial
509# git bisect start, git bisect good, and git bisect bad, and
510# then it will run git bisect replay on this file, before
511# continuing with the bisect.
512#
513# BISECT_START = commit (optional, default undefined)
514#
515# As with BISECT_REPLAY, if the test failed on a commit that
516# just happen to have a bad commit in the middle of the bisect,
517# and you need to skip it. If BISECT_START is defined, it
518# will checkout that commit after doing the initial git bisect start,
519# git bisect good, git bisect bad, and running the git bisect replay
520# if the BISECT_REPLAY is set.
521#
522# BISECT_REVERSE = 1 (optional, default 0)
523#
524# In those strange instances where it was broken forever
525# and you are trying to find where it started to work!
526# Set BISECT_GOOD to the commit that was last known to fail
527# Set BISECT_BAD to the commit that is known to start working.
528# With BISECT_REVERSE = 1, The test will consider failures as
529# good, and success as bad.
530#
531# BISECT_CHECK = 1 (optional, default 0)
532#
533# Just to be sure the good is good and bad is bad, setting
534# BISECT_CHECK to 1 will start the bisect by first checking
535# out BISECT_BAD and makes sure it fails, then it will check
536# out BISECT_GOOD and makes sure it succeeds before starting
537# the bisect (it works for BISECT_REVERSE too).
538#
539# You can limit the test to just check BISECT_GOOD or
540# BISECT_BAD with BISECT_CHECK = good or
541# BISECT_CHECK = bad, respectively.
542#
543# Example:
544# TEST_START
545# TEST_TYPE = bisect
546# BISECT_GOOD = v2.6.36
547# BISECT_BAD = b5153163ed580e00c67bdfecb02b2e3843817b3e
548# BISECT_TYPE = build
549# MIN_CONFIG = /home/test/config-bisect
550#
551#
552#
553# For TEST_TYPE = config_bisect
554#
555# In those cases that you have two different configs. One of them
556# work, the other does not, and you do not know what config causes
557# the problem.
558# The TEST_TYPE config_bisect will bisect the bad config looking for
559# what config causes the failure.
560#
561# The way it works is this:
562#
563# First it finds a config to work with. Since a different version, or
564# MIN_CONFIG may cause different dependecies, it must run through this
565# preparation.
566#
567# Overwrites any config set in the bad config with a config set in
568# either the MIN_CONFIG or ADD_CONFIG. Thus, make sure these configs
569# are minimal and do not disable configs you want to test:
570# (ie. # CONFIG_FOO is not set).
571#
572# An oldconfig is run on the bad config and any new config that
573# appears will be added to the configs to test.
574#
575# Finally, it generates a config with the above result and runs it
576# again through make oldconfig to produce a config that should be
577# satisfied by kconfig.
578#
579# Then it starts the bisect.
580#
581# The configs to test are cut in half. If all the configs in this
582# half depend on a config in the other half, then the other half
583# is tested instead. If no configs are enabled by either half, then
584# this means a circular dependency exists and the test fails.
585#
586# A config is created with the test half, and the bisect test is run.
587#
588# If the bisect succeeds, then all configs in the generated config
589# are removed from the configs to test and added to the configs that
590# will be enabled for all builds (they will be enabled, but not be part
591# of the configs to examine).
592#
593# If the bisect fails, then all test configs that were not enabled by
594# the config file are removed from the test. These configs will not
595# be enabled in future tests. Since current config failed, we consider
596# this to be a subset of the config that we started with.
597#
598# When we are down to one config, it is considered the bad config.
599#
600# Note, the config chosen may not be the true bad config. Due to
601# dependencies and selections of the kbuild system, mulitple
602# configs may be needed to cause a failure. If you disable the
603# config that was found and restart the test, if the test fails
604# again, it is recommended to rerun the config_bisect with a new
605# bad config without the found config enabled.
606#
607# The option BUILD_TYPE will be ignored.
608#
609# CONFIG_BISECT_TYPE is the type of test to perform:
610# build - bad fails to build
611# boot - bad builds but fails to boot
612# test - bad boots but fails a test
613#
614# CONFIG_BISECT is the config that failed to boot
615#
616# Example:
617# TEST_START
618# TEST_TYPE = config_bisect
619# CONFIG_BISECT_TYPE = build
620# CONFIG_BISECT = /home/test/¢onfig-bad
621# MIN_CONFIG = /home/test/config-min
622#
diff --git a/tools/virtio/Makefile b/tools/virtio/Makefile
new file mode 100644
index 000000000000..d1d442ed106a
--- /dev/null
+++ b/tools/virtio/Makefile
@@ -0,0 +1,12 @@
1all: test mod
2test: virtio_test
3virtio_test: virtio_ring.o virtio_test.o
4CFLAGS += -g -O2 -Wall -I. -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -MMD
5vpath %.c ../../drivers/virtio
6mod:
7 ${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test
8.PHONY: all test mod clean
9clean:
10 ${RM} *.o vhost_test/*.o vhost_test/.*.cmd \
11 vhost_test/Module.symvers vhost_test/modules.order *.d
12-include *.d
diff --git a/tools/virtio/linux/device.h b/tools/virtio/linux/device.h
new file mode 100644
index 000000000000..4ad7e1df0db5
--- /dev/null
+++ b/tools/virtio/linux/device.h
@@ -0,0 +1,2 @@
1#ifndef LINUX_DEVICE_H
2#endif
diff --git a/tools/virtio/linux/slab.h b/tools/virtio/linux/slab.h
new file mode 100644
index 000000000000..81baeac8ae40
--- /dev/null
+++ b/tools/virtio/linux/slab.h
@@ -0,0 +1,2 @@
1#ifndef LINUX_SLAB_H
2#endif
diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h
new file mode 100644
index 000000000000..669bcdd45805
--- /dev/null
+++ b/tools/virtio/linux/virtio.h
@@ -0,0 +1,223 @@
1#ifndef LINUX_VIRTIO_H
2#define LINUX_VIRTIO_H
3
4#include <stdbool.h>
5#include <stdlib.h>
6#include <stddef.h>
7#include <stdio.h>
8#include <string.h>
9#include <assert.h>
10
11#include <linux/types.h>
12#include <errno.h>
13
14typedef unsigned long long dma_addr_t;
15
16struct scatterlist {
17 unsigned long page_link;
18 unsigned int offset;
19 unsigned int length;
20 dma_addr_t dma_address;
21};
22
23struct page {
24 unsigned long long dummy;
25};
26
27#define BUG_ON(__BUG_ON_cond) assert(!(__BUG_ON_cond))
28
29/* Physical == Virtual */
30#define virt_to_phys(p) ((unsigned long)p)
31#define phys_to_virt(a) ((void *)(unsigned long)(a))
32/* Page address: Virtual / 4K */
33#define virt_to_page(p) ((struct page*)((virt_to_phys(p) / 4096) * \
34 sizeof(struct page)))
35#define offset_in_page(p) (((unsigned long)p) % 4096)
36#define sg_phys(sg) ((sg->page_link & ~0x3) / sizeof(struct page) * 4096 + \
37 sg->offset)
38static inline void sg_mark_end(struct scatterlist *sg)
39{
40 /*
41 * Set termination bit, clear potential chain bit
42 */
43 sg->page_link |= 0x02;
44 sg->page_link &= ~0x01;
45}
46static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
47{
48 memset(sgl, 0, sizeof(*sgl) * nents);
49 sg_mark_end(&sgl[nents - 1]);
50}
51static inline void sg_assign_page(struct scatterlist *sg, struct page *page)
52{
53 unsigned long page_link = sg->page_link & 0x3;
54
55 /*
56 * In order for the low bit stealing approach to work, pages
57 * must be aligned at a 32-bit boundary as a minimum.
58 */
59 BUG_ON((unsigned long) page & 0x03);
60 sg->page_link = page_link | (unsigned long) page;
61}
62
63static inline void sg_set_page(struct scatterlist *sg, struct page *page,
64 unsigned int len, unsigned int offset)
65{
66 sg_assign_page(sg, page);
67 sg->offset = offset;
68 sg->length = len;
69}
70
71static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
72 unsigned int buflen)
73{
74 sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
75}
76
77static inline void sg_init_one(struct scatterlist *sg, const void *buf, unsigned int buflen)
78{
79 sg_init_table(sg, 1);
80 sg_set_buf(sg, buf, buflen);
81}
82
83typedef __u16 u16;
84
85typedef enum {
86 GFP_KERNEL,
87 GFP_ATOMIC,
88} gfp_t;
89typedef enum {
90 IRQ_NONE,
91 IRQ_HANDLED
92} irqreturn_t;
93
94static inline void *kmalloc(size_t s, gfp_t gfp)
95{
96 return malloc(s);
97}
98
99static inline void kfree(void *p)
100{
101 free(p);
102}
103
104#define container_of(ptr, type, member) ({ \
105 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
106 (type *)( (char *)__mptr - offsetof(type,member) );})
107
108#define uninitialized_var(x) x = x
109
110# ifndef likely
111# define likely(x) (__builtin_expect(!!(x), 1))
112# endif
113# ifndef unlikely
114# define unlikely(x) (__builtin_expect(!!(x), 0))
115# endif
116
117#define pr_err(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
118#ifdef DEBUG
119#define pr_debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
120#else
121#define pr_debug(format, ...) do {} while (0)
122#endif
123#define dev_err(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__)
124#define dev_warn(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__)
125
126/* TODO: empty stubs for now. Broken but enough for virtio_ring.c */
127#define list_add_tail(a, b) do {} while (0)
128#define list_del(a) do {} while (0)
129
130#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
131#define BITS_PER_BYTE 8
132#define BITS_PER_LONG (sizeof(long) * BITS_PER_BYTE)
133#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
134/* TODO: Not atomic as it should be:
135 * we don't use this for anything important. */
136static inline void clear_bit(int nr, volatile unsigned long *addr)
137{
138 unsigned long mask = BIT_MASK(nr);
139 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
140
141 *p &= ~mask;
142}
143
144static inline int test_bit(int nr, const volatile unsigned long *addr)
145{
146 return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
147}
148
149/* The only feature we care to support */
150#define virtio_has_feature(dev, feature) \
151 test_bit((feature), (dev)->features)
152/* end of stubs */
153
154struct virtio_device {
155 void *dev;
156 unsigned long features[1];
157};
158
159struct virtqueue {
160 /* TODO: commented as list macros are empty stubs for now.
161 * Broken but enough for virtio_ring.c
162 * struct list_head list; */
163 void (*callback)(struct virtqueue *vq);
164 const char *name;
165 struct virtio_device *vdev;
166 void *priv;
167};
168
169#define EXPORT_SYMBOL_GPL(__EXPORT_SYMBOL_GPL_name) \
170 void __EXPORT_SYMBOL_GPL##__EXPORT_SYMBOL_GPL_name() { \
171}
172#define MODULE_LICENSE(__MODULE_LICENSE_value) \
173 const char *__MODULE_LICENSE_name = __MODULE_LICENSE_value
174
175#define CONFIG_SMP
176
177#if defined(__i386__) || defined(__x86_64__)
178#define barrier() asm volatile("" ::: "memory")
179#define mb() __sync_synchronize()
180
181#define smp_mb() mb()
182# define smp_rmb() barrier()
183# define smp_wmb() barrier()
184#else
185#error Please fill in barrier macros
186#endif
187
188/* Interfaces exported by virtio_ring. */
189int virtqueue_add_buf_gfp(struct virtqueue *vq,
190 struct scatterlist sg[],
191 unsigned int out_num,
192 unsigned int in_num,
193 void *data,
194 gfp_t gfp);
195
196static inline int virtqueue_add_buf(struct virtqueue *vq,
197 struct scatterlist sg[],
198 unsigned int out_num,
199 unsigned int in_num,
200 void *data)
201{
202 return virtqueue_add_buf_gfp(vq, sg, out_num, in_num, data, GFP_ATOMIC);
203}
204
205void virtqueue_kick(struct virtqueue *vq);
206
207void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len);
208
209void virtqueue_disable_cb(struct virtqueue *vq);
210
211bool virtqueue_enable_cb(struct virtqueue *vq);
212
213void *virtqueue_detach_unused_buf(struct virtqueue *vq);
214struct virtqueue *vring_new_virtqueue(unsigned int num,
215 unsigned int vring_align,
216 struct virtio_device *vdev,
217 void *pages,
218 void (*notify)(struct virtqueue *vq),
219 void (*callback)(struct virtqueue *vq),
220 const char *name);
221void vring_del_virtqueue(struct virtqueue *vq);
222
223#endif
diff --git a/tools/virtio/vhost_test/Makefile b/tools/virtio/vhost_test/Makefile
new file mode 100644
index 000000000000..a1d35b81b314
--- /dev/null
+++ b/tools/virtio/vhost_test/Makefile
@@ -0,0 +1,2 @@
1obj-m += vhost_test.o
2EXTRA_CFLAGS += -Idrivers/vhost
diff --git a/tools/virtio/vhost_test/vhost_test.c b/tools/virtio/vhost_test/vhost_test.c
new file mode 100644
index 000000000000..18735189e62b
--- /dev/null
+++ b/tools/virtio/vhost_test/vhost_test.c
@@ -0,0 +1 @@
#include "test.c"
diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c
new file mode 100644
index 000000000000..df0c6d2c3860
--- /dev/null
+++ b/tools/virtio/virtio_test.c
@@ -0,0 +1,248 @@
1#define _GNU_SOURCE
2#include <getopt.h>
3#include <string.h>
4#include <poll.h>
5#include <sys/eventfd.h>
6#include <stdlib.h>
7#include <assert.h>
8#include <unistd.h>
9#include <sys/ioctl.h>
10#include <sys/stat.h>
11#include <sys/types.h>
12#include <fcntl.h>
13#include <linux/vhost.h>
14#include <linux/virtio.h>
15#include <linux/virtio_ring.h>
16#include "../../drivers/vhost/test.h"
17
18struct vq_info {
19 int kick;
20 int call;
21 int num;
22 int idx;
23 void *ring;
24 /* copy used for control */
25 struct vring vring;
26 struct virtqueue *vq;
27};
28
29struct vdev_info {
30 struct virtio_device vdev;
31 int control;
32 struct pollfd fds[1];
33 struct vq_info vqs[1];
34 int nvqs;
35 void *buf;
36 size_t buf_size;
37 struct vhost_memory *mem;
38};
39
40void vq_notify(struct virtqueue *vq)
41{
42 struct vq_info *info = vq->priv;
43 unsigned long long v = 1;
44 int r;
45 r = write(info->kick, &v, sizeof v);
46 assert(r == sizeof v);
47}
48
49void vq_callback(struct virtqueue *vq)
50{
51}
52
53
54void vhost_vq_setup(struct vdev_info *dev, struct vq_info *info)
55{
56 struct vhost_vring_state state = { .index = info->idx };
57 struct vhost_vring_file file = { .index = info->idx };
58 unsigned long long features = dev->vdev.features[0];
59 struct vhost_vring_addr addr = {
60 .index = info->idx,
61 .desc_user_addr = (uint64_t)(unsigned long)info->vring.desc,
62 .avail_user_addr = (uint64_t)(unsigned long)info->vring.avail,
63 .used_user_addr = (uint64_t)(unsigned long)info->vring.used,
64 };
65 int r;
66 r = ioctl(dev->control, VHOST_SET_FEATURES, &features);
67 assert(r >= 0);
68 state.num = info->vring.num;
69 r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state);
70 assert(r >= 0);
71 state.num = 0;
72 r = ioctl(dev->control, VHOST_SET_VRING_BASE, &state);
73 assert(r >= 0);
74 r = ioctl(dev->control, VHOST_SET_VRING_ADDR, &addr);
75 assert(r >= 0);
76 file.fd = info->kick;
77 r = ioctl(dev->control, VHOST_SET_VRING_KICK, &file);
78 assert(r >= 0);
79 file.fd = info->call;
80 r = ioctl(dev->control, VHOST_SET_VRING_CALL, &file);
81 assert(r >= 0);
82}
83
84static void vq_info_add(struct vdev_info *dev, int num)
85{
86 struct vq_info *info = &dev->vqs[dev->nvqs];
87 int r;
88 info->idx = dev->nvqs;
89 info->kick = eventfd(0, EFD_NONBLOCK);
90 info->call = eventfd(0, EFD_NONBLOCK);
91 r = posix_memalign(&info->ring, 4096, vring_size(num, 4096));
92 assert(r >= 0);
93 memset(info->ring, 0, vring_size(num, 4096));
94 vring_init(&info->vring, num, info->ring, 4096);
95 info->vq = vring_new_virtqueue(info->vring.num, 4096, &dev->vdev, info->ring,
96 vq_notify, vq_callback, "test");
97 assert(info->vq);
98 info->vq->priv = info;
99 vhost_vq_setup(dev, info);
100 dev->fds[info->idx].fd = info->call;
101 dev->fds[info->idx].events = POLLIN;
102 dev->nvqs++;
103}
104
105static void vdev_info_init(struct vdev_info* dev, unsigned long long features)
106{
107 int r;
108 memset(dev, 0, sizeof *dev);
109 dev->vdev.features[0] = features;
110 dev->vdev.features[1] = features >> 32;
111 dev->buf_size = 1024;
112 dev->buf = malloc(dev->buf_size);
113 assert(dev->buf);
114 dev->control = open("/dev/vhost-test", O_RDWR);
115 assert(dev->control >= 0);
116 r = ioctl(dev->control, VHOST_SET_OWNER, NULL);
117 assert(r >= 0);
118 dev->mem = malloc(offsetof(struct vhost_memory, regions) +
119 sizeof dev->mem->regions[0]);
120 assert(dev->mem);
121 memset(dev->mem, 0, offsetof(struct vhost_memory, regions) +
122 sizeof dev->mem->regions[0]);
123 dev->mem->nregions = 1;
124 dev->mem->regions[0].guest_phys_addr = (long)dev->buf;
125 dev->mem->regions[0].userspace_addr = (long)dev->buf;
126 dev->mem->regions[0].memory_size = dev->buf_size;
127 r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem);
128 assert(r >= 0);
129}
130
131/* TODO: this is pretty bad: we get a cache line bounce
132 * for the wait queue on poll and another one on read,
133 * plus the read which is there just to clear the
134 * current state. */
135static void wait_for_interrupt(struct vdev_info *dev)
136{
137 int i;
138 unsigned long long val;
139 poll(dev->fds, dev->nvqs, -1);
140 for (i = 0; i < dev->nvqs; ++i)
141 if (dev->fds[i].revents & POLLIN) {
142 read(dev->fds[i].fd, &val, sizeof val);
143 }
144}
145
146static void run_test(struct vdev_info *dev, struct vq_info *vq, int bufs)
147{
148 struct scatterlist sl;
149 long started = 0, completed = 0;
150 long completed_before;
151 int r, test = 1;
152 unsigned len;
153 long long spurious = 0;
154 r = ioctl(dev->control, VHOST_TEST_RUN, &test);
155 assert(r >= 0);
156 for (;;) {
157 virtqueue_disable_cb(vq->vq);
158 completed_before = completed;
159 do {
160 if (started < bufs) {
161 sg_init_one(&sl, dev->buf, dev->buf_size);
162 r = virtqueue_add_buf(vq->vq, &sl, 1, 0,
163 dev->buf + started);
164 if (likely(r >= 0)) {
165 ++started;
166 virtqueue_kick(vq->vq);
167 }
168 } else
169 r = -1;
170
171 /* Flush out completed bufs if any */
172 if (virtqueue_get_buf(vq->vq, &len)) {
173 ++completed;
174 r = 0;
175 }
176
177 } while (r >= 0);
178 if (completed == completed_before)
179 ++spurious;
180 assert(completed <= bufs);
181 assert(started <= bufs);
182 if (completed == bufs)
183 break;
184 if (virtqueue_enable_cb(vq->vq)) {
185 wait_for_interrupt(dev);
186 }
187 }
188 test = 0;
189 r = ioctl(dev->control, VHOST_TEST_RUN, &test);
190 assert(r >= 0);
191 fprintf(stderr, "spurious wakeus: 0x%llx\n", spurious);
192}
193
194const char optstring[] = "h";
195const struct option longopts[] = {
196 {
197 .name = "help",
198 .val = 'h',
199 },
200 {
201 .name = "indirect",
202 .val = 'I',
203 },
204 {
205 .name = "no-indirect",
206 .val = 'i',
207 },
208 {
209 }
210};
211
212static void help()
213{
214 fprintf(stderr, "Usage: virtio_test [--help] [--no-indirect]\n");
215}
216
217int main(int argc, char **argv)
218{
219 struct vdev_info dev;
220 unsigned long long features = 1ULL << VIRTIO_RING_F_INDIRECT_DESC;
221 int o;
222
223 for (;;) {
224 o = getopt_long(argc, argv, optstring, longopts, NULL);
225 switch (o) {
226 case -1:
227 goto done;
228 case '?':
229 help();
230 exit(2);
231 case 'h':
232 help();
233 goto done;
234 case 'i':
235 features &= ~(1ULL << VIRTIO_RING_F_INDIRECT_DESC);
236 break;
237 default:
238 assert(0);
239 break;
240 }
241 }
242
243done:
244 vdev_info_init(&dev, features);
245 vq_info_add(&dev, 256);
246 run_test(&dev, &dev.vqs[0], 0x100000);
247 return 0;
248}