[PATCH 25/40] perf tools: Protect dso symbol loading using a mutex

2015-05-17 Thread Namhyung Kim
When multi-thread support for perf report is enabled, it's possible to
access a dso concurrently.  Add a new pthread_mutex to protect it from
concurrent dso__load().

Signed-off-by: Namhyung Kim 
---
 tools/perf/util/dso.c|  2 ++
 tools/perf/util/dso.h|  1 +
 tools/perf/util/symbol.c | 34 --
 3 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 7078700233fa..c14d981568fd 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -936,6 +936,7 @@ struct dso *dso__new(const char *name)
RB_CLEAR_NODE(>rb_node);
INIT_LIST_HEAD(>node);
INIT_LIST_HEAD(>data.open_entry);
+   pthread_mutex_init(>lock, NULL);
}
 
return dso;
@@ -966,6 +967,7 @@ void dso__delete(struct dso *dso)
dso_cache__free(>data.cache);
dso__free_a2l(dso);
zfree(>symsrc_filename);
+   pthread_mutex_destroy(>lock);
free(dso);
 }
 
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 3d79c749934c..b26ec3ab1336 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -129,6 +129,7 @@ struct dsos {
 struct auxtrace_cache;
 
 struct dso {
+   pthread_mutex_t  lock;
struct list_head node;
struct rb_node   rb_node;   /* rbtree node sorted by long name */
struct rb_root   symbols[MAP__NR_TYPES];
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 5d69d3c407e6..6c88c607930f 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1383,12 +1383,22 @@ int dso__load(struct dso *dso, struct map *map, 
symbol_filter_t filter)
struct symsrc *syms_ss = NULL, *runtime_ss = NULL;
bool kmod;
 
-   dso__set_loaded(dso, map->type);
+   pthread_mutex_lock(>lock);
+
+   /* check again under the dso->lock */
+   if (dso__loaded(dso, map->type)) {
+   ret = 1;
+   goto out;
+   }
+
+   if (dso->kernel) {
+   if (dso->kernel == DSO_TYPE_KERNEL)
+   ret = dso__load_kernel_sym(dso, map, filter);
+   else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
+   ret = dso__load_guest_kernel_sym(dso, map, filter);
 
-   if (dso->kernel == DSO_TYPE_KERNEL)
-   return dso__load_kernel_sym(dso, map, filter);
-   else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
-   return dso__load_guest_kernel_sym(dso, map, filter);
+   goto out;
+   }
 
if (map->groups && map->groups->machine)
machine = map->groups->machine;
@@ -1401,18 +1411,18 @@ int dso__load(struct dso *dso, struct map *map, 
symbol_filter_t filter)
struct stat st;
 
if (lstat(dso->name, ) < 0)
-   return -1;
+   goto out;
 
if (st.st_uid && (st.st_uid != geteuid())) {
pr_warning("File %s not owned by current user or root, "
"ignoring it.\n", dso->name);
-   return -1;
+   goto out;
}
 
ret = dso__load_perf_map(dso, map, filter);
dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT :
 DSO_BINARY_TYPE__NOT_FOUND;
-   return ret;
+   goto out;
}
 
if (machine)
@@ -1420,7 +1430,7 @@ int dso__load(struct dso *dso, struct map *map, 
symbol_filter_t filter)
 
name = malloc(PATH_MAX);
if (!name)
-   return -1;
+   goto out;
 
kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
@@ -1501,7 +1511,11 @@ int dso__load(struct dso *dso, struct map *map, 
symbol_filter_t filter)
 out_free:
free(name);
if (ret < 0 && strstr(dso->name, " (deleted)") != NULL)
-   return 0;
+   ret = 0;
+out:
+   dso__set_loaded(dso, map->type);
+   pthread_mutex_unlock(>lock);
+
return ret;
 }
 
-- 
2.4.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 25/40] perf tools: Protect dso symbol loading using a mutex

