aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2009-09-04 15:39:51 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-04 15:50:17 -0400
commit6b58e7f146f8d79c08f62087f928e1f01747de71 (patch)
tree98669b06646894d1dd8f85c1ae932aa6a8fb42de /tools/perf/util/parse-events.c
parent849abde92bd3314a4894f2b4f70b30c2accf8653 (diff)
perf tools: Avoid unnecessary work in directory lookups
This patch improves some (common) inefficiencies in the handling of directory lookups: - not using the d_type information returned by the kernel - constructing (absolute) paths for file operation even though directory-relative operations using the *at functions is possible There are more places to fix but this is a start. Signed-off-by: Ulrich Drepper <drepper@redhat.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Mike Galbraith <efault@gmx.de> LKML-Reference: <20090904193951.GB6186@ghostprotocols.net> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c68
1 files changed, 37 insertions, 31 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 89d46c99bc9c..52219d5a507b 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1,14 +1,12 @@
1 1
2#include "../perf.h"
3#include "util.h" 2#include "util.h"
3#include "../perf.h"
4#include "parse-options.h" 4#include "parse-options.h"
5#include "parse-events.h" 5#include "parse-events.h"
6#include "exec_cmd.h" 6#include "exec_cmd.h"
7#include "string.h" 7#include "string.h"
8#include "cache.h" 8#include "cache.h"
9 9
10extern char *strcasestr(const char *haystack, const char *needle);
11
12int nr_counters; 10int nr_counters;
13 11
14struct perf_counter_attr attrs[MAX_COUNTERS]; 12struct perf_counter_attr attrs[MAX_COUNTERS];
@@ -113,11 +111,9 @@ static unsigned long hw_cache_stat[C(MAX)] = {
113 [C(BPU)] = (CACHE_READ), 111 [C(BPU)] = (CACHE_READ),
114}; 112};
115 113
116#define for_each_subsystem(sys_dir, sys_dirent, sys_next, file, st) \ 114#define for_each_subsystem(sys_dir, sys_dirent, sys_next) \
117 while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 115 while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \
118 if (snprintf(file, MAXPATHLEN, "%s/%s", debugfs_path, \ 116 if (sys_dirent.d_type == DT_DIR && \
119 sys_dirent.d_name) && \
120 (!stat(file, &st)) && (S_ISDIR(st.st_mode)) && \
121 (strcmp(sys_dirent.d_name, ".")) && \ 117 (strcmp(sys_dirent.d_name, ".")) && \
122 (strcmp(sys_dirent.d_name, ".."))) 118 (strcmp(sys_dirent.d_name, "..")))
123 119
@@ -136,11 +132,9 @@ static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
136 return 0; 132 return 0;
137} 133}
138 134
139#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, file, st) \ 135#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \
140 while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 136 while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \
141 if (snprintf(file, MAXPATHLEN, "%s/%s/%s", debugfs_path, \ 137 if (evt_dirent.d_type == DT_DIR && \
142 sys_dirent.d_name, evt_dirent.d_name) && \
143 (!stat(file, &st)) && (S_ISDIR(st.st_mode)) && \
144 (strcmp(evt_dirent.d_name, ".")) && \ 138 (strcmp(evt_dirent.d_name, ".")) && \
145 (strcmp(evt_dirent.d_name, "..")) && \ 139 (strcmp(evt_dirent.d_name, "..")) && \
146 (!tp_event_has_id(&sys_dirent, &evt_dirent))) 140 (!tp_event_has_id(&sys_dirent, &evt_dirent)))
@@ -163,9 +157,8 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
163 struct tracepoint_path *path = NULL; 157 struct tracepoint_path *path = NULL;
164 DIR *sys_dir, *evt_dir; 158 DIR *sys_dir, *evt_dir;
165 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 159 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
166 struct stat st;
167 char id_buf[4]; 160 char id_buf[4];
168 int fd; 161 int sys_dir_fd, fd;
169 u64 id; 162 u64 id;
170 char evt_path[MAXPATHLEN]; 163 char evt_path[MAXPATHLEN];
171 164
@@ -175,17 +168,23 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
175 sys_dir = opendir(debugfs_path); 168 sys_dir = opendir(debugfs_path);
176 if (!sys_dir) 169 if (!sys_dir)
177 goto cleanup; 170 goto cleanup;
178 171 sys_dir_fd = dirfd(sys_dir);
179 for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) { 172
180 evt_dir = opendir(evt_path); 173 for_each_subsystem(sys_dir, sys_dirent, sys_next) {
181 if (!evt_dir) 174 int dfd = openat(sys_dir_fd, sys_dirent.d_name,
182 goto cleanup; 175 O_RDONLY|O_DIRECTORY), evt_dir_fd;
183 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, 176 if (dfd == -1)
184 evt_path, st) { 177 continue;
185 snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", 178 evt_dir = fdopendir(dfd);
186 debugfs_path, sys_dirent.d_name, 179 if (!evt_dir) {
180 close(dfd);
181 continue;
182 }
183 evt_dir_fd = dirfd(evt_dir);
184 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
185 snprintf(evt_path, MAXPATHLEN, "%s/id",
187 evt_dirent.d_name); 186 evt_dirent.d_name);
188 fd = open(evt_path, O_RDONLY); 187 fd = openat(evt_dir_fd, evt_path, O_RDONLY);
189 if (fd < 0) 188 if (fd < 0)
190 continue; 189 continue;
191 if (read(fd, id_buf, sizeof(id_buf)) < 0) { 190 if (read(fd, id_buf, sizeof(id_buf)) < 0) {
@@ -629,7 +628,7 @@ static void print_tracepoint_events(void)
629{ 628{
630 DIR *sys_dir, *evt_dir; 629 DIR *sys_dir, *evt_dir;
631 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 630 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
632 struct stat st; 631 int sys_dir_fd;
633 char evt_path[MAXPATHLEN]; 632 char evt_path[MAXPATHLEN];
634 633
635 if (valid_debugfs_mount(debugfs_path)) 634 if (valid_debugfs_mount(debugfs_path))
@@ -638,13 +637,20 @@ static void print_tracepoint_events(void)
638 sys_dir = opendir(debugfs_path); 637 sys_dir = opendir(debugfs_path);
639 if (!sys_dir) 638 if (!sys_dir)
640 goto cleanup; 639 goto cleanup;
641 640 sys_dir_fd = dirfd(sys_dir);
642 for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) { 641
643 evt_dir = opendir(evt_path); 642 for_each_subsystem(sys_dir, sys_dirent, sys_next) {
644 if (!evt_dir) 643 int dfd = openat(sys_dir_fd, sys_dirent.d_name,
645 goto cleanup; 644 O_RDONLY|O_DIRECTORY), evt_dir_fd;
646 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, 645 if (dfd == -1)
647 evt_path, st) { 646 continue;
647 evt_dir = fdopendir(dfd);
648 if (!evt_dir) {
649 close(dfd);
650 continue;
651 }
652 evt_dir_fd = dirfd(evt_dir);
653 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
648 snprintf(evt_path, MAXPATHLEN, "%s:%s", 654 snprintf(evt_path, MAXPATHLEN, "%s:%s",
649 sys_dirent.d_name, evt_dirent.d_name); 655 sys_dirent.d_name, evt_dirent.d_name);
650 fprintf(stderr, " %-40s [%s]\n", evt_path, 656 fprintf(stderr, " %-40s [%s]\n", evt_path,