From 71ff824a60a7b0d9d0746e6e237fe4735077e5b4 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 21 May 2015 01:03:39 +0900 Subject: [PATCH] perf tools: Fix dso__data_read_offset() file opening When dso__data_read_offset/addr() is called without prior dso__data_fd() (or other functions which call it internally), it failed to open dso in data_file_size() since its binary type was not identified. However calling dso__data_fd() in dso__data_read_offset() will hurt performance as it grabs a global lock everytime. So factor out the loop on the binary type in dso__data_fd(), and call it from both. Reported-by: Adrian Hunter Signed-off-by: Namhyung Kim Acked-by: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1432137821-10853-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dso.c | 59 ++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 1b96c8d..516e0c2 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -440,15 +440,7 @@ void dso__data_close(struct dso *dso) pthread_mutex_unlock(&dso__data_open_lock); } -/** - * dso__data_fd - Get dso's data file descriptor - * @dso: dso object - * @machine: machine object - * - * External interface to find dso's file, open it and - * returns file descriptor. - */ -int dso__data_fd(struct dso *dso, struct machine *machine) +static void try_to_open_dso(struct dso *dso, struct machine *machine) { enum dso_binary_type binary_type_data[] = { DSO_BINARY_TYPE__BUILD_ID_CACHE, @@ -457,13 +449,8 @@ int dso__data_fd(struct dso *dso, struct machine *machine) }; int i = 0; - if (dso->data.status == DSO_DATA_STATUS_ERROR) - return -1; - - pthread_mutex_lock(&dso__data_open_lock); - if (dso->data.fd >= 0) - goto out; + return; if (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND) { dso->data.fd = open_dso(dso, machine); @@ -483,8 +470,25 @@ out: dso->data.status = DSO_DATA_STATUS_OK; else dso->data.status = DSO_DATA_STATUS_ERROR; +} + +/** + * dso__data_fd - Get dso's data file descriptor + * @dso: dso object + * @machine: machine object + * + * External interface to find dso's file, open it and + * returns file descriptor. + */ +int dso__data_fd(struct dso *dso, struct machine *machine) +{ + if (dso->data.status == DSO_DATA_STATUS_ERROR) + return -1; + pthread_mutex_lock(&dso__data_open_lock); + try_to_open_dso(dso, machine); pthread_mutex_unlock(&dso__data_open_lock); + return dso->data.fd; } @@ -609,13 +613,12 @@ dso_cache__read(struct dso *dso, struct machine *machine, * dso->data.fd might be closed if other thread opened another * file (dso) due to open file limit (RLIMIT_NOFILE). */ + try_to_open_dso(dso, machine); + if (dso->data.fd < 0) { - dso->data.fd = open_dso(dso, machine); - if (dso->data.fd < 0) { - ret = -errno; - dso->data.status = DSO_DATA_STATUS_ERROR; - break; - } + ret = -errno; + dso->data.status = DSO_DATA_STATUS_ERROR; + break; } cache_offset = offset & DSO__DATA_CACHE_MASK; @@ -702,19 +705,21 @@ static int data_file_size(struct dso *dso, struct machine *machine) if (dso->data.file_size) return 0; + if (dso->data.status == DSO_DATA_STATUS_ERROR) + return -1; + pthread_mutex_lock(&dso__data_open_lock); /* * dso->data.fd might be closed if other thread opened another * file (dso) due to open file limit (RLIMIT_NOFILE). */ + try_to_open_dso(dso, machine); + if (dso->data.fd < 0) { - dso->data.fd = open_dso(dso, machine); - if (dso->data.fd < 0) { - ret = -errno; - dso->data.status = DSO_DATA_STATUS_ERROR; - goto out; - } + ret = -errno; + dso->data.status = DSO_DATA_STATUS_ERROR; + goto out; } if (fstat(dso->data.fd, &st) < 0) { -- 2.7.4