2015-05-17 Thread Namhyung Kim
When multi-thread support for perf report is enabled, it's possible to
access a dso concurrently.  Add a new pthread_mutex to protect it from
concurrent dso__load().

Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/dso.c|  2 ++
 tools/perf/util/dso.h|  1 +
 tools/perf/util/symbol.c | 34 --
 3 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 7078700233fa..c14d981568fd 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -936,6 +936,7 @@ struct dso *dso__new(const char *name)
RB_CLEAR_NODE(dso-rb_node);
INIT_LIST_HEAD(dso-node);
INIT_LIST_HEAD(dso-data.open_entry);
+   pthread_mutex_init(dso-lock, NULL);
}
 
return dso;
@@ -966,6 +967,7 @@ void dso__delete(struct dso *dso)
dso_cache__free(dso-data.cache);
dso__free_a2l(dso);
zfree(dso-symsrc_filename);
+   pthread_mutex_destroy(dso-lock);
free(dso);
 }
 
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 3d79c749934c..b26ec3ab1336 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -129,6 +129,7 @@ struct dsos {
 struct auxtrace_cache;
 
 struct dso {
+   pthread_mutex_t  lock;
struct list_head node;
struct rb_node   rb_node;   /* rbtree node sorted by long name */
struct rb_root   symbols[MAP__NR_TYPES];
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 5d69d3c407e6..6c88c607930f 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1383,12 +1383,22 @@ int dso__load(struct dso *dso, struct map *map, 
symbol_filter_t filter)
struct symsrc *syms_ss = NULL, *runtime_ss = NULL;
bool kmod;
 
-   dso__set_loaded(dso, map-type);
+   pthread_mutex_lock(dso-lock);
+
+   /* check again under the dso-lock */
+   if (dso__loaded(dso, map-type)) {
+   ret = 1;
+   goto out;
+   }
+
+   if (dso-kernel) {
+   if (dso-kernel == DSO_TYPE_KERNEL)
+   ret = dso__load_kernel_sym(dso, map, filter);
+   else if (dso-kernel == DSO_TYPE_GUEST_KERNEL)
+   ret = dso__load_guest_kernel_sym(dso, map, filter);
 
-   if (dso-kernel == DSO_TYPE_KERNEL)
-   return dso__load_kernel_sym(dso, map, filter);
-   else if (dso-kernel == DSO_TYPE_GUEST_KERNEL)
-   return dso__load_guest_kernel_sym(dso, map, filter);
+   goto out;
+   }
 
if (map-groups  map-groups-machine)
machine = map-groups-machine;
@@ -1401,18 +1411,18 @@ int dso__load(struct dso *dso, struct map *map, 
symbol_filter_t filter)
struct stat st;
 
if (lstat(dso-name, st)  0)
-   return -1;
+   goto out;
 
if (st.st_uid  (st.st_uid != geteuid())) {
pr_warning(File %s not owned by current user or root, 
ignoring it.\n, dso-name);
-   return -1;
+   goto out;
}
 
ret = dso__load_perf_map(dso, map, filter);
dso-symtab_type = ret  0 ? DSO_BINARY_TYPE__JAVA_JIT :
 DSO_BINARY_TYPE__NOT_FOUND;
-   return ret;
+   goto out;
}
 
if (machine)
@@ -1420,7 +1430,7 @@ int dso__load(struct dso *dso, struct map *map, 
symbol_filter_t filter)
 
name = malloc(PATH_MAX);
if (!name)
-   return -1;
+   goto out;
 
kmod = dso-symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
dso-symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
@@ -1501,7 +1511,11 @@ int dso__load(struct dso *dso, struct map *map, 
symbol_filter_t filter)
 out_free:
free(name);
if (ret  0  strstr(dso-name,  (deleted)) != NULL)
-   return 0;
+   ret = 0;
+out:
+   dso__set_loaded(dso, map-type);
+   pthread_mutex_unlock(dso-lock);
+
return ret;
 }
 
-- 
2.4.0

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/