aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-07-06 04:17:40 -0400
committerIngo Molnar <mingo@kernel.org>2012-07-06 04:22:46 -0400
commit387ef4e24af4ae43a7961ba6eec749488da99535 (patch)
treebdd6995a544bce7401562afbd70ffd27e2b5a083 /tools
parent6a67943a18c264d5f3df436da38edb3e59adc905 (diff)
parent81e9b994bb20716d1f6c47e048e4ae4a43de2f83 (diff)
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
perf/core improvements and fixes: - Preparatory patches to use hw events in PMU syntax, from Jiri Olsa - Remaining backport of trace-cmd's libparseevent, from Namhyung Kim - Fix libtraceevent 'clean' make target, from Namhyung Kim - Teach ctags about libtraceevent error codes, from Namhyung Kim - Fix libtraceevent dependency files usage, from Namhyung Kim - Support hex number pretty printing in libtraceevent, fixing kvm output, from Namhyung Kim - Kill some die() usage in libtraceevent, from Namhyung Kim - Improve support for hw breakpoints parsing/pretty printing/testing, from Jiri Olsa - Clarify perf bench option naming, from Hitoshi Mitake - Look for ".note" ELF notes too, used in the kernel vdso, from Jiri Olsa - Fix internal PMU list usage, removing leak, from Robert Richter Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/lib/traceevent/Makefile14
-rw-r--r--tools/lib/traceevent/event-parse.c399
-rw-r--r--tools/lib/traceevent/event-parse.h7
-rw-r--r--tools/lib/traceevent/parse-filter.c86
-rw-r--r--tools/perf/Documentation/perf-bench.txt4
-rw-r--r--tools/perf/bench/mem-memcpy.c80
-rw-r--r--tools/perf/bench/mem-memset.c80
-rw-r--r--tools/perf/util/evsel.c30
-rw-r--r--tools/perf/util/include/linux/kernel.h10
-rw-r--r--tools/perf/util/parse-events-test.c76
-rw-r--r--tools/perf/util/parse-events.c194
-rw-r--r--tools/perf/util/parse-events.l5
-rw-r--r--tools/perf/util/parse-events.y15
-rw-r--r--tools/perf/util/pmu.c3
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c4
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c4
-rw-r--r--tools/perf/util/symbol.c29
17 files changed, 726 insertions, 314 deletions
diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 3d69aa9ff51e..46c2f6b7b123 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -250,8 +250,12 @@ endef
250all_objs := $(sort $(ALL_OBJS)) 250all_objs := $(sort $(ALL_OBJS))
251all_deps := $(all_objs:%.o=.%.d) 251all_deps := $(all_objs:%.o=.%.d)
252 252
253# let .d file also depends on the source and header files
253define check_deps 254define check_deps
254 $(CC) -M $(CFLAGS) $< > $@; 255 @set -e; $(RM) $@; \
256 $(CC) -M $(CFLAGS) $< > $@.$$$$; \
257 sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
258 $(RM) $@.$$$$
255endef 259endef
256 260
257$(gui_deps): ks_version.h 261$(gui_deps): ks_version.h
@@ -270,11 +274,13 @@ endif
270 274
271tags: force 275tags: force
272 $(RM) tags 276 $(RM) tags
273 find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px 277 find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
278 --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'
274 279
275TAGS: force 280TAGS: force
276 $(RM) TAGS 281 $(RM) TAGS
277 find . -name '*.[ch]' | xargs etags 282 find . -name '*.[ch]' | xargs etags \
283 --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/'
278 284
279define do_install 285define do_install
280 $(print_install) \ 286 $(print_install) \
@@ -290,7 +296,7 @@ install_lib: all_cmd install_plugins install_python
290install: install_lib 296install: install_lib
291 297
292clean: 298clean:
293 $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES).*.d 299 $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d
294 $(RM) tags TAGS 300 $(RM) tags TAGS
295 301
296endif # skip-makefile 302endif # skip-makefile
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 554828219c33..5f34aa371b56 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -467,8 +467,10 @@ int pevent_register_function(struct pevent *pevent, char *func,
467 item->mod = NULL; 467 item->mod = NULL;
468 item->addr = addr; 468 item->addr = addr;
469 469
470 pevent->funclist = item; 470 if (!item->func || (mod && !item->mod))
471 die("malloc func");
471 472
473 pevent->funclist = item;
472 pevent->func_count++; 474 pevent->func_count++;
473 475
474 return 0; 476 return 0;
@@ -511,12 +513,12 @@ struct printk_list {
511 513
512static int printk_cmp(const void *a, const void *b) 514static int printk_cmp(const void *a, const void *b)
513{ 515{
514 const struct func_map *fa = a; 516 const struct printk_map *pa = a;
515 const struct func_map *fb = b; 517 const struct printk_map *pb = b;
516 518
517 if (fa->addr < fb->addr) 519 if (pa->addr < pb->addr)
518 return -1; 520 return -1;
519 if (fa->addr > fb->addr) 521 if (pa->addr > pb->addr)
520 return 1; 522 return 1;
521 523
522 return 0; 524 return 0;
@@ -583,10 +585,13 @@ int pevent_register_print_string(struct pevent *pevent, char *fmt,
583 item = malloc_or_die(sizeof(*item)); 585 item = malloc_or_die(sizeof(*item));
584 586
585 item->next = pevent->printklist; 587 item->next = pevent->printklist;
586 pevent->printklist = item;
587 item->printk = strdup(fmt); 588 item->printk = strdup(fmt);
588 item->addr = addr; 589 item->addr = addr;
589 590
591 if (!item->printk)
592 die("malloc fmt");
593
594 pevent->printklist = item;
590 pevent->printk_count++; 595 pevent->printk_count++;
591 596
592 return 0; 597 return 0;
@@ -616,7 +621,9 @@ static struct event_format *alloc_event(void)
616{ 621{
617 struct event_format *event; 622 struct event_format *event;
618 623
619 event = malloc_or_die(sizeof(*event)); 624 event = malloc(sizeof(*event));
625 if (!event)
626 return NULL;
620 memset(event, 0, sizeof(*event)); 627 memset(event, 0, sizeof(*event));
621 628
622 return event; 629 return event;
@@ -626,12 +633,8 @@ static void add_event(struct pevent *pevent, struct event_format *event)
626{ 633{
627 int i; 634 int i;
628 635
629 if (!pevent->events) 636 pevent->events = realloc(pevent->events, sizeof(event) *
630 pevent->events = malloc_or_die(sizeof(event)); 637 (pevent->nr_events + 1));
631 else
632 pevent->events =
633 realloc(pevent->events, sizeof(event) *
634 (pevent->nr_events + 1));
635 if (!pevent->events) 638 if (!pevent->events)
636 die("Can not allocate events"); 639 die("Can not allocate events");
637 640
@@ -697,6 +700,10 @@ static void free_arg(struct print_arg *arg)
697 free_arg(arg->symbol.field); 700 free_arg(arg->symbol.field);
698 free_flag_sym(arg->symbol.symbols); 701 free_flag_sym(arg->symbol.symbols);
699 break; 702 break;
703 case PRINT_HEX:
704 free_arg(arg->hex.field);
705 free_arg(arg->hex.size);
706 break;
700 case PRINT_TYPE: 707 case PRINT_TYPE:
701 free(arg->typecast.type); 708 free(arg->typecast.type);
702 free_arg(arg->typecast.item); 709 free_arg(arg->typecast.item);
@@ -775,6 +782,25 @@ int pevent_peek_char(void)
775 return __peek_char(); 782 return __peek_char();
776} 783}
777 784
785static int extend_token(char **tok, char *buf, int size)
786{
787 char *newtok = realloc(*tok, size);
788
789 if (!newtok) {
790 free(*tok);
791 *tok = NULL;
792 return -1;
793 }
794
795 if (!*tok)
796 strcpy(newtok, buf);
797 else
798 strcat(newtok, buf);
799 *tok = newtok;
800
801 return 0;
802}
803
778static enum event_type force_token(const char *str, char **tok); 804static enum event_type force_token(const char *str, char **tok);
779 805
780static enum event_type __read_token(char **tok) 806static enum event_type __read_token(char **tok)
@@ -859,17 +885,10 @@ static enum event_type __read_token(char **tok)
859 do { 885 do {
860 if (i == (BUFSIZ - 1)) { 886 if (i == (BUFSIZ - 1)) {
861 buf[i] = 0; 887 buf[i] = 0;
862 if (*tok) { 888 tok_size += BUFSIZ;
863 *tok = realloc(*tok, tok_size + BUFSIZ);
864 if (!*tok)
865 return EVENT_NONE;
866 strcat(*tok, buf);
867 } else
868 *tok = strdup(buf);
869 889
870 if (!*tok) 890 if (extend_token(tok, buf, tok_size) < 0)
871 return EVENT_NONE; 891 return EVENT_NONE;
872 tok_size += BUFSIZ;
873 i = 0; 892 i = 0;
874 } 893 }
875 last_ch = ch; 894 last_ch = ch;
@@ -908,17 +927,10 @@ static enum event_type __read_token(char **tok)
908 while (get_type(__peek_char()) == type) { 927 while (get_type(__peek_char()) == type) {
909 if (i == (BUFSIZ - 1)) { 928 if (i == (BUFSIZ - 1)) {
910 buf[i] = 0; 929 buf[i] = 0;
911 if (*tok) { 930 tok_size += BUFSIZ;
912 *tok = realloc(*tok, tok_size + BUFSIZ);
913 if (!*tok)
914 return EVENT_NONE;
915 strcat(*tok, buf);
916 } else
917 *tok = strdup(buf);
918 931
919 if (!*tok) 932 if (extend_token(tok, buf, tok_size) < 0)
920 return EVENT_NONE; 933 return EVENT_NONE;
921 tok_size += BUFSIZ;
922 i = 0; 934 i = 0;
923 } 935 }
924 ch = __read_char(); 936 ch = __read_char();
@@ -927,14 +939,7 @@ static enum event_type __read_token(char **tok)
927 939
928 out: 940 out:
929 buf[i] = 0; 941 buf[i] = 0;
930 if (*tok) { 942 if (extend_token(tok, buf, tok_size + i + 1) < 0)
931 *tok = realloc(*tok, tok_size + i);
932 if (!*tok)
933 return EVENT_NONE;
934 strcat(*tok, buf);
935 } else
936 *tok = strdup(buf);
937 if (!*tok)
938 return EVENT_NONE; 943 return EVENT_NONE;
939 944
940 if (type == EVENT_ITEM) { 945 if (type == EVENT_ITEM) {
@@ -1255,9 +1260,15 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1255 field->flags |= FIELD_IS_POINTER; 1260 field->flags |= FIELD_IS_POINTER;
1256 1261
1257 if (field->type) { 1262 if (field->type) {
1258 field->type = realloc(field->type, 1263 char *new_type;
1259 strlen(field->type) + 1264 new_type = realloc(field->type,
1260 strlen(last_token) + 2); 1265 strlen(field->type) +
1266 strlen(last_token) + 2);
1267 if (!new_type) {
1268 free(last_token);
1269 goto fail;
1270 }
1271 field->type = new_type;
1261 strcat(field->type, " "); 1272 strcat(field->type, " ");
1262 strcat(field->type, last_token); 1273 strcat(field->type, last_token);
1263 free(last_token); 1274 free(last_token);
@@ -1282,6 +1293,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1282 if (strcmp(token, "[") == 0) { 1293 if (strcmp(token, "[") == 0) {
1283 enum event_type last_type = type; 1294 enum event_type last_type = type;
1284 char *brackets = token; 1295 char *brackets = token;
1296 char *new_brackets;
1285 int len; 1297 int len;
1286 1298
1287 field->flags |= FIELD_IS_ARRAY; 1299 field->flags |= FIELD_IS_ARRAY;
@@ -1301,9 +1313,14 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1301 len = 1; 1313 len = 1;
1302 last_type = type; 1314 last_type = type;
1303 1315
1304 brackets = realloc(brackets, 1316 new_brackets = realloc(brackets,
1305 strlen(brackets) + 1317 strlen(brackets) +
1306 strlen(token) + len); 1318 strlen(token) + len);
1319 if (!new_brackets) {
1320 free(brackets);
1321 goto fail;
1322 }
1323 brackets = new_brackets;
1307 if (len == 2) 1324 if (len == 2)
1308 strcat(brackets, " "); 1325 strcat(brackets, " ");
1309 strcat(brackets, token); 1326 strcat(brackets, token);
@@ -1319,7 +1336,12 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1319 1336
1320 free_token(token); 1337 free_token(token);
1321 1338
1322 brackets = realloc(brackets, strlen(brackets) + 2); 1339 new_brackets = realloc(brackets, strlen(brackets) + 2);
1340 if (!new_brackets) {
1341 free(brackets);
1342 goto fail;
1343 }
1344 brackets = new_brackets;
1323 strcat(brackets, "]"); 1345 strcat(brackets, "]");
1324 1346
1325 /* add brackets to type */ 1347 /* add brackets to type */
@@ -1330,10 +1352,16 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1330 * the format: type [] item; 1352 * the format: type [] item;
1331 */ 1353 */
1332 if (type == EVENT_ITEM) { 1354 if (type == EVENT_ITEM) {
1333 field->type = realloc(field->type, 1355 char *new_type;
1334 strlen(field->type) + 1356 new_type = realloc(field->type,
1335 strlen(field->name) + 1357 strlen(field->type) +
1336 strlen(brackets) + 2); 1358 strlen(field->name) +
1359 strlen(brackets) + 2);
1360 if (!new_type) {
1361 free(brackets);
1362 goto fail;
1363 }
1364 field->type = new_type;
1337 strcat(field->type, " "); 1365 strcat(field->type, " ");
1338 strcat(field->type, field->name); 1366 strcat(field->type, field->name);
1339 free_token(field->name); 1367 free_token(field->name);
@@ -1341,9 +1369,15 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1341 field->name = token; 1369 field->name = token;
1342 type = read_token(&token); 1370 type = read_token(&token);
1343 } else { 1371 } else {
1344 field->type = realloc(field->type, 1372 char *new_type;
1345 strlen(field->type) + 1373 new_type = realloc(field->type,
1346 strlen(brackets) + 1); 1374 strlen(field->type) +
1375 strlen(brackets) + 1);
1376 if (!new_type) {
1377 free(brackets);
1378 goto fail;
1379 }
1380 field->type = new_type;
1347 strcat(field->type, brackets); 1381 strcat(field->type, brackets);
1348 } 1382 }
1349 free(brackets); 1383 free(brackets);
@@ -1726,10 +1760,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1726 /* could just be a type pointer */ 1760 /* could just be a type pointer */
1727 if ((strcmp(arg->op.op, "*") == 0) && 1761 if ((strcmp(arg->op.op, "*") == 0) &&
1728 type == EVENT_DELIM && (strcmp(token, ")") == 0)) { 1762 type == EVENT_DELIM && (strcmp(token, ")") == 0)) {
1763 char *new_atom;
1764
1729 if (left->type != PRINT_ATOM) 1765 if (left->type != PRINT_ATOM)
1730 die("bad pointer type"); 1766 die("bad pointer type");
1731 left->atom.atom = realloc(left->atom.atom, 1767 new_atom = realloc(left->atom.atom,
1732 strlen(left->atom.atom) + 3); 1768 strlen(left->atom.atom) + 3);
1769 if (!new_atom)
1770 goto out_free;
1771
1772 left->atom.atom = new_atom;
1733 strcat(left->atom.atom, " *"); 1773 strcat(left->atom.atom, " *");
1734 free(arg->op.op); 1774 free(arg->op.op);
1735 *arg = *left; 1775 *arg = *left;
@@ -2146,6 +2186,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2146 if (value == NULL) 2186 if (value == NULL)
2147 goto out_free; 2187 goto out_free;
2148 field->value = strdup(value); 2188 field->value = strdup(value);
2189 if (field->value == NULL)
2190 goto out_free;
2149 2191
2150 free_arg(arg); 2192 free_arg(arg);
2151 arg = alloc_arg(); 2193 arg = alloc_arg();
@@ -2159,6 +2201,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2159 if (value == NULL) 2201 if (value == NULL)
2160 goto out_free; 2202 goto out_free;
2161 field->str = strdup(value); 2203 field->str = strdup(value);
2204 if (field->str == NULL)
2205 goto out_free;
2162 free_arg(arg); 2206 free_arg(arg);
2163 arg = NULL; 2207 arg = NULL;
2164 2208
@@ -2260,6 +2304,45 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok)
2260} 2304}
2261 2305
2262static enum event_type 2306static enum event_type
2307process_hex(struct event_format *event, struct print_arg *arg, char **tok)
2308{
2309 struct print_arg *field;
2310 enum event_type type;
2311 char *token;
2312
2313 memset(arg, 0, sizeof(*arg));
2314 arg->type = PRINT_HEX;
2315
2316 field = alloc_arg();
2317 type = process_arg(event, field, &token);
2318
2319 if (test_type_token(type, token, EVENT_DELIM, ","))
2320 goto out_free;
2321
2322 arg->hex.field = field;
2323
2324 free_token(token);
2325
2326 field = alloc_arg();
2327 type = process_arg(event, field, &token);
2328
2329 if (test_type_token(type, token, EVENT_DELIM, ")"))
2330 goto out_free;
2331
2332 arg->hex.size = field;
2333
2334 free_token(token);
2335 type = read_token_item(tok);
2336 return type;
2337
2338 out_free:
2339 free_arg(field);
2340 free_token(token);
2341 *tok = NULL;
2342 return EVENT_ERROR;
2343}
2344
2345static enum event_type
2263process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) 2346process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok)
2264{ 2347{
2265 struct format_field *field; 2348 struct format_field *field;
@@ -2488,6 +2571,10 @@ process_function(struct event_format *event, struct print_arg *arg,
2488 is_symbolic_field = 1; 2571 is_symbolic_field = 1;
2489 return process_symbols(event, arg, tok); 2572 return process_symbols(event, arg, tok);
2490 } 2573 }
2574 if (strcmp(token, "__print_hex") == 0) {
2575 free_token(token);
2576 return process_hex(event, arg, tok);
2577 }
2491 if (strcmp(token, "__get_str") == 0) { 2578 if (strcmp(token, "__get_str") == 0) {
2492 free_token(token); 2579 free_token(token);
2493 return process_str(event, arg, tok); 2580 return process_str(event, arg, tok);
@@ -2541,7 +2628,16 @@ process_arg_token(struct event_format *event, struct print_arg *arg,
2541 } 2628 }
2542 /* atoms can be more than one token long */ 2629 /* atoms can be more than one token long */
2543 while (type == EVENT_ITEM) { 2630 while (type == EVENT_ITEM) {
2544 atom = realloc(atom, strlen(atom) + strlen(token) + 2); 2631 char *new_atom;
2632 new_atom = realloc(atom,
2633 strlen(atom) + strlen(token) + 2);
2634 if (!new_atom) {
2635 free(atom);
2636 *tok = NULL;
2637 free_token(token);
2638 return EVENT_ERROR;
2639 }
2640 atom = new_atom;
2545 strcat(atom, " "); 2641 strcat(atom, " ");
2546 strcat(atom, token); 2642 strcat(atom, token);
2547 free_token(token); 2643 free_token(token);
@@ -2835,7 +2931,7 @@ static int get_common_info(struct pevent *pevent,
2835 event = pevent->events[0]; 2931 event = pevent->events[0];
2836 field = pevent_find_common_field(event, type); 2932 field = pevent_find_common_field(event, type);
2837 if (!field) 2933 if (!field)
2838 die("field '%s' not found", type); 2934 return -1;
2839 2935
2840 *offset = field->offset; 2936 *offset = field->offset;
2841 *size = field->size; 2937 *size = field->size;
@@ -2886,15 +2982,16 @@ static int parse_common_flags(struct pevent *pevent, void *data)
2886 2982
2887static int parse_common_lock_depth(struct pevent *pevent, void *data) 2983static int parse_common_lock_depth(struct pevent *pevent, void *data)
2888{ 2984{
2889 int ret; 2985 return __parse_common(pevent, data,
2890 2986 &pevent->ld_size, &pevent->ld_offset,
2891 ret = __parse_common(pevent, data, 2987 "common_lock_depth");
2892 &pevent->ld_size, &pevent->ld_offset, 2988}
2893 "common_lock_depth");
2894 if (ret < 0)
2895 return -1;
2896 2989
2897 return ret; 2990static int parse_common_migrate_disable(struct pevent *pevent, void *data)
2991{
2992 return __parse_common(pevent, data,
2993 &pevent->ld_size, &pevent->ld_offset,
2994 "common_migrate_disable");
2898} 2995}
2899 2996
2900static int events_id_cmp(const void *a, const void *b); 2997static int events_id_cmp(const void *a, const void *b);
@@ -2995,6 +3092,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
2995 break; 3092 break;
2996 case PRINT_FLAGS: 3093 case PRINT_FLAGS:
2997 case PRINT_SYMBOL: 3094 case PRINT_SYMBOL:
3095 case PRINT_HEX:
2998 break; 3096 break;
2999 case PRINT_TYPE: 3097 case PRINT_TYPE:
3000 val = eval_num_arg(data, size, event, arg->typecast.item); 3098 val = eval_num_arg(data, size, event, arg->typecast.item);
@@ -3214,11 +3312,13 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3214{ 3312{
3215 struct pevent *pevent = event->pevent; 3313 struct pevent *pevent = event->pevent;
3216 struct print_flag_sym *flag; 3314 struct print_flag_sym *flag;
3315 struct format_field *field;
3217 unsigned long long val, fval; 3316 unsigned long long val, fval;
3218 unsigned long addr; 3317 unsigned long addr;
3219 char *str; 3318 char *str;
3319 unsigned char *hex;
3220 int print; 3320 int print;
3221 int len; 3321 int i, len;
3222 3322
3223 switch (arg->type) { 3323 switch (arg->type) {
3224 case PRINT_NULL: 3324 case PRINT_NULL:
@@ -3228,27 +3328,29 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3228 print_str_to_seq(s, format, len_arg, arg->atom.atom); 3328 print_str_to_seq(s, format, len_arg, arg->atom.atom);
3229 return; 3329 return;
3230 case PRINT_FIELD: 3330 case PRINT_FIELD:
3231 if (!arg->field.field) { 3331 field = arg->field.field;
3232 arg->field.field = pevent_find_any_field(event, arg->field.name); 3332 if (!field) {
3233 if (!arg->field.field) 3333 field = pevent_find_any_field(event, arg->field.name);
3334 if (!field)
3234 die("field %s not found", arg->field.name); 3335 die("field %s not found", arg->field.name);
3336 arg->field.field = field;
3235 } 3337 }
3236 /* Zero sized fields, mean the rest of the data */ 3338 /* Zero sized fields, mean the rest of the data */
3237 len = arg->field.field->size ? : size - arg->field.field->offset; 3339 len = field->size ? : size - field->offset;
3238 3340
3239 /* 3341 /*
3240 * Some events pass in pointers. If this is not an array 3342 * Some events pass in pointers. If this is not an array
3241 * and the size is the same as long_size, assume that it 3343 * and the size is the same as long_size, assume that it
3242 * is a pointer. 3344 * is a pointer.
3243 */ 3345 */
3244 if (!(arg->field.field->flags & FIELD_IS_ARRAY) && 3346 if (!(field->flags & FIELD_IS_ARRAY) &&
3245 arg->field.field->size == pevent->long_size) { 3347 field->size == pevent->long_size) {
3246 addr = *(unsigned long *)(data + arg->field.field->offset); 3348 addr = *(unsigned long *)(data + field->offset);
3247 trace_seq_printf(s, "%lx", addr); 3349 trace_seq_printf(s, "%lx", addr);
3248 break; 3350 break;
3249 } 3351 }
3250 str = malloc_or_die(len + 1); 3352 str = malloc_or_die(len + 1);
3251 memcpy(str, data + arg->field.field->offset, len); 3353 memcpy(str, data + field->offset, len);
3252 str[len] = 0; 3354 str[len] = 0;
3253 print_str_to_seq(s, format, len_arg, str); 3355 print_str_to_seq(s, format, len_arg, str);
3254 free(str); 3356 free(str);
@@ -3281,6 +3383,23 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3281 } 3383 }
3282 } 3384 }
3283 break; 3385 break;
3386 case PRINT_HEX:
3387 field = arg->hex.field->field.field;
3388 if (!field) {
3389 str = arg->hex.field->field.name;
3390 field = pevent_find_any_field(event, str);
3391 if (!field)
3392 die("field %s not found", str);
3393 arg->hex.field->field.field = field;
3394 }
3395 hex = data + field->offset;
3396 len = eval_num_arg(data, size, event, arg->hex.size);
3397 for (i = 0; i < len; i++) {
3398 if (i)
3399 trace_seq_putc(s, ' ');
3400 trace_seq_printf(s, "%02x", hex[i]);
3401 }
3402 break;
3284 3403
3285 case PRINT_TYPE: 3404 case PRINT_TYPE:
3286 break; 3405 break;
@@ -3299,7 +3418,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3299 break; 3418 break;
3300 } 3419 }
3301 case PRINT_BSTRING: 3420 case PRINT_BSTRING:
3302 trace_seq_printf(s, format, arg->string.string); 3421 print_str_to_seq(s, format, len_arg, arg->string.string);
3303 break; 3422 break;
3304 case PRINT_OP: 3423 case PRINT_OP:
3305 /* 3424 /*
@@ -3363,6 +3482,10 @@ process_defined_func(struct trace_seq *s, void *data, int size,
3363 string = malloc_or_die(sizeof(*string)); 3482 string = malloc_or_die(sizeof(*string));
3364 string->next = strings; 3483 string->next = strings;
3365 string->str = strdup(str.buffer); 3484 string->str = strdup(str.buffer);
3485 if (!string->str)
3486 die("malloc str");
3487
3488 args[i] = (unsigned long long)string->str;
3366 strings = string; 3489 strings = string;
3367 trace_seq_destroy(&str); 3490 trace_seq_destroy(&str);
3368 break; 3491 break;
@@ -3400,6 +3523,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3400 unsigned long long ip, val; 3523 unsigned long long ip, val;
3401 char *ptr; 3524 char *ptr;
3402 void *bptr; 3525 void *bptr;
3526 int vsize;
3403 3527
3404 field = pevent->bprint_buf_field; 3528 field = pevent->bprint_buf_field;
3405 ip_field = pevent->bprint_ip_field; 3529 ip_field = pevent->bprint_ip_field;
@@ -3448,6 +3572,8 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3448 goto process_again; 3572 goto process_again;
3449 case '0' ... '9': 3573 case '0' ... '9':
3450 goto process_again; 3574 goto process_again;
3575 case '.':
3576 goto process_again;
3451 case 'p': 3577 case 'p':
3452 ls = 1; 3578 ls = 1;
3453 /* fall through */ 3579 /* fall through */
@@ -3455,23 +3581,30 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3455 case 'u': 3581 case 'u':
3456 case 'x': 3582 case 'x':
3457 case 'i': 3583 case 'i':
3458 /* the pointers are always 4 bytes aligned */
3459 bptr = (void *)(((unsigned long)bptr + 3) &
3460 ~3);
3461 switch (ls) { 3584 switch (ls) {
3462 case 0: 3585 case 0:
3463 ls = 4; 3586 vsize = 4;
3464 break; 3587 break;
3465 case 1: 3588 case 1:
3466 ls = pevent->long_size; 3589 vsize = pevent->long_size;
3467 break; 3590 break;
3468 case 2: 3591 case 2:
3469 ls = 8; 3592 vsize = 8;
3593 break;
3470 default: 3594 default:
3595 vsize = ls; /* ? */
3471 break; 3596 break;
3472 } 3597 }
3473 val = pevent_read_number(pevent, bptr, ls); 3598 /* fall through */
3474 bptr += ls; 3599 case '*':
3600 if (*ptr == '*')
3601 vsize = 4;
3602
3603 /* the pointers are always 4 bytes aligned */
3604 bptr = (void *)(((unsigned long)bptr + 3) &
3605 ~3);
3606 val = pevent_read_number(pevent, bptr, vsize);
3607 bptr += vsize;
3475 arg = alloc_arg(); 3608 arg = alloc_arg();
3476 arg->next = NULL; 3609 arg->next = NULL;
3477 arg->type = PRINT_ATOM; 3610 arg->type = PRINT_ATOM;
@@ -3479,12 +3612,21 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3479 sprintf(arg->atom.atom, "%lld", val); 3612 sprintf(arg->atom.atom, "%lld", val);
3480 *next = arg; 3613 *next = arg;
3481 next = &arg->next; 3614 next = &arg->next;
3615 /*
3616 * The '*' case means that an arg is used as the length.
3617 * We need to continue to figure out for what.
3618 */
3619 if (*ptr == '*')
3620 goto process_again;
3621
3482 break; 3622 break;
3483 case 's': 3623 case 's':
3484 arg = alloc_arg(); 3624 arg = alloc_arg();
3485 arg->next = NULL; 3625 arg->next = NULL;
3486 arg->type = PRINT_BSTRING; 3626 arg->type = PRINT_BSTRING;
3487 arg->string.string = strdup(bptr); 3627 arg->string.string = strdup(bptr);
3628 if (!arg->string.string)
3629 break;
3488 bptr += strlen(bptr) + 1; 3630 bptr += strlen(bptr) + 1;
3489 *next = arg; 3631 *next = arg;
3490 next = &arg->next; 3632 next = &arg->next;
@@ -3589,6 +3731,16 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
3589 trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); 3731 trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
3590} 3732}
3591 3733
3734static int is_printable_array(char *p, unsigned int len)
3735{
3736 unsigned int i;
3737
3738 for (i = 0; i < len && p[i]; i++)
3739 if (!isprint(p[i]))
3740 return 0;
3741 return 1;
3742}
3743
3592static void print_event_fields(struct trace_seq *s, void *data, int size, 3744static void print_event_fields(struct trace_seq *s, void *data, int size,
3593 struct event_format *event) 3745 struct event_format *event)
3594{ 3746{
@@ -3608,7 +3760,8 @@ static void print_event_fields(struct trace_seq *s, void *data, int size,
3608 len = offset >> 16; 3760 len = offset >> 16;
3609 offset &= 0xffff; 3761 offset &= 0xffff;
3610 } 3762 }
3611 if (field->flags & FIELD_IS_STRING) { 3763 if (field->flags & FIELD_IS_STRING &&
3764 is_printable_array(data + offset, len)) {
3612 trace_seq_printf(s, "%s", (char *)data + offset); 3765 trace_seq_printf(s, "%s", (char *)data + offset);
3613 } else { 3766 } else {
3614 trace_seq_puts(s, "ARRAY["); 3767 trace_seq_puts(s, "ARRAY[");
@@ -3619,6 +3772,7 @@ static void print_event_fields(struct trace_seq *s, void *data, int size,
3619 *((unsigned char *)data + offset + i)); 3772 *((unsigned char *)data + offset + i));
3620 } 3773 }
3621 trace_seq_putc(s, ']'); 3774 trace_seq_putc(s, ']');
3775 field->flags &= ~FIELD_IS_STRING;
3622 } 3776 }
3623 } else { 3777 } else {
3624 val = pevent_read_number(event->pevent, data + field->offset, 3778 val = pevent_read_number(event->pevent, data + field->offset,
@@ -3758,6 +3912,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3758 } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') { 3912 } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') {
3759 print_mac_arg(s, *(ptr+1), data, size, event, arg); 3913 print_mac_arg(s, *(ptr+1), data, size, event, arg);
3760 ptr++; 3914 ptr++;
3915 arg = arg->next;
3761 break; 3916 break;
3762 } 3917 }
3763 3918
@@ -3794,14 +3949,15 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3794 break; 3949 break;
3795 } 3950 }
3796 } 3951 }
3797 if (pevent->long_size == 8 && ls) { 3952 if (pevent->long_size == 8 && ls &&
3953 sizeof(long) != 8) {
3798 char *p; 3954 char *p;
3799 3955
3800 ls = 2; 3956 ls = 2;
3801 /* make %l into %ll */ 3957 /* make %l into %ll */
3802 p = strchr(format, 'l'); 3958 p = strchr(format, 'l');
3803 if (p) 3959 if (p)
3804 memmove(p, p+1, strlen(p)+1); 3960 memmove(p+1, p, strlen(p)+1);
3805 else if (strcmp(format, "%p") == 0) 3961 else if (strcmp(format, "%p") == 0)
3806 strcpy(format, "0x%llx"); 3962 strcpy(format, "0x%llx");
3807 } 3963 }
@@ -3878,8 +4034,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3878 * pevent_data_lat_fmt - parse the data for the latency format 4034 * pevent_data_lat_fmt - parse the data for the latency format
3879 * @pevent: a handle to the pevent 4035 * @pevent: a handle to the pevent
3880 * @s: the trace_seq to write to 4036 * @s: the trace_seq to write to
3881 * @data: the raw data to read from 4037 * @record: the record to read from
3882 * @size: currently unused.
3883 * 4038 *
3884 * This parses out the Latency format (interrupts disabled, 4039 * This parses out the Latency format (interrupts disabled,
3885 * need rescheduling, in hard/soft interrupt, preempt count 4040 * need rescheduling, in hard/soft interrupt, preempt count
@@ -3889,10 +4044,13 @@ void pevent_data_lat_fmt(struct pevent *pevent,
3889 struct trace_seq *s, struct pevent_record *record) 4044 struct trace_seq *s, struct pevent_record *record)
3890{ 4045{
3891 static int check_lock_depth = 1; 4046 static int check_lock_depth = 1;
4047 static int check_migrate_disable = 1;
3892 static int lock_depth_exists; 4048 static int lock_depth_exists;
4049 static int migrate_disable_exists;
3893 unsigned int lat_flags; 4050 unsigned int lat_flags;
3894 unsigned int pc; 4051 unsigned int pc;
3895 int lock_depth; 4052 int lock_depth;
4053 int migrate_disable;
3896 int hardirq; 4054 int hardirq;
3897 int softirq; 4055 int softirq;
3898 void *data = record->data; 4056 void *data = record->data;
@@ -3900,18 +4058,26 @@ void pevent_data_lat_fmt(struct pevent *pevent,
3900 lat_flags = parse_common_flags(pevent, data); 4058 lat_flags = parse_common_flags(pevent, data);
3901 pc = parse_common_pc(pevent, data); 4059 pc = parse_common_pc(pevent, data);
3902 /* lock_depth may not always exist */ 4060 /* lock_depth may not always exist */
3903 if (check_lock_depth) {
3904 struct format_field *field;
3905 struct event_format *event;
3906
3907 check_lock_depth = 0;
3908 event = pevent->events[0];
3909 field = pevent_find_common_field(event, "common_lock_depth");
3910 if (field)
3911 lock_depth_exists = 1;
3912 }
3913 if (lock_depth_exists) 4061 if (lock_depth_exists)
3914 lock_depth = parse_common_lock_depth(pevent, data); 4062 lock_depth = parse_common_lock_depth(pevent, data);
4063 else if (check_lock_depth) {
4064 lock_depth = parse_common_lock_depth(pevent, data);
4065 if (lock_depth < 0)
4066 check_lock_depth = 0;
4067 else
4068 lock_depth_exists = 1;
4069 }
4070
4071 /* migrate_disable may not always exist */
4072 if (migrate_disable_exists)
4073 migrate_disable = parse_common_migrate_disable(pevent, data);
4074 else if (check_migrate_disable) {
4075 migrate_disable = parse_common_migrate_disable(pevent, data);
4076 if (migrate_disable < 0)
4077 check_migrate_disable = 0;
4078 else
4079 migrate_disable_exists = 1;
4080 }
3915 4081
3916 hardirq = lat_flags & TRACE_FLAG_HARDIRQ; 4082 hardirq = lat_flags & TRACE_FLAG_HARDIRQ;
3917 softirq = lat_flags & TRACE_FLAG_SOFTIRQ; 4083 softirq = lat_flags & TRACE_FLAG_SOFTIRQ;
@@ -3930,6 +4096,13 @@ void pevent_data_lat_fmt(struct pevent *pevent,
3930 else 4096 else
3931 trace_seq_putc(s, '.'); 4097 trace_seq_putc(s, '.');
3932 4098
4099 if (migrate_disable_exists) {
4100 if (migrate_disable < 0)
4101 trace_seq_putc(s, '.');
4102 else
4103 trace_seq_printf(s, "%d", migrate_disable);
4104 }
4105
3933 if (lock_depth_exists) { 4106 if (lock_depth_exists) {
3934 if (lock_depth < 0) 4107 if (lock_depth < 0)
3935 trace_seq_putc(s, '.'); 4108 trace_seq_putc(s, '.');
@@ -3996,10 +4169,7 @@ const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid)
3996 * pevent_data_comm_from_pid - parse the data into the print format 4169 * pevent_data_comm_from_pid - parse the data into the print format
3997 * @s: the trace_seq to write to 4170 * @s: the trace_seq to write to
3998 * @event: the handle to the event 4171 * @event: the handle to the event
3999 * @cpu: the cpu the event was recorded on 4172 * @record: the record to read from
4000 * @data: the raw data
4001 * @size: the size of the raw data
4002 * @nsecs: the timestamp of the event
4003 * 4173 *
4004 * This parses the raw @data using the given @event information and 4174 * This parses the raw @data using the given @event information and
4005 * writes the print format into the trace_seq. 4175 * writes the print format into the trace_seq.
@@ -4279,6 +4449,13 @@ static void print_args(struct print_arg *args)
4279 trace_seq_destroy(&s); 4449 trace_seq_destroy(&s);
4280 printf(")"); 4450 printf(")");
4281 break; 4451 break;
4452 case PRINT_HEX:
4453 printf("__print_hex(");
4454 print_args(args->hex.field);
4455 printf(", ");
4456 print_args(args->hex.size);
4457 printf(")");
4458 break;
4282 case PRINT_STRING: 4459 case PRINT_STRING:
4283 case PRINT_BSTRING: 4460 case PRINT_BSTRING:
4284 printf("__get_str(%s)", args->string.string); 4461 printf("__get_str(%s)", args->string.string);
@@ -4541,6 +4718,8 @@ int pevent_parse_event(struct pevent *pevent,
4541 die("failed to read event id"); 4718 die("failed to read event id");
4542 4719
4543 event->system = strdup(sys); 4720 event->system = strdup(sys);
4721 if (!event->system)
4722 die("failed to allocate system");
4544 4723
4545 /* Add pevent to event so that it can be referenced */ 4724 /* Add pevent to event so that it can be referenced */
4546 event->pevent = pevent; 4725 event->pevent = pevent;
@@ -4582,6 +4761,11 @@ int pevent_parse_event(struct pevent *pevent,
4582 list = &arg->next; 4761 list = &arg->next;
4583 arg->type = PRINT_FIELD; 4762 arg->type = PRINT_FIELD;
4584 arg->field.name = strdup(field->name); 4763 arg->field.name = strdup(field->name);
4764 if (!arg->field.name) {
4765 do_warning("failed to allocate field name");
4766 event->flags |= EVENT_FL_FAILED;
4767 return -1;
4768 }
4585 arg->field.field = field; 4769 arg->field.field = field;
4586 } 4770 }
4587 return 0; 4771 return 0;
@@ -4753,7 +4937,7 @@ int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event,
4753 * @record: The record with the field name. 4937 * @record: The record with the field name.
4754 * @err: print default error if failed. 4938 * @err: print default error if failed.
4755 * 4939 *
4756 * Returns: 0 on success, -1 field not fould, or 1 if buffer is full. 4940 * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
4757 */ 4941 */
4758int pevent_print_num_field(struct trace_seq *s, const char *fmt, 4942int pevent_print_num_field(struct trace_seq *s, const char *fmt,
4759 struct event_format *event, const char *name, 4943 struct event_format *event, const char *name,
@@ -4795,11 +4979,12 @@ static void free_func_handle(struct pevent_function_handler *func)
4795 * pevent_register_print_function - register a helper function 4979 * pevent_register_print_function - register a helper function
4796 * @pevent: the handle to the pevent 4980 * @pevent: the handle to the pevent
4797 * @func: the function to process the helper function 4981 * @func: the function to process the helper function
4982 * @ret_type: the return type of the helper function
4798 * @name: the name of the helper function 4983 * @name: the name of the helper function
4799 * @parameters: A list of enum pevent_func_arg_type 4984 * @parameters: A list of enum pevent_func_arg_type
4800 * 4985 *
4801 * Some events may have helper functions in the print format arguments. 4986 * Some events may have helper functions in the print format arguments.
4802 * This allows a plugin to dynmically create a way to process one 4987 * This allows a plugin to dynamically create a way to process one
4803 * of these functions. 4988 * of these functions.
4804 * 4989 *
4805 * The @parameters is a variable list of pevent_func_arg_type enums that 4990 * The @parameters is a variable list of pevent_func_arg_type enums that
@@ -4870,12 +5055,13 @@ int pevent_register_print_function(struct pevent *pevent,
4870} 5055}
4871 5056
4872/** 5057/**
4873 * pevent_register_event_handle - register a way to parse an event 5058 * pevent_register_event_handler - register a way to parse an event
4874 * @pevent: the handle to the pevent 5059 * @pevent: the handle to the pevent
4875 * @id: the id of the event to register 5060 * @id: the id of the event to register
4876 * @sys_name: the system name the event belongs to 5061 * @sys_name: the system name the event belongs to
4877 * @event_name: the name of the event 5062 * @event_name: the name of the event
4878 * @func: the function to call to parse the event information 5063 * @func: the function to call to parse the event information
5064 * @context: the data to be passed to @func
4879 * 5065 *
4880 * This function allows a developer to override the parsing of 5066 * This function allows a developer to override the parsing of
4881 * a given event. If for some reason the default print format 5067 * a given event. If for some reason the default print format
@@ -4925,6 +5111,11 @@ int pevent_register_event_handler(struct pevent *pevent,
4925 if (sys_name) 5111 if (sys_name)
4926 handle->sys_name = strdup(sys_name); 5112 handle->sys_name = strdup(sys_name);
4927 5113
5114 if ((event_name && !handle->event_name) ||
5115 (sys_name && !handle->sys_name)) {
5116 die("Failed to allocate event/sys name");
5117 }
5118
4928 handle->func = func; 5119 handle->func = func;
4929 handle->next = pevent->handlers; 5120 handle->next = pevent->handlers;
4930 pevent->handlers = handle; 5121 pevent->handlers = handle;
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index ac997bc7b592..5772ad8cb386 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -226,6 +226,11 @@ struct print_arg_symbol {
226 struct print_flag_sym *symbols; 226 struct print_flag_sym *symbols;
227}; 227};
228 228
229struct print_arg_hex {
230 struct print_arg *field;
231 struct print_arg *size;
232};
233
229struct print_arg_dynarray { 234struct print_arg_dynarray {
230 struct format_field *field; 235 struct format_field *field;
231 struct print_arg *index; 236 struct print_arg *index;
@@ -253,6 +258,7 @@ enum print_arg_type {
253 PRINT_FIELD, 258 PRINT_FIELD,
254 PRINT_FLAGS, 259 PRINT_FLAGS,
255 PRINT_SYMBOL, 260 PRINT_SYMBOL,
261 PRINT_HEX,
256 PRINT_TYPE, 262 PRINT_TYPE,
257 PRINT_STRING, 263 PRINT_STRING,
258 PRINT_BSTRING, 264 PRINT_BSTRING,
@@ -270,6 +276,7 @@ struct print_arg {
270 struct print_arg_typecast typecast; 276 struct print_arg_typecast typecast;
271 struct print_arg_flags flags; 277 struct print_arg_flags flags;
272 struct print_arg_symbol symbol; 278 struct print_arg_symbol symbol;
279 struct print_arg_hex hex;
273 struct print_arg_func func; 280 struct print_arg_func func;
274 struct print_arg_string string; 281 struct print_arg_string string;
275 struct print_arg_op op; 282 struct print_arg_op op;
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index dfcfe2c131de..ad17855528f9 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -96,7 +96,7 @@ static enum event_type read_token(char **tok)
96 (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) && 96 (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
97 pevent_peek_char() == '~') { 97 pevent_peek_char() == '~') {
98 /* append it */ 98 /* append it */
99 *tok = malloc(3); 99 *tok = malloc_or_die(3);
100 sprintf(*tok, "%c%c", *token, '~'); 100 sprintf(*tok, "%c%c", *token, '~');
101 free_token(token); 101 free_token(token);
102 /* Now remove the '~' from the buffer */ 102 /* Now remove the '~' from the buffer */
@@ -148,17 +148,11 @@ add_filter_type(struct event_filter *filter, int id)
148 if (filter_type) 148 if (filter_type)
149 return filter_type; 149 return filter_type;
150 150
151 if (!filter->filters) 151 filter->event_filters = realloc(filter->event_filters,
152 filter->event_filters = 152 sizeof(*filter->event_filters) *
153 malloc_or_die(sizeof(*filter->event_filters)); 153 (filter->filters + 1));
154 else { 154 if (!filter->event_filters)
155 filter->event_filters = 155 die("Could not allocate filter");
156 realloc(filter->event_filters,
157 sizeof(*filter->event_filters) *
158 (filter->filters + 1));
159 if (!filter->event_filters)
160 die("Could not allocate filter");
161 }
162 156
163 for (i = 0; i < filter->filters; i++) { 157 for (i = 0; i < filter->filters; i++) {
164 if (filter->event_filters[i].event_id > id) 158 if (filter->event_filters[i].event_id > id)
@@ -1480,7 +1474,7 @@ void pevent_filter_clear_trivial(struct event_filter *filter,
1480{ 1474{
1481 struct filter_type *filter_type; 1475 struct filter_type *filter_type;
1482 int count = 0; 1476 int count = 0;
1483 int *ids; 1477 int *ids = NULL;
1484 int i; 1478 int i;
1485 1479
1486 if (!filter->filters) 1480 if (!filter->filters)
@@ -1504,10 +1498,8 @@ void pevent_filter_clear_trivial(struct event_filter *filter,
1504 default: 1498 default:
1505 break; 1499 break;
1506 } 1500 }
1507 if (count) 1501
1508 ids = realloc(ids, sizeof(*ids) * (count + 1)); 1502 ids = realloc(ids, sizeof(*ids) * (count + 1));
1509 else
1510 ids = malloc(sizeof(*ids));
1511 if (!ids) 1503 if (!ids)
1512 die("Can't allocate ids"); 1504 die("Can't allocate ids");
1513 ids[count++] = filter_type->event_id; 1505 ids[count++] = filter_type->event_id;
@@ -1710,18 +1702,43 @@ static int test_num(struct event_format *event,
1710 1702
1711static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record) 1703static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record)
1712{ 1704{
1713 const char *val = record->data + arg->str.field->offset; 1705 struct event_format *event;
1706 struct pevent *pevent;
1707 unsigned long long addr;
1708 const char *val = NULL;
1709 char hex[64];
1714 1710
1715 /* 1711 /* If the field is not a string convert it */
1716 * We need to copy the data since we can't be sure the field 1712 if (arg->str.field->flags & FIELD_IS_STRING) {
1717 * is null terminated. 1713 val = record->data + arg->str.field->offset;
1718 */ 1714
1719 if (*(val + arg->str.field->size - 1)) { 1715 /*
1720 /* copy it */ 1716 * We need to copy the data since we can't be sure the field
1721 memcpy(arg->str.buffer, val, arg->str.field->size); 1717 * is null terminated.
1722 /* the buffer is already NULL terminated */ 1718 */
1723 val = arg->str.buffer; 1719 if (*(val + arg->str.field->size - 1)) {
1720 /* copy it */
1721 memcpy(arg->str.buffer, val, arg->str.field->size);
1722 /* the buffer is already NULL terminated */
1723 val = arg->str.buffer;
1724 }
1725
1726 } else {
1727 event = arg->str.field->event;
1728 pevent = event->pevent;
1729 addr = get_value(event, arg->str.field, record);
1730
1731 if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG))
1732 /* convert to a kernel symbol */
1733 val = pevent_find_function(pevent, addr);
1734
1735 if (val == NULL) {
1736 /* just use the hex of the string name */
1737 snprintf(hex, 64, "0x%llx", addr);
1738 val = hex;
1739 }
1724 } 1740 }
1741
1725 return val; 1742 return val;
1726} 1743}
1727 1744
@@ -2001,11 +2018,13 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
2001 char *lstr; 2018 char *lstr;
2002 char *rstr; 2019 char *rstr;
2003 char *op; 2020 char *op;
2004 char *str; 2021 char *str = NULL;
2005 int len; 2022 int len;
2006 2023
2007 lstr = arg_to_str(filter, arg->exp.left); 2024 lstr = arg_to_str(filter, arg->exp.left);
2008 rstr = arg_to_str(filter, arg->exp.right); 2025 rstr = arg_to_str(filter, arg->exp.right);
2026 if (!lstr || !rstr)
2027 goto out;
2009 2028
2010 switch (arg->exp.type) { 2029 switch (arg->exp.type) {
2011 case FILTER_EXP_ADD: 2030 case FILTER_EXP_ADD:
@@ -2045,6 +2064,7 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
2045 len = strlen(op) + strlen(lstr) + strlen(rstr) + 4; 2064 len = strlen(op) + strlen(lstr) + strlen(rstr) + 4;
2046 str = malloc_or_die(len); 2065 str = malloc_or_die(len);
2047 snprintf(str, len, "%s %s %s", lstr, op, rstr); 2066 snprintf(str, len, "%s %s %s", lstr, op, rstr);
2067out:
2048 free(lstr); 2068 free(lstr);
2049 free(rstr); 2069 free(rstr);
2050 2070
@@ -2061,6 +2081,8 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
2061 2081
2062 lstr = arg_to_str(filter, arg->num.left); 2082 lstr = arg_to_str(filter, arg->num.left);
2063 rstr = arg_to_str(filter, arg->num.right); 2083 rstr = arg_to_str(filter, arg->num.right);
2084 if (!lstr || !rstr)
2085 goto out;
2064 2086
2065 switch (arg->num.type) { 2087 switch (arg->num.type) {
2066 case FILTER_CMP_EQ: 2088 case FILTER_CMP_EQ:
@@ -2097,6 +2119,7 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
2097 break; 2119 break;
2098 } 2120 }
2099 2121
2122out:
2100 free(lstr); 2123 free(lstr);
2101 free(rstr); 2124 free(rstr);
2102 return str; 2125 return str;
@@ -2247,7 +2270,12 @@ int pevent_filter_compare(struct event_filter *filter1, struct event_filter *fil
2247 /* The best way to compare complex filters is with strings */ 2270 /* The best way to compare complex filters is with strings */
2248 str1 = arg_to_str(filter1, filter_type1->filter); 2271 str1 = arg_to_str(filter1, filter_type1->filter);
2249 str2 = arg_to_str(filter2, filter_type2->filter); 2272 str2 = arg_to_str(filter2, filter_type2->filter);
2250 result = strcmp(str1, str2) != 0; 2273 if (str1 && str2)
2274 result = strcmp(str1, str2) != 0;
2275 else
2276 /* bail out if allocation fails */
2277 result = 1;
2278
2251 free(str1); 2279 free(str1);
2252 free(str2); 2280 free(str2);
2253 if (result) 2281 if (result)
diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt
index f3c716a4cad3..7065cd6fbdfc 100644
--- a/tools/perf/Documentation/perf-bench.txt
+++ b/tools/perf/Documentation/perf-bench.txt
@@ -144,7 +144,7 @@ On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported.
144Repeat memcpy invocation this number of times. 144Repeat memcpy invocation this number of times.
145 145
146-c:: 146-c::
147--clock:: 147--cycle::
148Use perf's cpu-cycles event instead of gettimeofday syscall. 148Use perf's cpu-cycles event instead of gettimeofday syscall.
149 149
150-o:: 150-o::
@@ -176,7 +176,7 @@ On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported.
176Repeat memset invocation this number of times. 176Repeat memset invocation this number of times.
177 177
178-c:: 178-c::
179--clock:: 179--cycle::
180Use perf's cpu-cycles event instead of gettimeofday syscall. 180Use perf's cpu-cycles event instead of gettimeofday syscall.
181 181
182-o:: 182-o::
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index d990365cafa0..02dad5d3359b 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -24,8 +24,8 @@
24static const char *length_str = "1MB"; 24static const char *length_str = "1MB";
25static const char *routine = "default"; 25static const char *routine = "default";
26static int iterations = 1; 26static int iterations = 1;
27static bool use_clock; 27static bool use_cycle;
28static int clock_fd; 28static int cycle_fd;
29static bool only_prefault; 29static bool only_prefault;
30static bool no_prefault; 30static bool no_prefault;
31 31
@@ -37,7 +37,7 @@ static const struct option options[] = {
37 "Specify routine to copy"), 37 "Specify routine to copy"),
38 OPT_INTEGER('i', "iterations", &iterations, 38 OPT_INTEGER('i', "iterations", &iterations,
39 "repeat memcpy() invocation this number of times"), 39 "repeat memcpy() invocation this number of times"),
40 OPT_BOOLEAN('c', "clock", &use_clock, 40 OPT_BOOLEAN('c', "cycle", &use_cycle,
41 "Use cycles event instead of gettimeofday() for measuring"), 41 "Use cycles event instead of gettimeofday() for measuring"),
42 OPT_BOOLEAN('o', "only-prefault", &only_prefault, 42 OPT_BOOLEAN('o', "only-prefault", &only_prefault,
43 "Show only the result with page faults before memcpy()"), 43 "Show only the result with page faults before memcpy()"),
@@ -76,27 +76,27 @@ static const char * const bench_mem_memcpy_usage[] = {
76 NULL 76 NULL
77}; 77};
78 78
79static struct perf_event_attr clock_attr = { 79static struct perf_event_attr cycle_attr = {
80 .type = PERF_TYPE_HARDWARE, 80 .type = PERF_TYPE_HARDWARE,
81 .config = PERF_COUNT_HW_CPU_CYCLES 81 .config = PERF_COUNT_HW_CPU_CYCLES
82}; 82};
83 83
84static void init_clock(void) 84static void init_cycle(void)
85{ 85{
86 clock_fd = sys_perf_event_open(&clock_attr, getpid(), -1, -1, 0); 86 cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, 0);
87 87
88 if (clock_fd < 0 && errno == ENOSYS) 88 if (cycle_fd < 0 && errno == ENOSYS)
89 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 89 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
90 else 90 else
91 BUG_ON(clock_fd < 0); 91 BUG_ON(cycle_fd < 0);
92} 92}
93 93
94static u64 get_clock(void) 94static u64 get_cycle(void)
95{ 95{
96 int ret; 96 int ret;
97 u64 clk; 97 u64 clk;
98 98
99 ret = read(clock_fd, &clk, sizeof(u64)); 99 ret = read(cycle_fd, &clk, sizeof(u64));
100 BUG_ON(ret != sizeof(u64)); 100 BUG_ON(ret != sizeof(u64));
101 101
102 return clk; 102 return clk;
@@ -119,9 +119,9 @@ static void alloc_mem(void **dst, void **src, size_t length)
119 die("memory allocation failed - maybe length is too large?\n"); 119 die("memory allocation failed - maybe length is too large?\n");
120} 120}
121 121
122static u64 do_memcpy_clock(memcpy_t fn, size_t len, bool prefault) 122static u64 do_memcpy_cycle(memcpy_t fn, size_t len, bool prefault)
123{ 123{
124 u64 clock_start = 0ULL, clock_end = 0ULL; 124 u64 cycle_start = 0ULL, cycle_end = 0ULL;
125 void *src = NULL, *dst = NULL; 125 void *src = NULL, *dst = NULL;
126 int i; 126 int i;
127 127
@@ -130,14 +130,14 @@ static u64 do_memcpy_clock(memcpy_t fn, size_t len, bool prefault)
130 if (prefault) 130 if (prefault)
131 fn(dst, src, len); 131 fn(dst, src, len);
132 132
133 clock_start = get_clock(); 133 cycle_start = get_cycle();
134 for (i = 0; i < iterations; ++i) 134 for (i = 0; i < iterations; ++i)
135 fn(dst, src, len); 135 fn(dst, src, len);
136 clock_end = get_clock(); 136 cycle_end = get_cycle();
137 137
138 free(src); 138 free(src);
139 free(dst); 139 free(dst);
140 return clock_end - clock_start; 140 return cycle_end - cycle_start;
141} 141}
142 142
143static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault) 143static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault)
@@ -182,17 +182,17 @@ int bench_mem_memcpy(int argc, const char **argv,
182 int i; 182 int i;
183 size_t len; 183 size_t len;
184 double result_bps[2]; 184 double result_bps[2];
185 u64 result_clock[2]; 185 u64 result_cycle[2];
186 186
187 argc = parse_options(argc, argv, options, 187 argc = parse_options(argc, argv, options,
188 bench_mem_memcpy_usage, 0); 188 bench_mem_memcpy_usage, 0);
189 189
190 if (use_clock) 190 if (use_cycle)
191 init_clock(); 191 init_cycle();
192 192
193 len = (size_t)perf_atoll((char *)length_str); 193 len = (size_t)perf_atoll((char *)length_str);
194 194
195 result_clock[0] = result_clock[1] = 0ULL; 195 result_cycle[0] = result_cycle[1] = 0ULL;
196 result_bps[0] = result_bps[1] = 0.0; 196 result_bps[0] = result_bps[1] = 0.0;
197 197
198 if ((s64)len <= 0) { 198 if ((s64)len <= 0) {
@@ -223,11 +223,11 @@ int bench_mem_memcpy(int argc, const char **argv,
223 223
224 if (!only_prefault && !no_prefault) { 224 if (!only_prefault && !no_prefault) {
225 /* show both of results */ 225 /* show both of results */
226 if (use_clock) { 226 if (use_cycle) {
227 result_clock[0] = 227 result_cycle[0] =
228 do_memcpy_clock(routines[i].fn, len, false); 228 do_memcpy_cycle(routines[i].fn, len, false);
229 result_clock[1] = 229 result_cycle[1] =
230 do_memcpy_clock(routines[i].fn, len, true); 230 do_memcpy_cycle(routines[i].fn, len, true);
231 } else { 231 } else {
232 result_bps[0] = 232 result_bps[0] =
233 do_memcpy_gettimeofday(routines[i].fn, 233 do_memcpy_gettimeofday(routines[i].fn,
@@ -237,9 +237,9 @@ int bench_mem_memcpy(int argc, const char **argv,
237 len, true); 237 len, true);
238 } 238 }
239 } else { 239 } else {
240 if (use_clock) { 240 if (use_cycle) {
241 result_clock[pf] = 241 result_cycle[pf] =
242 do_memcpy_clock(routines[i].fn, 242 do_memcpy_cycle(routines[i].fn,
243 len, only_prefault); 243 len, only_prefault);
244 } else { 244 } else {
245 result_bps[pf] = 245 result_bps[pf] =
@@ -251,12 +251,12 @@ int bench_mem_memcpy(int argc, const char **argv,
251 switch (bench_format) { 251 switch (bench_format) {
252 case BENCH_FORMAT_DEFAULT: 252 case BENCH_FORMAT_DEFAULT:
253 if (!only_prefault && !no_prefault) { 253 if (!only_prefault && !no_prefault) {
254 if (use_clock) { 254 if (use_cycle) {
255 printf(" %14lf Clock/Byte\n", 255 printf(" %14lf Cycle/Byte\n",
256 (double)result_clock[0] 256 (double)result_cycle[0]
257 / (double)len); 257 / (double)len);
258 printf(" %14lf Clock/Byte (with prefault)\n", 258 printf(" %14lf Cycle/Byte (with prefault)\n",
259 (double)result_clock[1] 259 (double)result_cycle[1]
260 / (double)len); 260 / (double)len);
261 } else { 261 } else {
262 print_bps(result_bps[0]); 262 print_bps(result_bps[0]);
@@ -265,9 +265,9 @@ int bench_mem_memcpy(int argc, const char **argv,
265 printf(" (with prefault)\n"); 265 printf(" (with prefault)\n");
266 } 266 }
267 } else { 267 } else {
268 if (use_clock) { 268 if (use_cycle) {
269 printf(" %14lf Clock/Byte", 269 printf(" %14lf Cycle/Byte",
270 (double)result_clock[pf] 270 (double)result_cycle[pf]
271 / (double)len); 271 / (double)len);
272 } else 272 } else
273 print_bps(result_bps[pf]); 273 print_bps(result_bps[pf]);
@@ -277,17 +277,17 @@ int bench_mem_memcpy(int argc, const char **argv,
277 break; 277 break;
278 case BENCH_FORMAT_SIMPLE: 278 case BENCH_FORMAT_SIMPLE:
279 if (!only_prefault && !no_prefault) { 279 if (!only_prefault && !no_prefault) {
280 if (use_clock) { 280 if (use_cycle) {
281 printf("%lf %lf\n", 281 printf("%lf %lf\n",
282 (double)result_clock[0] / (double)len, 282 (double)result_cycle[0] / (double)len,
283 (double)result_clock[1] / (double)len); 283 (double)result_cycle[1] / (double)len);
284 } else { 284 } else {
285 printf("%lf %lf\n", 285 printf("%lf %lf\n",
286 result_bps[0], result_bps[1]); 286 result_bps[0], result_bps[1]);
287 } 287 }
288 } else { 288 } else {
289 if (use_clock) { 289 if (use_cycle) {
290 printf("%lf\n", (double)result_clock[pf] 290 printf("%lf\n", (double)result_cycle[pf]
291 / (double)len); 291 / (double)len);
292 } else 292 } else
293 printf("%lf\n", result_bps[pf]); 293 printf("%lf\n", result_bps[pf]);
diff --git a/tools/perf/bench/mem-memset.c b/tools/perf/bench/mem-memset.c
index bf0d5f552017..350cc9557265 100644
--- a/tools/perf/bench/mem-memset.c
+++ b/tools/perf/bench/mem-memset.c
@@ -24,8 +24,8 @@
24static const char *length_str = "1MB"; 24static const char *length_str = "1MB";
25static const char *routine = "default"; 25static const char *routine = "default";
26static int iterations = 1; 26static int iterations = 1;
27static bool use_clock; 27static bool use_cycle;
28static int clock_fd; 28static int cycle_fd;
29static bool only_prefault; 29static bool only_prefault;
30static bool no_prefault; 30static bool no_prefault;
31 31
@@ -37,7 +37,7 @@ static const struct option options[] = {
37 "Specify routine to set"), 37 "Specify routine to set"),
38 OPT_INTEGER('i', "iterations", &iterations, 38 OPT_INTEGER('i', "iterations", &iterations,
39 "repeat memset() invocation this number of times"), 39 "repeat memset() invocation this number of times"),
40 OPT_BOOLEAN('c', "clock", &use_clock, 40 OPT_BOOLEAN('c', "cycle", &use_cycle,
41 "Use cycles event instead of gettimeofday() for measuring"), 41 "Use cycles event instead of gettimeofday() for measuring"),
42 OPT_BOOLEAN('o', "only-prefault", &only_prefault, 42 OPT_BOOLEAN('o', "only-prefault", &only_prefault,
43 "Show only the result with page faults before memset()"), 43 "Show only the result with page faults before memset()"),
@@ -76,27 +76,27 @@ static const char * const bench_mem_memset_usage[] = {
76 NULL 76 NULL
77}; 77};
78 78
79static struct perf_event_attr clock_attr = { 79static struct perf_event_attr cycle_attr = {
80 .type = PERF_TYPE_HARDWARE, 80 .type = PERF_TYPE_HARDWARE,
81 .config = PERF_COUNT_HW_CPU_CYCLES 81 .config = PERF_COUNT_HW_CPU_CYCLES
82}; 82};
83 83
84static void init_clock(void) 84static void init_cycle(void)
85{ 85{
86 clock_fd = sys_perf_event_open(&clock_attr, getpid(), -1, -1, 0); 86 cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, 0);
87 87
88 if (clock_fd < 0 && errno == ENOSYS) 88 if (cycle_fd < 0 && errno == ENOSYS)
89 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 89 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
90 else 90 else
91 BUG_ON(clock_fd < 0); 91 BUG_ON(cycle_fd < 0);
92} 92}
93 93
94static u64 get_clock(void) 94static u64 get_cycle(void)
95{ 95{
96 int ret; 96 int ret;
97 u64 clk; 97 u64 clk;
98 98
99 ret = read(clock_fd, &clk, sizeof(u64)); 99 ret = read(cycle_fd, &clk, sizeof(u64));
100 BUG_ON(ret != sizeof(u64)); 100 BUG_ON(ret != sizeof(u64));
101 101
102 return clk; 102 return clk;
@@ -115,9 +115,9 @@ static void alloc_mem(void **dst, size_t length)
115 die("memory allocation failed - maybe length is too large?\n"); 115 die("memory allocation failed - maybe length is too large?\n");
116} 116}
117 117
118static u64 do_memset_clock(memset_t fn, size_t len, bool prefault) 118static u64 do_memset_cycle(memset_t fn, size_t len, bool prefault)
119{ 119{
120 u64 clock_start = 0ULL, clock_end = 0ULL; 120 u64 cycle_start = 0ULL, cycle_end = 0ULL;
121 void *dst = NULL; 121 void *dst = NULL;
122 int i; 122 int i;
123 123
@@ -126,13 +126,13 @@ static u64 do_memset_clock(memset_t fn, size_t len, bool prefault)
126 if (prefault) 126 if (prefault)
127 fn(dst, -1, len); 127 fn(dst, -1, len);
128 128
129 clock_start = get_clock(); 129 cycle_start = get_cycle();
130 for (i = 0; i < iterations; ++i) 130 for (i = 0; i < iterations; ++i)
131 fn(dst, i, len); 131 fn(dst, i, len);
132 clock_end = get_clock(); 132 cycle_end = get_cycle();
133 133
134 free(dst); 134 free(dst);
135 return clock_end - clock_start; 135 return cycle_end - cycle_start;
136} 136}
137 137
138static double do_memset_gettimeofday(memset_t fn, size_t len, bool prefault) 138static double do_memset_gettimeofday(memset_t fn, size_t len, bool prefault)
@@ -176,17 +176,17 @@ int bench_mem_memset(int argc, const char **argv,
176 int i; 176 int i;
177 size_t len; 177 size_t len;
178 double result_bps[2]; 178 double result_bps[2];
179 u64 result_clock[2]; 179 u64 result_cycle[2];
180 180
181 argc = parse_options(argc, argv, options, 181 argc = parse_options(argc, argv, options,
182 bench_mem_memset_usage, 0); 182 bench_mem_memset_usage, 0);
183 183
184 if (use_clock) 184 if (use_cycle)
185 init_clock(); 185 init_cycle();
186 186
187 len = (size_t)perf_atoll((char *)length_str); 187 len = (size_t)perf_atoll((char *)length_str);
188 188
189 result_clock[0] = result_clock[1] = 0ULL; 189 result_cycle[0] = result_cycle[1] = 0ULL;
190 result_bps[0] = result_bps[1] = 0.0; 190 result_bps[0] = result_bps[1] = 0.0;
191 191
192 if ((s64)len <= 0) { 192 if ((s64)len <= 0) {
@@ -217,11 +217,11 @@ int bench_mem_memset(int argc, const char **argv,
217 217
218 if (!only_prefault && !no_prefault) { 218 if (!only_prefault && !no_prefault) {
219 /* show both of results */ 219 /* show both of results */
220 if (use_clock) { 220 if (use_cycle) {
221 result_clock[0] = 221 result_cycle[0] =
222 do_memset_clock(routines[i].fn, len, false); 222 do_memset_cycle(routines[i].fn, len, false);
223 result_clock[1] = 223 result_cycle[1] =
224 do_memset_clock(routines[i].fn, len, true); 224 do_memset_cycle(routines[i].fn, len, true);
225 } else { 225 } else {
226 result_bps[0] = 226 result_bps[0] =
227 do_memset_gettimeofday(routines[i].fn, 227 do_memset_gettimeofday(routines[i].fn,
@@ -231,9 +231,9 @@ int bench_mem_memset(int argc, const char **argv,
231 len, true); 231 len, true);
232 } 232 }
233 } else { 233 } else {
234 if (use_clock) { 234 if (use_cycle) {
235 result_clock[pf] = 235 result_cycle[pf] =
236 do_memset_clock(routines[i].fn, 236 do_memset_cycle(routines[i].fn,
237 len, only_prefault); 237 len, only_prefault);
238 } else { 238 } else {
239 result_bps[pf] = 239 result_bps[pf] =
@@ -245,12 +245,12 @@ int bench_mem_memset(int argc, const char **argv,
245 switch (bench_format) { 245 switch (bench_format) {
246 case BENCH_FORMAT_DEFAULT: 246 case BENCH_FORMAT_DEFAULT:
247 if (!only_prefault && !no_prefault) { 247 if (!only_prefault && !no_prefault) {
248 if (use_clock) { 248 if (use_cycle) {
249 printf(" %14lf Clock/Byte\n", 249 printf(" %14lf Cycle/Byte\n",
250 (double)result_clock[0] 250 (double)result_cycle[0]
251 / (double)len); 251 / (double)len);
252 printf(" %14lf Clock/Byte (with prefault)\n ", 252 printf(" %14lf Cycle/Byte (with prefault)\n ",
253 (double)result_clock[1] 253 (double)result_cycle[1]
254 / (double)len); 254 / (double)len);
255 } else { 255 } else {
256 print_bps(result_bps[0]); 256 print_bps(result_bps[0]);
@@ -259,9 +259,9 @@ int bench_mem_memset(int argc, const char **argv,
259 printf(" (with prefault)\n"); 259 printf(" (with prefault)\n");
260 } 260 }
261 } else { 261 } else {
262 if (use_clock) { 262 if (use_cycle) {
263 printf(" %14lf Clock/Byte", 263 printf(" %14lf Cycle/Byte",
264 (double)result_clock[pf] 264 (double)result_cycle[pf]
265 / (double)len); 265 / (double)len);
266 } else 266 } else
267 print_bps(result_bps[pf]); 267 print_bps(result_bps[pf]);
@@ -271,17 +271,17 @@ int bench_mem_memset(int argc, const char **argv,
271 break; 271 break;
272 case BENCH_FORMAT_SIMPLE: 272 case BENCH_FORMAT_SIMPLE:
273 if (!only_prefault && !no_prefault) { 273 if (!only_prefault && !no_prefault) {
274 if (use_clock) { 274 if (use_cycle) {
275 printf("%lf %lf\n", 275 printf("%lf %lf\n",
276 (double)result_clock[0] / (double)len, 276 (double)result_cycle[0] / (double)len,
277 (double)result_clock[1] / (double)len); 277 (double)result_cycle[1] / (double)len);
278 } else { 278 } else {
279 printf("%lf %lf\n", 279 printf("%lf %lf\n",
280 result_bps[0], result_bps[1]); 280 result_bps[0], result_bps[1]);
281 } 281 }
282 } else { 282 } else {
283 if (use_clock) { 283 if (use_cycle) {
284 printf("%lf\n", (double)result_clock[pf] 284 printf("%lf\n", (double)result_cycle[pf]
285 / (double)len); 285 / (double)len);
286 } else 286 } else
287 printf("%lf\n", result_bps[pf]); 287 printf("%lf\n", result_bps[pf]);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 3d1f6968f175..e81771364867 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -15,6 +15,7 @@
15#include "cpumap.h" 15#include "cpumap.h"
16#include "thread_map.h" 16#include "thread_map.h"
17#include "target.h" 17#include "target.h"
18#include "../../../include/linux/hw_breakpoint.h"
18 19
19#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 20#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
20#define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) 21#define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0))
@@ -152,6 +153,31 @@ static int perf_evsel__sw_name(struct perf_evsel *evsel, char *bf, size_t size)
152 return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); 153 return r + perf_evsel__add_modifiers(evsel, bf + r, size - r);
153} 154}
154 155
156static int __perf_evsel__bp_name(char *bf, size_t size, u64 addr, u64 type)
157{
158 int r;
159
160 r = scnprintf(bf, size, "mem:0x%" PRIx64 ":", addr);
161
162 if (type & HW_BREAKPOINT_R)
163 r += scnprintf(bf + r, size - r, "r");
164
165 if (type & HW_BREAKPOINT_W)
166 r += scnprintf(bf + r, size - r, "w");
167
168 if (type & HW_BREAKPOINT_X)
169 r += scnprintf(bf + r, size - r, "x");
170
171 return r;
172}
173
174static int perf_evsel__bp_name(struct perf_evsel *evsel, char *bf, size_t size)
175{
176 struct perf_event_attr *attr = &evsel->attr;
177 int r = __perf_evsel__bp_name(bf, size, attr->bp_addr, attr->bp_type);
178 return r + perf_evsel__add_modifiers(evsel, bf + r, size - r);
179}
180
155const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX] 181const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX]
156 [PERF_EVSEL__MAX_ALIASES] = { 182 [PERF_EVSEL__MAX_ALIASES] = {
157 { "L1-dcache", "l1-d", "l1d", "L1-data", }, 183 { "L1-dcache", "l1-d", "l1d", "L1-data", },
@@ -285,6 +311,10 @@ const char *perf_evsel__name(struct perf_evsel *evsel)
285 scnprintf(bf, sizeof(bf), "%s", "unknown tracepoint"); 311 scnprintf(bf, sizeof(bf), "%s", "unknown tracepoint");
286 break; 312 break;
287 313
314 case PERF_TYPE_BREAKPOINT:
315 perf_evsel__bp_name(evsel, bf, sizeof(bf));
316 break;
317
288 default: 318 default:
289 scnprintf(bf, sizeof(bf), "%s", "unknown attr type"); 319 scnprintf(bf, sizeof(bf), "%s", "unknown attr type");
290 break; 320 break;
diff --git a/tools/perf/util/include/linux/kernel.h b/tools/perf/util/include/linux/kernel.h
index 1eb804fd3fbf..b6842c1d02a8 100644
--- a/tools/perf/util/include/linux/kernel.h
+++ b/tools/perf/util/include/linux/kernel.h
@@ -108,4 +108,14 @@ int eprintf(int level,
108#define pr_debug3(fmt, ...) pr_debugN(3, pr_fmt(fmt), ##__VA_ARGS__) 108#define pr_debug3(fmt, ...) pr_debugN(3, pr_fmt(fmt), ##__VA_ARGS__)
109#define pr_debug4(fmt, ...) pr_debugN(4, pr_fmt(fmt), ##__VA_ARGS__) 109#define pr_debug4(fmt, ...) pr_debugN(4, pr_fmt(fmt), ##__VA_ARGS__)
110 110
111/*
112 * This looks more complex than it should be. But we need to
113 * get the type for the ~ right in round_down (it needs to be
114 * as wide as the result!), and we want to evaluate the macro
115 * arguments just once each.
116 */
117#define __round_mask(x, y) ((__typeof__(x))((y)-1))
118#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
119#define round_down(x, y) ((x) & ~__round_mask(x, y))
120
111#endif 121#endif
diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c
index a0f61a2a6835..1b997d2b89ce 100644
--- a/tools/perf/util/parse-events-test.c
+++ b/tools/perf/util/parse-events-test.c
@@ -181,6 +181,22 @@ static int test__checkevent_breakpoint_w(struct perf_evlist *evlist)
181 return 0; 181 return 0;
182} 182}
183 183
184static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist)
185{
186 struct perf_evsel *evsel = list_entry(evlist->entries.next,
187 struct perf_evsel, node);
188
189 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
190 TEST_ASSERT_VAL("wrong type",
191 PERF_TYPE_BREAKPOINT == evsel->attr.type);
192 TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
193 TEST_ASSERT_VAL("wrong bp_type",
194 (HW_BREAKPOINT_R|HW_BREAKPOINT_W) == evsel->attr.bp_type);
195 TEST_ASSERT_VAL("wrong bp_len",
196 HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
197 return 0;
198}
199
184static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) 200static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist)
185{ 201{
186 struct perf_evsel *evsel = list_entry(evlist->entries.next, 202 struct perf_evsel *evsel = list_entry(evlist->entries.next,
@@ -309,6 +325,8 @@ static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist)
309 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); 325 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
310 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); 326 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
311 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); 327 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
328 TEST_ASSERT_VAL("wrong name",
329 !strcmp(perf_evsel__name(evsel), "mem:0x0:rw:u"));
312 330
313 return test__checkevent_breakpoint(evlist); 331 return test__checkevent_breakpoint(evlist);
314} 332}
@@ -322,6 +340,8 @@ static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist)
322 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); 340 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
323 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); 341 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
324 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); 342 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
343 TEST_ASSERT_VAL("wrong name",
344 !strcmp(perf_evsel__name(evsel), "mem:0x0:x:k"));
325 345
326 return test__checkevent_breakpoint_x(evlist); 346 return test__checkevent_breakpoint_x(evlist);
327} 347}
@@ -335,6 +355,8 @@ static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist)
335 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); 355 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
336 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); 356 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
337 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); 357 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
358 TEST_ASSERT_VAL("wrong name",
359 !strcmp(perf_evsel__name(evsel), "mem:0x0:r:hp"));
338 360
339 return test__checkevent_breakpoint_r(evlist); 361 return test__checkevent_breakpoint_r(evlist);
340} 362}
@@ -348,10 +370,27 @@ static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist)
348 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); 370 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
349 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); 371 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
350 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); 372 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
373 TEST_ASSERT_VAL("wrong name",
374 !strcmp(perf_evsel__name(evsel), "mem:0x0:w:up"));
351 375
352 return test__checkevent_breakpoint_w(evlist); 376 return test__checkevent_breakpoint_w(evlist);
353} 377}
354 378
379static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist)
380{
381 struct perf_evsel *evsel = list_entry(evlist->entries.next,
382 struct perf_evsel, node);
383
384 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
385 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
386 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
387 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
388 TEST_ASSERT_VAL("wrong name",
389 !strcmp(perf_evsel__name(evsel), "mem:0x0:rw:kp"));
390
391 return test__checkevent_breakpoint_rw(evlist);
392}
393
355static int test__checkevent_pmu(struct perf_evlist *evlist) 394static int test__checkevent_pmu(struct perf_evlist *evlist)
356{ 395{
357 396
@@ -585,10 +624,16 @@ static struct test__event_st test__events[] = {
585 .name = "instructions:H", 624 .name = "instructions:H",
586 .check = test__checkevent_exclude_guest_modifier, 625 .check = test__checkevent_exclude_guest_modifier,
587 }, 626 },
627 [26] = {
628 .name = "mem:0:rw",
629 .check = test__checkevent_breakpoint_rw,
630 },
631 [27] = {
632 .name = "mem:0:rw:kp",
633 .check = test__checkevent_breakpoint_rw_modifier,
634 },
588}; 635};
589 636
590#define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st))
591
592static struct test__event_st test__events_pmu[] = { 637static struct test__event_st test__events_pmu[] = {
593 [0] = { 638 [0] = {
594 .name = "cpu/config=10,config1,config2=3,period=1000/u", 639 .name = "cpu/config=10,config1,config2=3,period=1000/u",
@@ -600,9 +645,6 @@ static struct test__event_st test__events_pmu[] = {
600 }, 645 },
601}; 646};
602 647
603#define TEST__EVENTS_PMU_CNT (sizeof(test__events_pmu) / \
604 sizeof(struct test__event_st))
605
606struct test__term { 648struct test__term {
607 const char *str; 649 const char *str;
608 __u32 type; 650 __u32 type;
@@ -718,21 +760,17 @@ int parse_events__test(void)
718{ 760{
719 int ret; 761 int ret;
720 762
721 do { 763#define TEST_EVENTS(tests) \
722 ret = test_events(test__events, TEST__EVENTS_CNT); 764do { \
723 if (ret) 765 ret = test_events(tests, ARRAY_SIZE(tests)); \
724 break; 766 if (ret) \
725 767 return ret; \
726 if (test_pmu()) { 768} while (0)
727 ret = test_events(test__events_pmu,
728 TEST__EVENTS_PMU_CNT);
729 if (ret)
730 break;
731 }
732 769
733 ret = test_terms(test__terms, TEST__TERMS_CNT); 770 TEST_EVENTS(test__events);
734 771
735 } while (0); 772 if (test_pmu())
773 TEST_EVENTS(test__events_pmu);
736 774
737 return ret; 775 return test_terms(test__terms, ARRAY_SIZE(test__terms));
738} 776}
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 0cc27da30ddb..1aa721d7c10f 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -19,8 +19,6 @@
19#define MAX_NAME_LEN 100 19#define MAX_NAME_LEN 100
20 20
21struct event_symbol { 21struct event_symbol {
22 u8 type;
23 u64 config;
24 const char *symbol; 22 const char *symbol;
25 const char *alias; 23 const char *alias;
26}; 24};
@@ -30,30 +28,86 @@ extern int parse_events_debug;
30#endif 28#endif
31int parse_events_parse(void *data, void *scanner); 29int parse_events_parse(void *data, void *scanner);
32 30
33#define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x 31static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
34#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x 32 [PERF_COUNT_HW_CPU_CYCLES] = {
35 33 .symbol = "cpu-cycles",
36static struct event_symbol event_symbols[] = { 34 .alias = "cycles",
37 { CHW(CPU_CYCLES), "cpu-cycles", "cycles" }, 35 },
38 { CHW(STALLED_CYCLES_FRONTEND), "stalled-cycles-frontend", "idle-cycles-frontend" }, 36 [PERF_COUNT_HW_INSTRUCTIONS] = {
39 { CHW(STALLED_CYCLES_BACKEND), "stalled-cycles-backend", "idle-cycles-backend" }, 37 .symbol = "instructions",
40 { CHW(INSTRUCTIONS), "instructions", "" }, 38 .alias = "",
41 { CHW(CACHE_REFERENCES), "cache-references", "" }, 39 },
42 { CHW(CACHE_MISSES), "cache-misses", "" }, 40 [PERF_COUNT_HW_CACHE_REFERENCES] = {
43 { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, 41 .symbol = "cache-references",
44 { CHW(BRANCH_MISSES), "branch-misses", "" }, 42 .alias = "",
45 { CHW(BUS_CYCLES), "bus-cycles", "" }, 43 },
46 { CHW(REF_CPU_CYCLES), "ref-cycles", "" }, 44 [PERF_COUNT_HW_CACHE_MISSES] = {
47 45 .symbol = "cache-misses",
48 { CSW(CPU_CLOCK), "cpu-clock", "" }, 46 .alias = "",
49 { CSW(TASK_CLOCK), "task-clock", "" }, 47 },
50 { CSW(PAGE_FAULTS), "page-faults", "faults" }, 48 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = {
51 { CSW(PAGE_FAULTS_MIN), "minor-faults", "" }, 49 .symbol = "branch-instructions",
52 { CSW(PAGE_FAULTS_MAJ), "major-faults", "" }, 50 .alias = "branches",
53 { CSW(CONTEXT_SWITCHES), "context-switches", "cs" }, 51 },
54 { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, 52 [PERF_COUNT_HW_BRANCH_MISSES] = {
55 { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" }, 53 .symbol = "branch-misses",
56 { CSW(EMULATION_FAULTS), "emulation-faults", "" }, 54 .alias = "",
55 },
56 [PERF_COUNT_HW_BUS_CYCLES] = {
57 .symbol = "bus-cycles",
58 .alias = "",
59 },
60 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = {
61 .symbol = "stalled-cycles-frontend",
62 .alias = "idle-cycles-frontend",
63 },
64 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = {
65 .symbol = "stalled-cycles-backend",
66 .alias = "idle-cycles-backend",
67 },
68 [PERF_COUNT_HW_REF_CPU_CYCLES] = {
69 .symbol = "ref-cycles",
70 .alias = "",
71 },
72};
73
74static struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
75 [PERF_COUNT_SW_CPU_CLOCK] = {
76 .symbol = "cpu-clock",
77 .alias = "",
78 },
79 [PERF_COUNT_SW_TASK_CLOCK] = {
80 .symbol = "task-clock",
81 .alias = "",
82 },
83 [PERF_COUNT_SW_PAGE_FAULTS] = {
84 .symbol = "page-faults",
85 .alias = "faults",
86 },
87 [PERF_COUNT_SW_CONTEXT_SWITCHES] = {
88 .symbol = "context-switches",
89 .alias = "cs",
90 },
91 [PERF_COUNT_SW_CPU_MIGRATIONS] = {
92 .symbol = "cpu-migrations",
93 .alias = "migrations",
94 },
95 [PERF_COUNT_SW_PAGE_FAULTS_MIN] = {
96 .symbol = "minor-faults",
97 .alias = "",
98 },
99 [PERF_COUNT_SW_PAGE_FAULTS_MAJ] = {
100 .symbol = "major-faults",
101 .alias = "",
102 },
103 [PERF_COUNT_SW_ALIGNMENT_FAULTS] = {
104 .symbol = "alignment-faults",
105 .alias = "",
106 },
107 [PERF_COUNT_SW_EMULATION_FAULTS] = {
108 .symbol = "emulation-faults",
109 .alias = "",
110 },
57}; 111};
58 112
59#define __PERF_EVENT_FIELD(config, name) \ 113#define __PERF_EVENT_FIELD(config, name) \
@@ -383,21 +437,31 @@ parse_breakpoint_type(const char *type, struct perf_event_attr *attr)
383 if (!type || !type[i]) 437 if (!type || !type[i])
384 break; 438 break;
385 439
440#define CHECK_SET_TYPE(bit) \
441do { \
442 if (attr->bp_type & bit) \
443 return -EINVAL; \
444 else \
445 attr->bp_type |= bit; \
446} while (0)
447
386 switch (type[i]) { 448 switch (type[i]) {
387 case 'r': 449 case 'r':
388 attr->bp_type |= HW_BREAKPOINT_R; 450 CHECK_SET_TYPE(HW_BREAKPOINT_R);
389 break; 451 break;
390 case 'w': 452 case 'w':
391 attr->bp_type |= HW_BREAKPOINT_W; 453 CHECK_SET_TYPE(HW_BREAKPOINT_W);
392 break; 454 break;
393 case 'x': 455 case 'x':
394 attr->bp_type |= HW_BREAKPOINT_X; 456 CHECK_SET_TYPE(HW_BREAKPOINT_X);
395 break; 457 break;
396 default: 458 default:
397 return -EINVAL; 459 return -EINVAL;
398 } 460 }
399 } 461 }
400 462
463#undef CHECK_SET_TYPE
464
401 if (!attr->bp_type) /* Default */ 465 if (!attr->bp_type) /* Default */
402 attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; 466 attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W;
403 467
@@ -408,7 +472,6 @@ int parse_events_add_breakpoint(struct list_head **list, int *idx,
408 void *ptr, char *type) 472 void *ptr, char *type)
409{ 473{
410 struct perf_event_attr attr; 474 struct perf_event_attr attr;
411 char name[MAX_NAME_LEN];
412 475
413 memset(&attr, 0, sizeof(attr)); 476 memset(&attr, 0, sizeof(attr));
414 attr.bp_addr = (unsigned long) ptr; 477 attr.bp_addr = (unsigned long) ptr;
@@ -427,8 +490,7 @@ int parse_events_add_breakpoint(struct list_head **list, int *idx,
427 490
428 attr.type = PERF_TYPE_BREAKPOINT; 491 attr.type = PERF_TYPE_BREAKPOINT;
429 492
430 snprintf(name, MAX_NAME_LEN, "mem:%p:%s", ptr, type ? type : "rw"); 493 return add_event(list, idx, &attr, NULL);
431 return add_event(list, idx, &attr, name);
432} 494}
433 495
434static int config_term(struct perf_event_attr *attr, 496static int config_term(struct perf_event_attr *attr,
@@ -816,16 +878,13 @@ int is_valid_tracepoint(const char *event_string)
816 return 0; 878 return 0;
817} 879}
818 880
819void print_events_type(u8 type) 881static void __print_events_type(u8 type, struct event_symbol *syms,
882 unsigned max)
820{ 883{
821 struct event_symbol *syms = event_symbols;
822 unsigned int i;
823 char name[64]; 884 char name[64];
885 unsigned i;
824 886
825 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { 887 for (i = 0; i < max ; i++, syms++) {
826 if (type != syms->type)
827 continue;
828
829 if (strlen(syms->alias)) 888 if (strlen(syms->alias))
830 snprintf(name, sizeof(name), "%s OR %s", 889 snprintf(name, sizeof(name), "%s OR %s",
831 syms->symbol, syms->alias); 890 syms->symbol, syms->alias);
@@ -837,6 +896,14 @@ void print_events_type(u8 type)
837 } 896 }
838} 897}
839 898
899void print_events_type(u8 type)
900{
901 if (type == PERF_TYPE_SOFTWARE)
902 __print_events_type(type, event_symbols_sw, PERF_COUNT_SW_MAX);
903 else
904 __print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX);
905}
906
840int print_hwcache_events(const char *event_glob) 907int print_hwcache_events(const char *event_glob)
841{ 908{
842 unsigned int type, op, i, printed = 0; 909 unsigned int type, op, i, printed = 0;
@@ -864,26 +931,13 @@ int print_hwcache_events(const char *event_glob)
864 return printed; 931 return printed;
865} 932}
866 933
867/* 934static void print_symbol_events(const char *event_glob, unsigned type,
868 * Print the help text for the event symbols: 935 struct event_symbol *syms, unsigned max)
869 */
870void print_events(const char *event_glob)
871{ 936{
872 unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0; 937 unsigned i, printed = 0;
873 struct event_symbol *syms = event_symbols;
874 char name[MAX_NAME_LEN]; 938 char name[MAX_NAME_LEN];
875 939
876 printf("\n"); 940 for (i = 0; i < max; i++, syms++) {
877 printf("List of pre-defined events (to be used in -e):\n");
878
879 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
880 type = syms->type;
881
882 if (type != prev_type && printed) {
883 printf("\n");
884 printed = 0;
885 ntypes_printed++;
886 }
887 941
888 if (event_glob != NULL && 942 if (event_glob != NULL &&
889 !(strglobmatch(syms->symbol, event_glob) || 943 !(strglobmatch(syms->symbol, event_glob) ||
@@ -894,17 +948,31 @@ void print_events(const char *event_glob)
894 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); 948 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
895 else 949 else
896 strncpy(name, syms->symbol, MAX_NAME_LEN); 950 strncpy(name, syms->symbol, MAX_NAME_LEN);
897 printf(" %-50s [%s]\n", name,
898 event_type_descriptors[type]);
899 951
900 prev_type = type; 952 printf(" %-50s [%s]\n", name, event_type_descriptors[type]);
901 ++printed; 953
954 printed++;
902 } 955 }
903 956
904 if (ntypes_printed) { 957 if (printed)
905 printed = 0;
906 printf("\n"); 958 printf("\n");
907 } 959}
960
961/*
962 * Print the help text for the event symbols:
963 */
964void print_events(const char *event_glob)
965{
966
967 printf("\n");
968 printf("List of pre-defined events (to be used in -e):\n");
969
970 print_symbol_events(event_glob, PERF_TYPE_HARDWARE,
971 event_symbols_hw, PERF_COUNT_HW_MAX);
972
973 print_symbol_events(event_glob, PERF_TYPE_SOFTWARE,
974 event_symbols_sw, PERF_COUNT_SW_MAX);
975
908 print_hwcache_events(event_glob); 976 print_hwcache_events(event_glob);
909 977
910 if (event_glob != NULL) 978 if (event_glob != NULL)
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 488362e14133..384ca74c6b22 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -56,7 +56,7 @@ static int sym(yyscan_t scanner, int type, int config)
56 YYSTYPE *yylval = parse_events_get_lval(scanner); 56 YYSTYPE *yylval = parse_events_get_lval(scanner);
57 57
58 yylval->num = (type << 16) + config; 58 yylval->num = (type << 16) + config;
59 return PE_VALUE_SYM; 59 return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW;
60} 60}
61 61
62static int term(yyscan_t scanner, int type) 62static int term(yyscan_t scanner, int type)
@@ -76,7 +76,7 @@ num_hex 0x[a-fA-F0-9]+
76num_raw_hex [a-fA-F0-9]+ 76num_raw_hex [a-fA-F0-9]+
77name [a-zA-Z_*?][a-zA-Z0-9_*?]* 77name [a-zA-Z_*?][a-zA-Z0-9_*?]*
78modifier_event [ukhpGH]{1,8} 78modifier_event [ukhpGH]{1,8}
79modifier_bp [rwx] 79modifier_bp [rwx]{1,3}
80 80
81%% 81%%
82 82
@@ -152,6 +152,7 @@ r{num_raw_hex} { return raw(yyscanner); }
152, { return ','; } 152, { return ','; }
153: { return ':'; } 153: { return ':'; }
154= { return '='; } 154= { return '='; }
155\n { }
155 156
156<mem>{ 157<mem>{
157{modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); } 158{modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); }
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 9525c455d27f..2bc5fbff2b5d 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -26,14 +26,15 @@ do { \
26%} 26%}
27 27
28%token PE_START_EVENTS PE_START_TERMS 28%token PE_START_EVENTS PE_START_TERMS
29%token PE_VALUE PE_VALUE_SYM PE_RAW PE_TERM 29%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
30%token PE_NAME 30%token PE_NAME
31%token PE_MODIFIER_EVENT PE_MODIFIER_BP 31%token PE_MODIFIER_EVENT PE_MODIFIER_BP
32%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT 32%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
33%token PE_PREFIX_MEM PE_PREFIX_RAW 33%token PE_PREFIX_MEM PE_PREFIX_RAW
34%token PE_ERROR 34%token PE_ERROR
35%type <num> PE_VALUE 35%type <num> PE_VALUE
36%type <num> PE_VALUE_SYM 36%type <num> PE_VALUE_SYM_HW
37%type <num> PE_VALUE_SYM_SW
37%type <num> PE_RAW 38%type <num> PE_RAW
38%type <num> PE_TERM 39%type <num> PE_TERM
39%type <str> PE_NAME 40%type <str> PE_NAME
@@ -41,6 +42,7 @@ do { \
41%type <str> PE_NAME_CACHE_OP_RESULT 42%type <str> PE_NAME_CACHE_OP_RESULT
42%type <str> PE_MODIFIER_EVENT 43%type <str> PE_MODIFIER_EVENT
43%type <str> PE_MODIFIER_BP 44%type <str> PE_MODIFIER_BP
45%type <num> value_sym
44%type <head> event_config 46%type <head> event_config
45%type <term> event_term 47%type <term> event_term
46%type <head> event_pmu 48%type <head> event_pmu
@@ -109,8 +111,13 @@ PE_NAME '/' event_config '/'
109 $$ = list; 111 $$ = list;
110} 112}
111 113
114value_sym:
115PE_VALUE_SYM_HW
116|
117PE_VALUE_SYM_SW
118
112event_legacy_symbol: 119event_legacy_symbol:
113PE_VALUE_SYM '/' event_config '/' 120value_sym '/' event_config '/'
114{ 121{
115 struct parse_events_data__events *data = _data; 122 struct parse_events_data__events *data = _data;
116 struct list_head *list = NULL; 123 struct list_head *list = NULL;
@@ -123,7 +130,7 @@ PE_VALUE_SYM '/' event_config '/'
123 $$ = list; 130 $$ = list;
124} 131}
125| 132|
126PE_VALUE_SYM sep_slash_dc 133value_sym sep_slash_dc
127{ 134{
128 struct parse_events_data__events *data = _data; 135 struct parse_events_data__events *data = _data;
129 struct list_head *list = NULL; 136 struct list_head *list = NULL;
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 74d0948ec368..67715a42cd6d 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -72,7 +72,7 @@ static int pmu_format(char *name, struct list_head *format)
72 "%s/bus/event_source/devices/%s/format", sysfs, name); 72 "%s/bus/event_source/devices/%s/format", sysfs, name);
73 73
74 if (stat(path, &st) < 0) 74 if (stat(path, &st) < 0)
75 return -1; 75 return 0; /* no error if format does not exist */
76 76
77 if (pmu_format_parse(path, format)) 77 if (pmu_format_parse(path, format))
78 return -1; 78 return -1;
@@ -252,6 +252,7 @@ static struct perf_pmu *pmu_lookup(char *name)
252 list_splice(&aliases, &pmu->aliases); 252 list_splice(&aliases, &pmu->aliases);
253 pmu->name = strdup(name); 253 pmu->name = strdup(name);
254 pmu->type = type; 254 pmu->type = type;
255 list_add_tail(&pmu->list, &pmus);
255 return pmu; 256 return pmu;
256} 257}
257 258
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index b3620fe12763..02dfa19a467f 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -209,6 +209,10 @@ static void define_event_symbols(struct event_format *event,
209 define_symbolic_values(args->symbol.symbols, ev_name, 209 define_symbolic_values(args->symbol.symbols, ev_name,
210 cur_field_name); 210 cur_field_name);
211 break; 211 break;
212 case PRINT_HEX:
213 define_event_symbols(event, ev_name, args->hex.field);
214 define_event_symbols(event, ev_name, args->hex.size);
215 break;
212 case PRINT_BSTRING: 216 case PRINT_BSTRING:
213 case PRINT_DYNAMIC_ARRAY: 217 case PRINT_DYNAMIC_ARRAY:
214 case PRINT_STRING: 218 case PRINT_STRING:
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index a8ca2f8179a9..ce4d1b0c3862 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -166,6 +166,10 @@ static void define_event_symbols(struct event_format *event,
166 define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name, 166 define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name,
167 cur_field_name); 167 cur_field_name);
168 break; 168 break;
169 case PRINT_HEX:
170 define_event_symbols(event, ev_name, args->hex.field);
171 define_event_symbols(event, ev_name, args->hex.size);
172 break;
169 case PRINT_STRING: 173 case PRINT_STRING:
170 break; 174 break;
171 case PRINT_TYPE: 175 case PRINT_TYPE:
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 994f4ffdcd05..50958bbeb26a 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1478,14 +1478,31 @@ static int elf_read_build_id(Elf *elf, void *bf, size_t size)
1478 goto out; 1478 goto out;
1479 } 1479 }
1480 1480
1481 sec = elf_section_by_name(elf, &ehdr, &shdr, 1481 /*
1482 ".note.gnu.build-id", NULL); 1482 * Check following sections for notes:
1483 if (sec == NULL) { 1483 * '.note.gnu.build-id'
1484 * '.notes'
1485 * '.note' (VDSO specific)
1486 */
1487 do {
1488 sec = elf_section_by_name(elf, &ehdr, &shdr,
1489 ".note.gnu.build-id", NULL);
1490 if (sec)
1491 break;
1492
1484 sec = elf_section_by_name(elf, &ehdr, &shdr, 1493 sec = elf_section_by_name(elf, &ehdr, &shdr,
1485 ".notes", NULL); 1494 ".notes", NULL);
1486 if (sec == NULL) 1495 if (sec)
1487 goto out; 1496 break;
1488 } 1497
1498 sec = elf_section_by_name(elf, &ehdr, &shdr,
1499 ".note", NULL);
1500 if (sec)
1501 break;
1502
1503 return err;
1504
1505 } while (0);
1489 1506
1490 data = elf_getdata(sec, NULL); 1507 data = elf_getdata(sec, NULL);
1491 if (data == NULL) 1508 if (data == NULL)