Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
perf tools: Dont use openat()
perf tools: Fix buffer allocation
perf tools: .gitignore += perf*.html
perf tools: Handle relative paths while loading module symbols
perf tools: Fix module symbol loading bug
perf_event, x86: Fix 'perf sched record' crashing the machine
perf_event: Update PERF_EVENT_FORK header definition
perf stat: Fix zero total printouts

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