diff options
author | Namhyung Kim <namhyung@kernel.org> | 2015-05-21 01:03:41 +0900 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-05-27 12:21:44 -0300 |
commit | 4bb11d012ab248d0e383008d725be0d26a74fac2 (patch) | |
tree | 56d8b7f278f2dad61c936b981b2844249e48c129 /tools/perf/util/dso.c | |
parent | e840238d7c6afcde0f6402aac3a74723ee9c448f (diff) | |
download | op-kernel-dev-4bb11d012ab248d0e383008d725be0d26a74fac2.zip op-kernel-dev-4bb11d012ab248d0e383008d725be0d26a74fac2.tar.gz |
perf tools: Add dso__data_get/put_fd()
Using dso__data_fd() in multi-thread environment is not safe since
returned fd can be closed and/or reused anytime.
So convert it to the dso__data_get/put_fd() pair to protect the access
with lock.
The original dso__data_fd() is deprecated and kept only for testing.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1432137821-10853-3-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/dso.c')
-rw-r--r-- | tools/perf/util/dso.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index e95e850..7e11a70 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -473,25 +473,35 @@ out: } /** - * dso__data_fd - Get dso's data file descriptor + * dso__data_get_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. + * returns file descriptor. It should be paired with + * dso__data_put_fd() if it returns non-negative value. */ -int dso__data_fd(struct dso *dso, struct machine *machine) +int dso__data_get_fd(struct dso *dso, struct machine *machine) { if (dso->data.status == DSO_DATA_STATUS_ERROR) return -1; - pthread_mutex_lock(&dso__data_open_lock); + if (pthread_mutex_lock(&dso__data_open_lock) < 0) + return -1; + try_to_open_dso(dso, machine); - pthread_mutex_unlock(&dso__data_open_lock); + + if (dso->data.fd < 0) + pthread_mutex_unlock(&dso__data_open_lock); return dso->data.fd; } +void dso__data_put_fd(struct dso *dso __maybe_unused) +{ + pthread_mutex_unlock(&dso__data_open_lock); +} + bool dso__data_status_seen(struct dso *dso, enum dso_data_status_seen by) { u32 flag = 1 << by; @@ -1199,12 +1209,15 @@ size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp) enum dso_type dso__type(struct dso *dso, struct machine *machine) { int fd; + enum dso_type type = DSO__TYPE_UNKNOWN; - fd = dso__data_fd(dso, machine); - if (fd < 0) - return DSO__TYPE_UNKNOWN; + fd = dso__data_get_fd(dso, machine); + if (fd >= 0) { + type = dso__type_fd(fd); + dso__data_put_fd(dso); + } - return dso__type_fd(fd); + return type; } int dso__strerror_load(struct dso *dso, char *buf, size_t buflen) |