diff options
author | Jiri Olsa <jolsa@kernel.org> | 2014-05-12 08:43:53 -0400 |
---|---|---|
committer | Jiri Olsa <jolsa@kernel.org> | 2014-06-12 10:53:22 -0400 |
commit | 4ebbcb84b19b8472fb5b9c8be89b3d0ea17c902e (patch) | |
tree | c0f3dad6de3aa5ead4b31c59e06e83e8ea81364e /tools | |
parent | 822c45db6398a69879b0539f0819de02b813493c (diff) |
perf tests: Add test for caching dso file descriptors
Adding test that setup test_dso_data__fd_limit and test
dso data file descriptors are cached appropriately.
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1401892622-30848-13-git-send-email-jolsa@kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/tests/builtin-test.c | 6 | ||||
-rw-r--r-- | tools/perf/tests/dso-data.c | 135 | ||||
-rw-r--r-- | tools/perf/tests/tests.h | 1 |
3 files changed, 138 insertions, 4 deletions
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 9677a5c6a366..b8a63583566f 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c | |||
@@ -52,10 +52,14 @@ static struct test { | |||
52 | .func = test__pmu, | 52 | .func = test__pmu, |
53 | }, | 53 | }, |
54 | { | 54 | { |
55 | .desc = "Test dso data interface", | 55 | .desc = "Test dso data read", |
56 | .func = test__dso_data, | 56 | .func = test__dso_data, |
57 | }, | 57 | }, |
58 | { | 58 | { |
59 | .desc = "Test dso data cache", | ||
60 | .func = test__dso_data_cache, | ||
61 | }, | ||
62 | { | ||
59 | .desc = "roundtrip evsel->name check", | 63 | .desc = "roundtrip evsel->name check", |
60 | .func = test__perf_evsel__roundtrip_name_test, | 64 | .func = test__perf_evsel__roundtrip_name_test, |
61 | }, | 65 | }, |
diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index 738438196d9a..2d30014d716b 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c | |||
@@ -1,11 +1,12 @@ | |||
1 | #include "util.h" | ||
2 | |||
3 | #include <stdlib.h> | 1 | #include <stdlib.h> |
4 | #include <linux/types.h> | 2 | #include <linux/types.h> |
5 | #include <sys/stat.h> | 3 | #include <sys/stat.h> |
6 | #include <fcntl.h> | 4 | #include <fcntl.h> |
7 | #include <string.h> | 5 | #include <string.h> |
8 | 6 | #include <sys/time.h> | |
7 | #include <sys/resource.h> | ||
8 | #include <api/fs/fs.h> | ||
9 | #include "util.h" | ||
9 | #include "machine.h" | 10 | #include "machine.h" |
10 | #include "symbol.h" | 11 | #include "symbol.h" |
11 | #include "tests.h" | 12 | #include "tests.h" |
@@ -154,3 +155,131 @@ int test__dso_data(void) | |||
154 | unlink(file); | 155 | unlink(file); |
155 | return 0; | 156 | return 0; |
156 | } | 157 | } |
158 | |||
159 | static long open_files_cnt(void) | ||
160 | { | ||
161 | char path[PATH_MAX]; | ||
162 | struct dirent *dent; | ||
163 | DIR *dir; | ||
164 | long nr = 0; | ||
165 | |||
166 | scnprintf(path, PATH_MAX, "%s/self/fd", procfs__mountpoint()); | ||
167 | pr_debug("fd path: %s\n", path); | ||
168 | |||
169 | dir = opendir(path); | ||
170 | TEST_ASSERT_VAL("failed to open fd directory", dir); | ||
171 | |||
172 | while ((dent = readdir(dir)) != NULL) { | ||
173 | if (!strcmp(dent->d_name, ".") || | ||
174 | !strcmp(dent->d_name, "..")) | ||
175 | continue; | ||
176 | |||
177 | nr++; | ||
178 | } | ||
179 | |||
180 | closedir(dir); | ||
181 | return nr - 1; | ||
182 | } | ||
183 | |||
184 | static struct dso **dsos; | ||
185 | |||
186 | static int dsos__create(int cnt, int size) | ||
187 | { | ||
188 | int i; | ||
189 | |||
190 | dsos = malloc(sizeof(dsos) * cnt); | ||
191 | TEST_ASSERT_VAL("failed to alloc dsos array", dsos); | ||
192 | |||
193 | for (i = 0; i < cnt; i++) { | ||
194 | char *file; | ||
195 | |||
196 | file = test_file(size); | ||
197 | TEST_ASSERT_VAL("failed to get dso file", file); | ||
198 | |||
199 | dsos[i] = dso__new(file); | ||
200 | TEST_ASSERT_VAL("failed to get dso", dsos[i]); | ||
201 | } | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | static void dsos__delete(int cnt) | ||
207 | { | ||
208 | int i; | ||
209 | |||
210 | for (i = 0; i < cnt; i++) { | ||
211 | struct dso *dso = dsos[i]; | ||
212 | |||
213 | unlink(dso->name); | ||
214 | dso__delete(dso); | ||
215 | } | ||
216 | |||
217 | free(dsos); | ||
218 | } | ||
219 | |||
220 | static int set_fd_limit(int n) | ||
221 | { | ||
222 | struct rlimit rlim; | ||
223 | |||
224 | if (getrlimit(RLIMIT_NOFILE, &rlim)) | ||
225 | return -1; | ||
226 | |||
227 | pr_debug("file limit %ld, new %d\n", (long) rlim.rlim_cur, n); | ||
228 | |||
229 | rlim.rlim_cur = n; | ||
230 | return setrlimit(RLIMIT_NOFILE, &rlim); | ||
231 | } | ||
232 | |||
233 | int test__dso_data_cache(void) | ||
234 | { | ||
235 | struct machine machine; | ||
236 | long nr_end, nr = open_files_cnt(); | ||
237 | int dso_cnt, limit, i, fd; | ||
238 | |||
239 | memset(&machine, 0, sizeof(machine)); | ||
240 | |||
241 | /* set as system limit */ | ||
242 | limit = nr * 4; | ||
243 | TEST_ASSERT_VAL("failed to set file limit", !set_fd_limit(limit)); | ||
244 | |||
245 | /* and this is now our dso open FDs limit + 1 extra */ | ||
246 | dso_cnt = limit / 2 + 1; | ||
247 | TEST_ASSERT_VAL("failed to create dsos\n", | ||
248 | !dsos__create(dso_cnt, TEST_FILE_SIZE)); | ||
249 | |||
250 | for (i = 0; i < (dso_cnt - 1); i++) { | ||
251 | struct dso *dso = dsos[i]; | ||
252 | |||
253 | /* | ||
254 | * Open dsos via dso__data_fd or dso__data_read_offset. | ||
255 | * Both opens the data file and keep it open. | ||
256 | */ | ||
257 | if (i % 2) { | ||
258 | fd = dso__data_fd(dso, &machine); | ||
259 | TEST_ASSERT_VAL("failed to get fd", fd > 0); | ||
260 | } else { | ||
261 | #define BUFSIZE 10 | ||
262 | u8 buf[BUFSIZE]; | ||
263 | ssize_t n; | ||
264 | |||
265 | n = dso__data_read_offset(dso, &machine, 0, buf, BUFSIZE); | ||
266 | TEST_ASSERT_VAL("failed to read dso", n == BUFSIZE); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | /* open +1 dso over the allowed limit */ | ||
271 | fd = dso__data_fd(dsos[i], &machine); | ||
272 | TEST_ASSERT_VAL("failed to get fd", fd > 0); | ||
273 | |||
274 | /* should force the first one to be closed */ | ||
275 | TEST_ASSERT_VAL("failed to close dsos[0]", dsos[0]->data.fd == -1); | ||
276 | |||
277 | /* cleanup everything */ | ||
278 | dsos__delete(dso_cnt); | ||
279 | |||
280 | /* Make sure we did not leak any file descriptor. */ | ||
281 | nr_end = open_files_cnt(); | ||
282 | pr_debug("nr start %ld, nr stop %ld\n", nr, nr_end); | ||
283 | TEST_ASSERT_VAL("failed leadking files", nr == nr_end); | ||
284 | return 0; | ||
285 | } | ||
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 022bb68fd9c7..ccc4deb2d963 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h | |||
@@ -28,6 +28,7 @@ int test__syscall_open_tp_fields(void); | |||
28 | int test__pmu(void); | 28 | int test__pmu(void); |
29 | int test__attr(void); | 29 | int test__attr(void); |
30 | int test__dso_data(void); | 30 | int test__dso_data(void); |
31 | int test__dso_data_cache(void); | ||
31 | int test__parse_events(void); | 32 | int test__parse_events(void); |
32 | int test__hists_link(void); | 33 | int test__hists_link(void); |
33 | int test__python_use(void); | 34 | int test__python_use(void); |