aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/cpu/perf_event.c3
-rw-r--r--include/linux/perf_counter.h2
-rw-r--r--include/linux/perf_event.h2
-rw-r--r--tools/perf/.gitignore1
-rw-r--r--tools/perf/builtin-stat.c18
-rw-r--r--tools/perf/util/module.c96
-rw-r--r--tools/perf/util/parse-events.c49
-rw-r--r--tools/perf/util/symbol.c17
8 files changed, 119 insertions, 69 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index a3c7adb06b78..b5801c311846 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1790,6 +1790,9 @@ void smp_perf_pending_interrupt(struct pt_regs *regs)
1790void set_perf_event_pending(void) 1790void set_perf_event_pending(void)
1791{ 1791{
1792#ifdef CONFIG_X86_LOCAL_APIC 1792#ifdef CONFIG_X86_LOCAL_APIC
1793 if (!x86_pmu.apic || !x86_pmu_initialized())
1794 return;
1795
1793 apic->send_IPI_self(LOCAL_PENDING_VECTOR); 1796 apic->send_IPI_self(LOCAL_PENDING_VECTOR);
1794#endif 1797#endif
1795} 1798}
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h
index 368bd70f1d2d..7b7fbf433cff 100644
--- a/include/linux/perf_counter.h
+++ b/include/linux/perf_counter.h
@@ -361,7 +361,7 @@ enum perf_event_type {
361 * struct perf_event_header header; 361 * struct perf_event_header header;
362 * u32 pid, ppid; 362 * u32 pid, ppid;
363 * u32 tid, ptid; 363 * u32 tid, ptid;
364 * { u64 time; } && PERF_SAMPLE_TIME 364 * u64 time;
365 * }; 365 * };
366 */ 366 */
367 PERF_EVENT_FORK = 7, 367 PERF_EVENT_FORK = 7,
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index acefaf71e6dd..3a9d36d1e92a 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -357,7 +357,7 @@ enum perf_event_type {
357 * struct perf_event_header header; 357 * struct perf_event_header header;
358 * u32 pid, ppid; 358 * u32 pid, ppid;
359 * u32 tid, ptid; 359 * u32 tid, ptid;
360 * { u64 time; } && PERF_SAMPLE_TIME 360 * u64 time;
361 * }; 361 * };
362 */ 362 */
363 PERF_RECORD_FORK = 7, 363 PERF_RECORD_FORK = 7,
diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore
index d69a759a1046..0854f110bf7f 100644
--- a/tools/perf/.gitignore
+++ b/tools/perf/.gitignore
@@ -10,6 +10,7 @@ perf-stat
10perf-top 10perf-top
11perf*.1 11perf*.1
12perf*.xml 12perf*.xml
13perf*.html
13common-cmds.h 14common-cmds.h
14tags 15tags
15TAGS 16TAGS
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 16af2d82e858..e5f6ece65a13 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -338,14 +338,24 @@ static void nsec_printout(int counter, double avg)
338 338
339static void abs_printout(int counter, double avg) 339static void abs_printout(int counter, double avg)
340{ 340{
341 double total, ratio = 0.0;
342
341 fprintf(stderr, " %14.0f %-24s", avg, event_name(counter)); 343 fprintf(stderr, " %14.0f %-24s", avg, event_name(counter));
342 344
343 if (MATCH_EVENT(HARDWARE, HW_INSTRUCTIONS, counter)) { 345 if (MATCH_EVENT(HARDWARE, HW_INSTRUCTIONS, counter)) {
344 fprintf(stderr, " # %10.3f IPC ", 346 total = avg_stats(&runtime_cycles_stats);
345 avg / avg_stats(&runtime_cycles_stats)); 347
348 if (total)
349 ratio = avg / total;
350
351 fprintf(stderr, " # %10.3f IPC ", ratio);
346 } else { 352 } else {
347 fprintf(stderr, " # %10.3f M/sec", 353 total = avg_stats(&runtime_nsecs_stats);
348 1000.0 * avg / avg_stats(&runtime_nsecs_stats)); 354
355 if (total)
356 ratio = 1000.0 * avg / total;
357
358 fprintf(stderr, " # %10.3f M/sec", ratio);
349 } 359 }
350} 360}
351 361
diff --git a/tools/perf/util/module.c b/tools/perf/util/module.c
index 3d567fe59c79..0d8c85defcd2 100644
--- a/tools/perf/util/module.c
+++ b/tools/perf/util/module.c
@@ -4,6 +4,7 @@
4#include "module.h" 4#include "module.h"
5 5
6#include <libelf.h> 6#include <libelf.h>
7#include <libgen.h>
7#include <gelf.h> 8#include <gelf.h>
8#include <elf.h> 9#include <elf.h>
9#include <dirent.h> 10#include <dirent.h>
@@ -409,35 +410,40 @@ out_failure:
409static int mod_dso__load_module_paths(struct mod_dso *self) 410static int mod_dso__load_module_paths(struct mod_dso *self)
410{ 411{
411 struct utsname uts; 412 struct utsname uts;
412 int count = 0, len; 413 int count = 0, len, err = -1;
413 char *line = NULL; 414 char *line = NULL;
414 FILE *file; 415 FILE *file;
415 char *path; 416 char *dpath, *dir;
416 size_t n; 417 size_t n;
417 418
418 if (uname(&uts) < 0) 419 if (uname(&uts) < 0)
419 goto out_failure; 420 return err;
420 421
421 len = strlen("/lib/modules/"); 422 len = strlen("/lib/modules/");
422 len += strlen(uts.release); 423 len += strlen(uts.release);
423 len += strlen("/modules.dep"); 424 len += strlen("/modules.dep");
424 425
425 path = calloc(1, len); 426 dpath = calloc(1, len + 1);
426 if (path == NULL) 427 if (dpath == NULL)
427 goto out_failure; 428 return err;
428 429
429 strcat(path, "/lib/modules/"); 430 strcat(dpath, "/lib/modules/");
430 strcat(path, uts.release); 431 strcat(dpath, uts.release);
431 strcat(path, "/modules.dep"); 432 strcat(dpath, "/modules.dep");
432 433
433 file = fopen(path, "r"); 434 file = fopen(dpath, "r");
434 free(path);
435 if (file == NULL) 435 if (file == NULL)
436 goto out_failure; 436 goto out_failure;
437 437
438 dir = dirname(dpath);
439 if (!dir)
440 goto out_failure;
441 strcat(dir, "/");
442
438 while (!feof(file)) { 443 while (!feof(file)) {
439 char *name, *tmp;
440 struct module *module; 444 struct module *module;
445 char *name, *path, *tmp;
446 FILE *modfile;
441 int line_len; 447 int line_len;
442 448
443 line_len = getline(&line, &n, file); 449 line_len = getline(&line, &n, file);
@@ -445,17 +451,41 @@ static int mod_dso__load_module_paths(struct mod_dso *self)
445 break; 451 break;
446 452
447 if (!line) 453 if (!line)
448 goto out_failure; 454 break;
449 455
450 line[--line_len] = '\0'; /* \n */ 456 line[--line_len] = '\0'; /* \n */
451 457
452 path = strtok(line, ":"); 458 path = strchr(line, ':');
459 if (!path)
460 break;
461 *path = '\0';
462
463 path = strdup(line);
453 if (!path) 464 if (!path)
454 goto out_failure; 465 break;
466
467 if (!strstr(path, dir)) {
468 if (strncmp(path, "kernel/", 7))
469 break;
470
471 free(path);
472 path = calloc(1, strlen(dir) + strlen(line) + 1);
473 if (!path)
474 break;
475 strcat(path, dir);
476 strcat(path, line);
477 }
478
479 modfile = fopen(path, "r");
480 if (modfile == NULL)
481 break;
482 fclose(modfile);
455 483
456 name = strdup(path); 484 name = strdup(path);
457 name = strtok(name, "/"); 485 if (!name)
486 break;
458 487
488 name = strtok(name, "/");
459 tmp = name; 489 tmp = name;
460 490
461 while (tmp) { 491 while (tmp) {
@@ -463,26 +493,25 @@ static int mod_dso__load_module_paths(struct mod_dso *self)
463 if (tmp) 493 if (tmp)
464 name = tmp; 494 name = tmp;
465 } 495 }
496
466 name = strsep(&name, "."); 497 name = strsep(&name, ".");
498 if (!name)
499 break;
467 500
468 /* Quirk: replace '-' with '_' in sound modules */ 501 /* Quirk: replace '-' with '_' in all modules */
469 for (len = strlen(name); len; len--) { 502 for (len = strlen(name); len; len--) {
470 if (*(name+len) == '-') 503 if (*(name+len) == '-')
471 *(name+len) = '_'; 504 *(name+len) = '_';
472 } 505 }
473 506
474 module = module__new(name, path); 507 module = module__new(name, path);
475 if (!module) { 508 if (!module)
476 fprintf(stderr, "load_module_paths: allocation error\n"); 509 break;
477 goto out_failure;
478 }
479 mod_dso__insert_module(self, module); 510 mod_dso__insert_module(self, module);
480 511
481 module->sections = sec_dso__new_dso("sections"); 512 module->sections = sec_dso__new_dso("sections");
482 if (!module->sections) { 513 if (!module->sections)
483 fprintf(stderr, "load_module_paths: allocation error\n"); 514 break;
484 goto out_failure;
485 }
486 515
487 module->active = mod_dso__load_sections(module); 516 module->active = mod_dso__load_sections(module);
488 517
@@ -490,13 +519,20 @@ static int mod_dso__load_module_paths(struct mod_dso *self)
490 count++; 519 count++;
491 } 520 }
492 521
493 free(line); 522 if (feof(file))
494 fclose(file); 523 err = count;
495 524 else
496 return count; 525 fprintf(stderr, "load_module_paths: modules.dep parsing failure!\n");
497 526
498out_failure: 527out_failure:
499 return -1; 528 if (dpath)
529 free(dpath);
530 if (file)
531 fclose(file);
532 if (line)
533 free(line);
534
535 return err;
500} 536}
501 537
502int mod_dso__load_modules(struct mod_dso *dso) 538int mod_dso__load_modules(struct mod_dso *dso)
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 13ab4b842d49..87c424de79ee 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -165,33 +165,31 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
165 DIR *sys_dir, *evt_dir; 165 DIR *sys_dir, *evt_dir;
166 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 166 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
167 char id_buf[4]; 167 char id_buf[4];
168 int sys_dir_fd, fd; 168 int fd;
169 u64 id; 169 u64 id;
170 char evt_path[MAXPATHLEN]; 170 char evt_path[MAXPATHLEN];
171 char dir_path[MAXPATHLEN];
171 172
172 if (valid_debugfs_mount(debugfs_path)) 173 if (valid_debugfs_mount(debugfs_path))
173 return NULL; 174 return NULL;
174 175
175 sys_dir = opendir(debugfs_path); 176 sys_dir = opendir(debugfs_path);
176 if (!sys_dir) 177 if (!sys_dir)
177 goto cleanup; 178 return NULL;
178 sys_dir_fd = dirfd(sys_dir);
179 179
180 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 180 for_each_subsystem(sys_dir, sys_dirent, sys_next) {
181 int dfd = openat(sys_dir_fd, sys_dirent.d_name, 181
182 O_RDONLY|O_DIRECTORY), evt_dir_fd; 182 snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
183 if (dfd == -1) 183 sys_dirent.d_name);
184 continue; 184 evt_dir = opendir(dir_path);
185 evt_dir = fdopendir(dfd); 185 if (!evt_dir)
186 if (!evt_dir) {
187 close(dfd);
188 continue; 186 continue;
189 } 187
190 evt_dir_fd = dirfd(evt_dir);
191 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 188 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
192 snprintf(evt_path, MAXPATHLEN, "%s/id", 189
190 snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path,
193 evt_dirent.d_name); 191 evt_dirent.d_name);
194 fd = openat(evt_dir_fd, evt_path, O_RDONLY); 192 fd = open(evt_path, O_RDONLY);
195 if (fd < 0) 193 if (fd < 0)
196 continue; 194 continue;
197 if (read(fd, id_buf, sizeof(id_buf)) < 0) { 195 if (read(fd, id_buf, sizeof(id_buf)) < 0) {
@@ -225,7 +223,6 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
225 closedir(evt_dir); 223 closedir(evt_dir);
226 } 224 }
227 225
228cleanup:
229 closedir(sys_dir); 226 closedir(sys_dir);
230 return NULL; 227 return NULL;
231} 228}
@@ -761,28 +758,24 @@ static void print_tracepoint_events(void)
761{ 758{
762 DIR *sys_dir, *evt_dir; 759 DIR *sys_dir, *evt_dir;
763 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 760 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
764 int sys_dir_fd;
765 char evt_path[MAXPATHLEN]; 761 char evt_path[MAXPATHLEN];
762 char dir_path[MAXPATHLEN];
766 763
767 if (valid_debugfs_mount(debugfs_path)) 764 if (valid_debugfs_mount(debugfs_path))
768 return; 765 return;
769 766
770 sys_dir = opendir(debugfs_path); 767 sys_dir = opendir(debugfs_path);
771 if (!sys_dir) 768 if (!sys_dir)
772 goto cleanup; 769 return;
773 sys_dir_fd = dirfd(sys_dir);
774 770
775 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 771 for_each_subsystem(sys_dir, sys_dirent, sys_next) {
776 int dfd = openat(sys_dir_fd, sys_dirent.d_name, 772
777 O_RDONLY|O_DIRECTORY), evt_dir_fd; 773 snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
778 if (dfd == -1) 774 sys_dirent.d_name);
779 continue; 775 evt_dir = opendir(dir_path);
780 evt_dir = fdopendir(dfd); 776 if (!evt_dir)
781 if (!evt_dir) {
782 close(dfd);
783 continue; 777 continue;
784 } 778
785 evt_dir_fd = dirfd(evt_dir);
786 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 779 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
787 snprintf(evt_path, MAXPATHLEN, "%s:%s", 780 snprintf(evt_path, MAXPATHLEN, "%s:%s",
788 sys_dirent.d_name, evt_dirent.d_name); 781 sys_dirent.d_name, evt_dirent.d_name);
@@ -791,8 +784,6 @@ static void print_tracepoint_events(void)
791 } 784 }
792 closedir(evt_dir); 785 closedir(evt_dir);
793 } 786 }
794
795cleanup:
796 closedir(sys_dir); 787 closedir(sys_dir);
797} 788}
798 789
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index fd3d9c8e90fc..559fb06210f5 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -833,7 +833,7 @@ int dso__load_modules(struct dso *self, symbol_filter_t filter, int v)
833 struct mod_dso *mods = mod_dso__new_dso("modules"); 833 struct mod_dso *mods = mod_dso__new_dso("modules");
834 struct module *pos; 834 struct module *pos;
835 struct rb_node *next; 835 struct rb_node *next;
836 int err; 836 int err, count = 0;
837 837
838 err = mod_dso__load_modules(mods); 838 err = mod_dso__load_modules(mods);
839 839
@@ -852,14 +852,16 @@ int dso__load_modules(struct dso *self, symbol_filter_t filter, int v)
852 break; 852 break;
853 853
854 next = rb_next(&pos->rb_node); 854 next = rb_next(&pos->rb_node);
855 count += err;
855 } 856 }
856 857
857 if (err < 0) { 858 if (err < 0) {
858 mod_dso__delete_modules(mods); 859 mod_dso__delete_modules(mods);
859 mod_dso__delete_self(mods); 860 mod_dso__delete_self(mods);
861 return err;
860 } 862 }
861 863
862 return err; 864 return count;
863} 865}
864 866
865static inline void dso__fill_symbol_holes(struct dso *self) 867static inline void dso__fill_symbol_holes(struct dso *self)
@@ -913,8 +915,15 @@ int dso__load_kernel(struct dso *self, const char *vmlinux,
913 915
914 if (vmlinux) { 916 if (vmlinux) {
915 err = dso__load_vmlinux(self, vmlinux, filter, v); 917 err = dso__load_vmlinux(self, vmlinux, filter, v);
916 if (err > 0 && use_modules) 918 if (err > 0 && use_modules) {
917 err = dso__load_modules(self, filter, v); 919 int syms = dso__load_modules(self, filter, v);
920
921 if (syms < 0) {
922 fprintf(stderr, "dso__load_modules failed!\n");
923 return syms;
924 }
925 err += syms;
926 }
918 } 927 }
919 928
920 if (err <= 0) 929 if (err <= 0)