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>
This commit is contained in:
Arnaldo Carvalho de Melo
2015-06-01 15:40:01 -03:00
parent 9f2de31542
commit e880784422
4 changed files with 95 additions and 47 deletions

View File

@@ -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;
}