diff options
author | Kan Liang <kan.liang@intel.com> | 2017-09-29 10:47:53 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2017-10-03 08:27:36 -0400 |
commit | f988e71bc6220d8b404dbd43c0e0962e30305795 (patch) | |
tree | 4f554e04a5480e14b7342934339a995d42af23dc /tools/perf/util/comm.c | |
parent | b32ee9e522f7ba26339856a047cfe9efc0be0ff3 (diff) |
perf tools: Lock to protect comm_str rb tree
Add comm_str_lock to protect comm_str rb tree.
The lock is only needed for multithreaded code, so using mutex wrappers
provided by perf tool.
Signed-off-by: Kan Liang <kan.liang@intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Lukasz Odzioba <lukasz.odzioba@intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1506696477-146932-3-git-send-email-kan.liang@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/comm.c')
-rw-r--r-- | tools/perf/util/comm.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c index 7bc981b6bf29..756a9c14efbb 100644 --- a/tools/perf/util/comm.c +++ b/tools/perf/util/comm.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <stdio.h> | 5 | #include <stdio.h> |
6 | #include <string.h> | 6 | #include <string.h> |
7 | #include <linux/refcount.h> | 7 | #include <linux/refcount.h> |
8 | #include "rwsem.h" | ||
8 | 9 | ||
9 | struct comm_str { | 10 | struct comm_str { |
10 | char *str; | 11 | char *str; |
@@ -14,6 +15,7 @@ struct comm_str { | |||
14 | 15 | ||
15 | /* Should perhaps be moved to struct machine */ | 16 | /* Should perhaps be moved to struct machine */ |
16 | static struct rb_root comm_str_root; | 17 | static struct rb_root comm_str_root; |
18 | static struct rw_semaphore comm_str_lock = {.lock = PTHREAD_RWLOCK_INITIALIZER,}; | ||
17 | 19 | ||
18 | static struct comm_str *comm_str__get(struct comm_str *cs) | 20 | static struct comm_str *comm_str__get(struct comm_str *cs) |
19 | { | 21 | { |
@@ -25,7 +27,9 @@ static struct comm_str *comm_str__get(struct comm_str *cs) | |||
25 | static void comm_str__put(struct comm_str *cs) | 27 | static void comm_str__put(struct comm_str *cs) |
26 | { | 28 | { |
27 | if (cs && refcount_dec_and_test(&cs->refcnt)) { | 29 | if (cs && refcount_dec_and_test(&cs->refcnt)) { |
30 | down_write(&comm_str_lock); | ||
28 | rb_erase(&cs->rb_node, &comm_str_root); | 31 | rb_erase(&cs->rb_node, &comm_str_root); |
32 | up_write(&comm_str_lock); | ||
29 | zfree(&cs->str); | 33 | zfree(&cs->str); |
30 | free(cs); | 34 | free(cs); |
31 | } | 35 | } |
@@ -50,7 +54,8 @@ static struct comm_str *comm_str__alloc(const char *str) | |||
50 | return cs; | 54 | return cs; |
51 | } | 55 | } |
52 | 56 | ||
53 | static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root) | 57 | static |
58 | struct comm_str *__comm_str__findnew(const char *str, struct rb_root *root) | ||
54 | { | 59 | { |
55 | struct rb_node **p = &root->rb_node; | 60 | struct rb_node **p = &root->rb_node; |
56 | struct rb_node *parent = NULL; | 61 | struct rb_node *parent = NULL; |
@@ -81,6 +86,17 @@ static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root) | |||
81 | return new; | 86 | return new; |
82 | } | 87 | } |
83 | 88 | ||
89 | static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root) | ||
90 | { | ||
91 | struct comm_str *cs; | ||
92 | |||
93 | down_write(&comm_str_lock); | ||
94 | cs = __comm_str__findnew(str, root); | ||
95 | up_write(&comm_str_lock); | ||
96 | |||
97 | return cs; | ||
98 | } | ||
99 | |||
84 | struct comm *comm__new(const char *str, u64 timestamp, bool exec) | 100 | struct comm *comm__new(const char *str, u64 timestamp, bool exec) |
85 | { | 101 | { |
86 | struct comm *comm = zalloc(sizeof(*comm)); | 102 | struct comm *comm = zalloc(sizeof(*comm)); |