aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/lib/traceevent/event-parse.c9
-rw-r--r--tools/lib/traceevent/parse-filter.c15
-rw-r--r--tools/perf/Makefile24
-rw-r--r--tools/perf/builtin-help.c2
-rw-r--r--tools/perf/builtin-trace.c18
-rw-r--r--tools/perf/perf.h2
-rw-r--r--tools/perf/ui/browsers/hists.c6
-rw-r--r--tools/perf/util/parse-events-test.c12
-rw-r--r--tools/perf/util/parse-events.c3
-rw-r--r--tools/perf/util/setup.py2
-rw-r--r--tools/perf/util/sort.c6
-rw-r--r--tools/perf/util/thread.c1
-rwxr-xr-xtools/testing/ktest/ktest.pl6
-rw-r--r--tools/testing/selftests/Makefile2
-rw-r--r--tools/testing/selftests/epoll/Makefile11
-rw-r--r--tools/testing/selftests/epoll/test_epoll.c344
-rw-r--r--tools/vm/page-types.c2
17 files changed, 78 insertions, 387 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 47264b4652b9..f2989c525e48 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -2602,6 +2602,9 @@ find_func_handler(struct pevent *pevent, char *func_name)
2602{ 2602{
2603 struct pevent_function_handler *func; 2603 struct pevent_function_handler *func;
2604 2604
2605 if (!pevent)
2606 return NULL;
2607
2605 for (func = pevent->func_handlers; func; func = func->next) { 2608 for (func = pevent->func_handlers; func; func = func->next) {
2606 if (strcmp(func->name, func_name) == 0) 2609 if (strcmp(func->name, func_name) == 0)
2607 break; 2610 break;
@@ -4938,6 +4941,9 @@ enum pevent_errno __pevent_parse_format(struct event_format **eventp,
4938 goto event_alloc_failed; 4941 goto event_alloc_failed;
4939 } 4942 }
4940 4943
4944 /* Add pevent to event so that it can be referenced */
4945 event->pevent = pevent;
4946
4941 ret = event_read_format(event); 4947 ret = event_read_format(event);
4942 if (ret < 0) { 4948 if (ret < 0) {
4943 ret = PEVENT_ERRNO__READ_FORMAT_FAILED; 4949 ret = PEVENT_ERRNO__READ_FORMAT_FAILED;
@@ -5041,9 +5047,6 @@ enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
5041 if (event == NULL) 5047 if (event == NULL)
5042 return ret; 5048 return ret;
5043 5049
5044 /* Add pevent to event so that it can be referenced */
5045 event->pevent = pevent;
5046
5047 if (add_event(pevent, event)) { 5050 if (add_event(pevent, event)) {
5048 ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; 5051 ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
5049 goto event_add_failed; 5052 goto event_add_failed;
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index ad17855528f9..5ea4326ad11f 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -209,7 +209,16 @@ static void free_arg(struct filter_arg *arg)
209 switch (arg->type) { 209 switch (arg->type) {
210 case FILTER_ARG_NONE: 210 case FILTER_ARG_NONE:
211 case FILTER_ARG_BOOLEAN: 211 case FILTER_ARG_BOOLEAN:
212 break;
213
212 case FILTER_ARG_NUM: 214 case FILTER_ARG_NUM:
215 free_arg(arg->num.left);
216 free_arg(arg->num.right);
217 break;
218
219 case FILTER_ARG_EXP:
220 free_arg(arg->exp.left);
221 free_arg(arg->exp.right);
213 break; 222 break;
214 223
215 case FILTER_ARG_STR: 224 case FILTER_ARG_STR:
@@ -218,6 +227,12 @@ static void free_arg(struct filter_arg *arg)
218 free(arg->str.buffer); 227 free(arg->str.buffer);
219 break; 228 break;
220 229
230 case FILTER_ARG_VALUE:
231 if (arg->value.type == FILTER_STRING ||
232 arg->value.type == FILTER_CHAR)
233 free(arg->value.str);
234 break;
235
221 case FILTER_ARG_OP: 236 case FILTER_ARG_OP:
222 free_arg(arg->op.left); 237 free_arg(arg->op.left);
223 free_arg(arg->op.right); 238 free_arg(arg->op.right);
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index f7c968ad5178..00deed4d6159 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -184,9 +184,22 @@ SCRIPT_SH += perf-archive.sh
184grep-libs = $(filter -l%,$(1)) 184grep-libs = $(filter -l%,$(1))
185strip-libs = $(filter-out -l%,$(1)) 185strip-libs = $(filter-out -l%,$(1))
186 186
187TRACE_EVENT_DIR = ../lib/traceevent/
188
189ifneq ($(OUTPUT),)
190 TE_PATH=$(OUTPUT)
191else
192 TE_PATH=$(TRACE_EVENT_DIR)
193endif
194
195LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
196TE_LIB := -L$(TE_PATH) -ltraceevent
197
187PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources) 198PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
188PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py 199PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py
189 200
201export LIBTRACEEVENT
202
190$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) 203$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
191 $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \ 204 $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \
192 --quiet build_ext; \ 205 --quiet build_ext; \
@@ -198,17 +211,6 @@ $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
198 211
199SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) 212SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH))
200 213
201TRACE_EVENT_DIR = ../lib/traceevent/
202
203ifneq ($(OUTPUT),)
204 TE_PATH=$(OUTPUT)
205else
206 TE_PATH=$(TRACE_EVENT_DIR)
207endif
208
209LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
210TE_LIB := -L$(TE_PATH) -ltraceevent
211
212# 214#
213# Single 'perf' binary right now: 215# Single 'perf' binary right now:
214# 216#
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 411ee5664e98..178b88ae3d2f 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -414,7 +414,7 @@ static int show_html_page(const char *perf_cmd)
414int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused) 414int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused)
415{ 415{
416 bool show_all = false; 416 bool show_all = false;
417 enum help_format help_format = HELP_FORMAT_NONE; 417 enum help_format help_format = HELP_FORMAT_MAN;
418 struct option builtin_help_options[] = { 418 struct option builtin_help_options[] = {
419 OPT_BOOLEAN('a', "all", &show_all, "print all available commands"), 419 OPT_BOOLEAN('a', "all", &show_all, "print all available commands"),
420 OPT_SET_UINT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN), 420 OPT_SET_UINT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN),
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index dec8ced61fb0..7aaee39f6774 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -56,6 +56,10 @@ static int trace__read_syscall_info(struct trace *trace, int id)
56{ 56{
57 char tp_name[128]; 57 char tp_name[128];
58 struct syscall *sc; 58 struct syscall *sc;
59 const char *name = audit_syscall_to_name(id, trace->audit_machine);
60
61 if (name == NULL)
62 return -1;
59 63
60 if (id > trace->syscalls.max) { 64 if (id > trace->syscalls.max) {
61 struct syscall *nsyscalls = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc)); 65 struct syscall *nsyscalls = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc));
@@ -75,11 +79,8 @@ static int trace__read_syscall_info(struct trace *trace, int id)
75 } 79 }
76 80
77 sc = trace->syscalls.table + id; 81 sc = trace->syscalls.table + id;
78 sc->name = audit_syscall_to_name(id, trace->audit_machine); 82 sc->name = name;
79 if (sc->name == NULL) 83 sc->fmt = syscall_fmt__find(sc->name);
80 return -1;
81
82 sc->fmt = syscall_fmt__find(sc->name);
83 84
84 snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name); 85 snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name);
85 sc->tp_format = event_format__new("syscalls", tp_name); 86 sc->tp_format = event_format__new("syscalls", tp_name);
@@ -267,6 +268,13 @@ again:
267 if (evlist->threads->map[0] == -1 || evlist->threads->nr > 1) 268 if (evlist->threads->map[0] == -1 || evlist->threads->nr > 1)
268 printf("%d ", sample.tid); 269 printf("%d ", sample.tid);
269 270
271 if (sample.raw_data == NULL) {
272 printf("%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
273 perf_evsel__name(evsel), sample.tid,
274 sample.cpu, sample.raw_size);
275 continue;
276 }
277
270 handler = evsel->handler.func; 278 handler = evsel->handler.func;
271 handler(trace, evsel, &sample); 279 handler(trace, evsel, &sample);
272 } 280 }
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 276287783a03..c50985eaec41 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -57,7 +57,7 @@ void get_term_dimensions(struct winsize *ws);
57#endif 57#endif
58 58
59#ifdef __sparc__ 59#ifdef __sparc__
60#include "../../arch/sparc/include/asm/unistd.h" 60#include "../../arch/sparc/include/uapi/asm/unistd.h"
61#define rmb() asm volatile("":::"memory") 61#define rmb() asm volatile("":::"memory")
62#define cpu_relax() asm volatile("":::"memory") 62#define cpu_relax() asm volatile("":::"memory")
63#define CPUINFO_PROC "cpu" 63#define CPUINFO_PROC "cpu"
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 0568536ecf67..ef2f93ca7496 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -610,6 +610,7 @@ static int hist_browser__show_entry(struct hist_browser *browser,
610 char folded_sign = ' '; 610 char folded_sign = ' ';
611 bool current_entry = ui_browser__is_current_entry(&browser->b, row); 611 bool current_entry = ui_browser__is_current_entry(&browser->b, row);
612 off_t row_offset = entry->row_offset; 612 off_t row_offset = entry->row_offset;
613 bool first = true;
613 614
614 if (current_entry) { 615 if (current_entry) {
615 browser->he_selection = entry; 616 browser->he_selection = entry;
@@ -633,10 +634,11 @@ static int hist_browser__show_entry(struct hist_browser *browser,
633 if (!perf_hpp__format[i].cond) 634 if (!perf_hpp__format[i].cond)
634 continue; 635 continue;
635 636
636 if (i) { 637 if (!first) {
637 slsmg_printf(" "); 638 slsmg_printf(" ");
638 width -= 2; 639 width -= 2;
639 } 640 }
641 first = false;
640 642
641 if (perf_hpp__format[i].color) { 643 if (perf_hpp__format[i].color) {
642 hpp.ptr = &percent; 644 hpp.ptr = &percent;
@@ -645,7 +647,7 @@ static int hist_browser__show_entry(struct hist_browser *browser,
645 647
646 ui_browser__set_percent_color(&browser->b, percent, current_entry); 648 ui_browser__set_percent_color(&browser->b, percent, current_entry);
647 649
648 if (i == 0 && symbol_conf.use_callchain) { 650 if (i == PERF_HPP__OVERHEAD && symbol_conf.use_callchain) {
649 slsmg_printf("%c ", folded_sign); 651 slsmg_printf("%c ", folded_sign);
650 width -= 2; 652 width -= 2;
651 } 653 }
diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c
index 28c18d1d52c3..516ecd9ddd6e 100644
--- a/tools/perf/util/parse-events-test.c
+++ b/tools/perf/util/parse-events-test.c
@@ -513,7 +513,8 @@ static int test__group1(struct perf_evlist *evlist)
513 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); 513 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
514 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); 514 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
515 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); 515 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
516 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); 516 /* use of precise requires exclude_guest */
517 TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
517 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); 518 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
518 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2); 519 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2);
519 TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); 520 TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
@@ -599,7 +600,8 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused)
599 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); 600 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
600 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); 601 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
601 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); 602 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
602 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); 603 /* use of precise requires exclude_guest */
604 TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
603 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); 605 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
604 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 3); 606 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 3);
605 TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); 607 TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
@@ -662,7 +664,8 @@ static int test__group4(struct perf_evlist *evlist __maybe_unused)
662 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); 664 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
663 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); 665 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
664 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); 666 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
665 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); 667 /* use of precise requires exclude_guest */
668 TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
666 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); 669 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
667 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 1); 670 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 1);
668 TEST_ASSERT_VAL("wrong group name", !evsel->group_name); 671 TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
@@ -676,7 +679,8 @@ static int test__group4(struct perf_evlist *evlist __maybe_unused)
676 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); 679 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
677 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); 680 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
678 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); 681 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
679 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); 682 /* use of precise requires exclude_guest */
683 TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
680 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); 684 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
681 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2); 685 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2);
682 TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); 686 TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index aed38e4b9dfa..75c7b0fca6d9 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -690,6 +690,9 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
690 eH = 0; 690 eH = 0;
691 } else if (*str == 'p') { 691 } else if (*str == 'p') {
692 precise++; 692 precise++;
693 /* use of precise requires exclude_guest */
694 if (!exclude_GH)
695 eG = 1;
693 } else 696 } else
694 break; 697 break;
695 698
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index d0f9f29cf181..73d510269784 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -23,6 +23,7 @@ cflags += getenv('CFLAGS', '').split()
23 23
24build_lib = getenv('PYTHON_EXTBUILD_LIB') 24build_lib = getenv('PYTHON_EXTBUILD_LIB')
25build_tmp = getenv('PYTHON_EXTBUILD_TMP') 25build_tmp = getenv('PYTHON_EXTBUILD_TMP')
26libtraceevent = getenv('LIBTRACEEVENT')
26 27
27ext_sources = [f.strip() for f in file('util/python-ext-sources') 28ext_sources = [f.strip() for f in file('util/python-ext-sources')
28 if len(f.strip()) > 0 and f[0] != '#'] 29 if len(f.strip()) > 0 and f[0] != '#']
@@ -31,6 +32,7 @@ perf = Extension('perf',
31 sources = ext_sources, 32 sources = ext_sources,
32 include_dirs = ['util/include'], 33 include_dirs = ['util/include'],
33 extra_compile_args = cflags, 34 extra_compile_args = cflags,
35 extra_objects = [libtraceevent],
34 ) 36 )
35 37
36setup(name='perf', 38setup(name='perf',
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index b5b1b9211960..cfd1c0feb32d 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -260,6 +260,12 @@ static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf,
260 if (path != NULL) 260 if (path != NULL)
261 goto out_path; 261 goto out_path;
262 262
263 if (!self->ms.map)
264 goto out_ip;
265
266 if (!strncmp(self->ms.map->dso->long_name, "/tmp/perf-", 10))
267 goto out_ip;
268
263 snprintf(cmd, sizeof(cmd), "addr2line -e %s %016" PRIx64, 269 snprintf(cmd, sizeof(cmd), "addr2line -e %s %016" PRIx64,
264 self->ms.map->dso->long_name, self->ip); 270 self->ms.map->dso->long_name, self->ip);
265 fp = popen(cmd, "r"); 271 fp = popen(cmd, "r");
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index fb4b7ea6752f..8b3e5939afb6 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -39,7 +39,6 @@ int thread__set_comm(struct thread *self, const char *comm)
39 err = self->comm == NULL ? -ENOMEM : 0; 39 err = self->comm == NULL ? -ENOMEM : 0;
40 if (!err) { 40 if (!err) {
41 self->comm_set = true; 41 self->comm_set = true;
42 map_groups__flush(&self->mg);
43 } 42 }
44 return err; 43 return err;
45} 44}
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index b51d787176d3..c7ba7614061b 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -1740,8 +1740,10 @@ sub install {
1740 open(IN, "$output_config") or dodie("Can't read config file"); 1740 open(IN, "$output_config") or dodie("Can't read config file");
1741 while (<IN>) { 1741 while (<IN>) {
1742 if (/CONFIG_MODULES(=y)?/) { 1742 if (/CONFIG_MODULES(=y)?/) {
1743 $install_mods = 1 if (defined($1)); 1743 if (defined($1)) {
1744 last; 1744 $install_mods = 1;
1745 last;
1746 }
1745 } 1747 }
1746 } 1748 }
1747 close(IN); 1749 close(IN);
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 43480149119e..85baf11e2acd 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -1,4 +1,4 @@
1TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug epoll 1TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug
2 2
3all: 3all:
4 for TARGET in $(TARGETS); do \ 4 for TARGET in $(TARGETS); do \
diff --git a/tools/testing/selftests/epoll/Makefile b/tools/testing/selftests/epoll/Makefile
deleted file mode 100644
index 19806ed62f50..000000000000
--- a/tools/testing/selftests/epoll/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
1# Makefile for epoll selftests
2
3all: test_epoll
4%: %.c
5 gcc -pthread -g -o $@ $^
6
7run_tests: all
8 ./test_epoll
9
10clean:
11 $(RM) test_epoll
diff --git a/tools/testing/selftests/epoll/test_epoll.c b/tools/testing/selftests/epoll/test_epoll.c
deleted file mode 100644
index e0fcff1e8331..000000000000
--- a/tools/testing/selftests/epoll/test_epoll.c
+++ /dev/null
@@ -1,344 +0,0 @@
1/*
2 * tools/testing/selftests/epoll/test_epoll.c
3 *
4 * Copyright 2012 Adobe Systems Incorporated
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * Paton J. Lewis <palewis@adobe.com>
12 *
13 */
14
15#include <errno.h>
16#include <fcntl.h>
17#include <pthread.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <unistd.h>
21#include <sys/epoll.h>
22#include <sys/socket.h>
23
24/*
25 * A pointer to an epoll_item_private structure will be stored in the epoll
26 * item's event structure so that we can get access to the epoll_item_private
27 * data after calling epoll_wait:
28 */
29struct epoll_item_private {
30 int index; /* Position of this struct within the epoll_items array. */
31 int fd;
32 uint32_t events;
33 pthread_mutex_t mutex; /* Guards the following variables... */
34 int stop;
35 int status; /* Stores any error encountered while handling item. */
36 /* The following variable allows us to test whether we have encountered
37 a problem while attempting to cancel and delete the associated
38 event. When the test program exits, 'deleted' should be exactly
39 one. If it is greater than one, then the failed test reflects a real
40 world situation where we would have tried to access the epoll item's
41 private data after deleting it: */
42 int deleted;
43};
44
45struct epoll_item_private *epoll_items;
46
47/*
48 * Delete the specified item from the epoll set. In a real-world secneario this
49 * is where we would free the associated data structure, but in this testing
50 * environment we retain the structure so that we can test for double-deletion:
51 */
52void delete_item(int index)
53{
54 __sync_fetch_and_add(&epoll_items[index].deleted, 1);
55}
56
57/*
58 * A pointer to a read_thread_data structure will be passed as the argument to
59 * each read thread:
60 */
61struct read_thread_data {
62 int stop;
63 int status; /* Indicates any error encountered by the read thread. */
64 int epoll_set;
65};
66
67/*
68 * The function executed by the read threads:
69 */
70void *read_thread_function(void *function_data)
71{
72 struct read_thread_data *thread_data =
73 (struct read_thread_data *)function_data;
74 struct epoll_event event_data;
75 struct epoll_item_private *item_data;
76 char socket_data;
77
78 /* Handle events until we encounter an error or this thread's 'stop'
79 condition is set: */
80 while (1) {
81 int result = epoll_wait(thread_data->epoll_set,
82 &event_data,
83 1, /* Number of desired events */
84 1000); /* Timeout in ms */
85 if (result < 0) {
86 /* Breakpoints signal all threads. Ignore that while
87 debugging: */
88 if (errno == EINTR)
89 continue;
90 thread_data->status = errno;
91 return 0;
92 } else if (thread_data->stop)
93 return 0;
94 else if (result == 0) /* Timeout */
95 continue;
96
97 /* We need the mutex here because checking for the stop
98 condition and re-enabling the epoll item need to be done
99 together as one atomic operation when EPOLL_CTL_DISABLE is
100 available: */
101 item_data = (struct epoll_item_private *)event_data.data.ptr;
102 pthread_mutex_lock(&item_data->mutex);
103
104 /* Remove the item from the epoll set if we want to stop
105 handling that event: */
106 if (item_data->stop)
107 delete_item(item_data->index);
108 else {
109 /* Clear the data that was written to the other end of
110 our non-blocking socket: */
111 do {
112 if (read(item_data->fd, &socket_data, 1) < 1) {
113 if ((errno == EAGAIN) ||
114 (errno == EWOULDBLOCK))
115 break;
116 else
117 goto error_unlock;
118 }
119 } while (item_data->events & EPOLLET);
120
121 /* The item was one-shot, so re-enable it: */
122 event_data.events = item_data->events;
123 if (epoll_ctl(thread_data->epoll_set,
124 EPOLL_CTL_MOD,
125 item_data->fd,
126 &event_data) < 0)
127 goto error_unlock;
128 }
129
130 pthread_mutex_unlock(&item_data->mutex);
131 }
132
133error_unlock:
134 thread_data->status = item_data->status = errno;
135 pthread_mutex_unlock(&item_data->mutex);
136 return 0;
137}
138
139/*
140 * A pointer to a write_thread_data structure will be passed as the argument to
141 * the write thread:
142 */
143struct write_thread_data {
144 int stop;
145 int status; /* Indicates any error encountered by the write thread. */
146 int n_fds;
147 int *fds;
148};
149
150/*
151 * The function executed by the write thread. It writes a single byte to each
152 * socket in turn until the stop condition for this thread is set. If writing to
153 * a socket would block (i.e. errno was EAGAIN), we leave that socket alone for
154 * the moment and just move on to the next socket in the list. We don't care
155 * about the order in which we deliver events to the epoll set. In fact we don't
156 * care about the data we're writing to the pipes at all; we just want to
157 * trigger epoll events:
158 */
159void *write_thread_function(void *function_data)
160{
161 const char data = 'X';
162 int index;
163 struct write_thread_data *thread_data =
164 (struct write_thread_data *)function_data;
165 while (!write_thread_data->stop)
166 for (index = 0;
167 !thread_data->stop && (index < thread_data->n_fds);
168 ++index)
169 if ((write(thread_data->fds[index], &data, 1) < 1) &&
170 (errno != EAGAIN) &&
171 (errno != EWOULDBLOCK)) {
172 write_thread_data->status = errno;
173 return;
174 }
175}
176
177/*
178 * Arguments are currently ignored:
179 */
180int main(int argc, char **argv)
181{
182 const int n_read_threads = 100;
183 const int n_epoll_items = 500;
184 int index;
185 int epoll_set = epoll_create1(0);
186 struct write_thread_data write_thread_data = {
187 0, 0, n_epoll_items, malloc(n_epoll_items * sizeof(int))
188 };
189 struct read_thread_data *read_thread_data =
190 malloc(n_read_threads * sizeof(struct read_thread_data));
191 pthread_t *read_threads = malloc(n_read_threads * sizeof(pthread_t));
192 pthread_t write_thread;
193
194 printf("-----------------\n");
195 printf("Runing test_epoll\n");
196 printf("-----------------\n");
197
198 epoll_items = malloc(n_epoll_items * sizeof(struct epoll_item_private));
199
200 if (epoll_set < 0 || epoll_items == 0 || write_thread_data.fds == 0 ||
201 read_thread_data == 0 || read_threads == 0)
202 goto error;
203
204 if (sysconf(_SC_NPROCESSORS_ONLN) < 2) {
205 printf("Error: please run this test on a multi-core system.\n");
206 goto error;
207 }
208
209 /* Create the socket pairs and epoll items: */
210 for (index = 0; index < n_epoll_items; ++index) {
211 int socket_pair[2];
212 struct epoll_event event_data;
213 if (socketpair(AF_UNIX,
214 SOCK_STREAM | SOCK_NONBLOCK,
215 0,
216 socket_pair) < 0)
217 goto error;
218 write_thread_data.fds[index] = socket_pair[0];
219 epoll_items[index].index = index;
220 epoll_items[index].fd = socket_pair[1];
221 if (pthread_mutex_init(&epoll_items[index].mutex, NULL) != 0)
222 goto error;
223 /* We always use EPOLLONESHOT because this test is currently
224 structured to demonstrate the need for EPOLL_CTL_DISABLE,
225 which only produces useful information in the EPOLLONESHOT
226 case (without EPOLLONESHOT, calling epoll_ctl with
227 EPOLL_CTL_DISABLE will never return EBUSY). If support for
228 testing events without EPOLLONESHOT is desired, it should
229 probably be implemented in a separate unit test. */
230 epoll_items[index].events = EPOLLIN | EPOLLONESHOT;
231 if (index < n_epoll_items / 2)
232 epoll_items[index].events |= EPOLLET;
233 epoll_items[index].stop = 0;
234 epoll_items[index].status = 0;
235 epoll_items[index].deleted = 0;
236 event_data.events = epoll_items[index].events;
237 event_data.data.ptr = &epoll_items[index];
238 if (epoll_ctl(epoll_set,
239 EPOLL_CTL_ADD,
240 epoll_items[index].fd,
241 &event_data) < 0)
242 goto error;
243 }
244
245 /* Create and start the read threads: */
246 for (index = 0; index < n_read_threads; ++index) {
247 read_thread_data[index].stop = 0;
248 read_thread_data[index].status = 0;
249 read_thread_data[index].epoll_set = epoll_set;
250 if (pthread_create(&read_threads[index],
251 NULL,
252 read_thread_function,
253 &read_thread_data[index]) != 0)
254 goto error;
255 }
256
257 if (pthread_create(&write_thread,
258 NULL,
259 write_thread_function,
260 &write_thread_data) != 0)
261 goto error;
262
263 /* Cancel all event pollers: */
264#ifdef EPOLL_CTL_DISABLE
265 for (index = 0; index < n_epoll_items; ++index) {
266 pthread_mutex_lock(&epoll_items[index].mutex);
267 ++epoll_items[index].stop;
268 if (epoll_ctl(epoll_set,
269 EPOLL_CTL_DISABLE,
270 epoll_items[index].fd,
271 NULL) == 0)
272 delete_item(index);
273 else if (errno != EBUSY) {
274 pthread_mutex_unlock(&epoll_items[index].mutex);
275 goto error;
276 }
277 /* EBUSY means events were being handled; allow the other thread
278 to delete the item. */
279 pthread_mutex_unlock(&epoll_items[index].mutex);
280 }
281#else
282 for (index = 0; index < n_epoll_items; ++index) {
283 pthread_mutex_lock(&epoll_items[index].mutex);
284 ++epoll_items[index].stop;
285 pthread_mutex_unlock(&epoll_items[index].mutex);
286 /* Wait in case a thread running read_thread_function is
287 currently executing code between epoll_wait and
288 pthread_mutex_lock with this item. Note that a longer delay
289 would make double-deletion less likely (at the expense of
290 performance), but there is no guarantee that any delay would
291 ever be sufficient. Note also that we delete all event
292 pollers at once for testing purposes, but in a real-world
293 environment we are likely to want to be able to cancel event
294 pollers at arbitrary times. Therefore we can't improve this
295 situation by just splitting this loop into two loops
296 (i.e. signal 'stop' for all items, sleep, and then delete all
297 items). We also can't fix the problem via EPOLL_CTL_DEL
298 because that command can't prevent the case where some other
299 thread is executing read_thread_function within the region
300 mentioned above: */
301 usleep(1);
302 pthread_mutex_lock(&epoll_items[index].mutex);
303 if (!epoll_items[index].deleted)
304 delete_item(index);
305 pthread_mutex_unlock(&epoll_items[index].mutex);
306 }
307#endif
308
309 /* Shut down the read threads: */
310 for (index = 0; index < n_read_threads; ++index)
311 __sync_fetch_and_add(&read_thread_data[index].stop, 1);
312 for (index = 0; index < n_read_threads; ++index) {
313 if (pthread_join(read_threads[index], NULL) != 0)
314 goto error;
315 if (read_thread_data[index].status)
316 goto error;
317 }
318
319 /* Shut down the write thread: */
320 __sync_fetch_and_add(&write_thread_data.stop, 1);
321 if ((pthread_join(write_thread, NULL) != 0) || write_thread_data.status)
322 goto error;
323
324 /* Check for final error conditions: */
325 for (index = 0; index < n_epoll_items; ++index) {
326 if (epoll_items[index].status != 0)
327 goto error;
328 if (pthread_mutex_destroy(&epoll_items[index].mutex) < 0)
329 goto error;
330 }
331 for (index = 0; index < n_epoll_items; ++index)
332 if (epoll_items[index].deleted != 1) {
333 printf("Error: item data deleted %1d times.\n",
334 epoll_items[index].deleted);
335 goto error;
336 }
337
338 printf("[PASS]\n");
339 return 0;
340
341 error:
342 printf("[FAIL]\n");
343 return errno;
344}
diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c
index cd1b03e80899..b76edf2f8333 100644
--- a/tools/vm/page-types.c
+++ b/tools/vm/page-types.c
@@ -35,7 +35,7 @@
35#include <sys/mount.h> 35#include <sys/mount.h>
36#include <sys/statfs.h> 36#include <sys/statfs.h>
37#include "../../include/uapi/linux/magic.h" 37#include "../../include/uapi/linux/magic.h"
38#include "../../include/linux/kernel-page-flags.h" 38#include "../../include/uapi/linux/kernel-page-flags.h"
39 39
40 40
41#ifndef MAX_PATH 41#ifndef MAX_PATH