diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-06-01 21:40:01 +0300 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-06-08 16:31:40 +0300 |
commit | e88078442232f3bbcb4ff1d24b3f9ab3dca472b9 (patch) | |
tree | d755616b5eb4d95607e4d75f36f221b9e7de4972 /tools/perf/util/vdso.c | |
parent | 9f2de31542f1ac38a15117f90ee6b8449951d86e (diff) | |
download | linux-e88078442232f3bbcb4ff1d24b3f9ab3dca472b9.tar.xz |
perf tools: Protect accesses the dso rbtrees/lists with a rw lock
To allow concurrent access, next step: refcount struct dso instances, so
that we can ditch unused them when the last map pointing to it goes
away.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/n/tip-yk1k08etpd2aoe3tnrf0oizn@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/vdso.c')
-rw-r--r-- | tools/perf/util/vdso.c | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 2e8f6886ca72..c646c74c34f8 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -120,14 +120,14 @@ void machine__exit_vdso(struct machine *machine) zfree(&machine->vdso_info); } -static struct dso *machine__addnew_vdso(struct machine *machine, const char *short_name, - const char *long_name) +static struct dso *__machine__addnew_vdso(struct machine *machine, const char *short_name, + const char *long_name) { struct dso *dso; dso = dso__new(short_name); if (dso != NULL) { - dsos__add(&machine->dsos, dso); + __dsos__add(&machine->dsos, dso); dso__set_long_name(dso, long_name, false); } @@ -230,27 +230,31 @@ static const char *vdso__get_compat_file(struct vdso_file *vdso_file) return vdso_file->temp_file_name; } -static struct dso *vdso__findnew_compat(struct machine *machine, - struct vdso_file *vdso_file) +static struct dso *__machine__findnew_compat(struct machine *machine, + struct vdso_file *vdso_file) { const char *file_name; struct dso *dso; - dso = dsos__find(&machine->dsos, vdso_file->dso_name, true); + pthread_rwlock_wrlock(&machine->dsos.lock); + dso = __dsos__find(&machine->dsos, vdso_file->dso_name, true); if (dso) - return dso; + goto out_unlock; file_name = vdso__get_compat_file(vdso_file); if (!file_name) - return NULL; + goto out_unlock; - return machine__addnew_vdso(machine, vdso_file->dso_name, file_name); + dso = __machine__addnew_vdso(machine, vdso_file->dso_name, file_name); +out_unlock: + pthread_rwlock_unlock(&machine->dsos.lock); + return dso; } -static int machine__findnew_vdso_compat(struct machine *machine, - struct thread *thread, - struct vdso_info *vdso_info, - struct dso **dso) +static int __machine__findnew_vdso_compat(struct machine *machine, + struct thread *thread, + struct vdso_info *vdso_info, + struct dso **dso) { enum dso_type dso_type; @@ -267,10 +271,10 @@ static int machine__findnew_vdso_compat(struct machine *machine, switch (dso_type) { case DSO__TYPE_32BIT: - *dso = vdso__findnew_compat(machine, &vdso_info->vdso32); + *dso = __machine__findnew_compat(machine, &vdso_info->vdso32); return 1; case DSO__TYPE_X32BIT: - *dso = vdso__findnew_compat(machine, &vdso_info->vdsox32); + *dso = __machine__findnew_compat(machine, &vdso_info->vdsox32); return 1; case DSO__TYPE_UNKNOWN: case DSO__TYPE_64BIT: @@ -285,31 +289,32 @@ struct dso *machine__findnew_vdso(struct machine *machine, struct thread *thread __maybe_unused) { struct vdso_info *vdso_info; - struct dso *dso; + struct dso *dso = NULL; + pthread_rwlock_wrlock(&machine->dsos.lock); if (!machine->vdso_info) machine->vdso_info = vdso_info__new(); vdso_info = machine->vdso_info; if (!vdso_info) - return NULL; + goto out_unlock; #if BITS_PER_LONG == 64 - if (machine__findnew_vdso_compat(machine, thread, vdso_info, &dso)) - return dso; + if (__machine__findnew_vdso_compat(machine, thread, vdso_info, &dso)) + goto out_unlock; #endif - dso = dsos__find(&machine->dsos, DSO__NAME_VDSO, true); + dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO, true); if (!dso) { char *file; file = get_file(&vdso_info->vdso); - if (!file) - return NULL; - - dso = machine__addnew_vdso(machine, DSO__NAME_VDSO, file); + if (file) + dso = __machine__addnew_vdso(machine, DSO__NAME_VDSO, file); } +out_unlock: + pthread_rwlock_unlock(&machine->dsos.lock); return dso; } |