diff options
author | Ingo Molnar <mingo@kernel.org> | 2017-10-03 12:30:24 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-10-03 12:30:24 -0400 |
commit | 4b50239a769e78bbe362fc92c3f8bd5415a4a5f5 (patch) | |
tree | 951832e213945ede19cd676a04e5218e68afd074 /tools/perf/util/thread.c | |
parent | a47ba4d77e1236d214e5116b5631bc4c2d6e6369 (diff) | |
parent | f6a9820d572bd8384d982357cbad214b3a6c04bb (diff) |
Merge tag 'perf-core-for-mingo-4.15-20171003' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
- Multithread the synthesizing of PERF_RECORD_ events for pre-existing
threads in 'perf top', speeding up that phase, greatly improving the
user experience in systems such as Intel's Knights Mill (Kan Liang)
- 'perf test' fixes for the perf_event_attr test case (Jiri Olsa, Thomas Richter)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util/thread.c')
-rw-r--r-- | tools/perf/util/thread.c | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index c09bdb509d82..bf73117b4822 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
@@ -45,6 +45,8 @@ struct thread *thread__new(pid_t pid, pid_t tid) | |||
45 | thread->cpu = -1; | 45 | thread->cpu = -1; |
46 | INIT_LIST_HEAD(&thread->namespaces_list); | 46 | INIT_LIST_HEAD(&thread->namespaces_list); |
47 | INIT_LIST_HEAD(&thread->comm_list); | 47 | INIT_LIST_HEAD(&thread->comm_list); |
48 | init_rwsem(&thread->namespaces_lock); | ||
49 | init_rwsem(&thread->comm_lock); | ||
48 | 50 | ||
49 | comm_str = malloc(32); | 51 | comm_str = malloc(32); |
50 | if (!comm_str) | 52 | if (!comm_str) |
@@ -83,18 +85,26 @@ void thread__delete(struct thread *thread) | |||
83 | map_groups__put(thread->mg); | 85 | map_groups__put(thread->mg); |
84 | thread->mg = NULL; | 86 | thread->mg = NULL; |
85 | } | 87 | } |
88 | down_write(&thread->namespaces_lock); | ||
86 | list_for_each_entry_safe(namespaces, tmp_namespaces, | 89 | list_for_each_entry_safe(namespaces, tmp_namespaces, |
87 | &thread->namespaces_list, list) { | 90 | &thread->namespaces_list, list) { |
88 | list_del(&namespaces->list); | 91 | list_del(&namespaces->list); |
89 | namespaces__free(namespaces); | 92 | namespaces__free(namespaces); |
90 | } | 93 | } |
94 | up_write(&thread->namespaces_lock); | ||
95 | |||
96 | down_write(&thread->comm_lock); | ||
91 | list_for_each_entry_safe(comm, tmp_comm, &thread->comm_list, list) { | 97 | list_for_each_entry_safe(comm, tmp_comm, &thread->comm_list, list) { |
92 | list_del(&comm->list); | 98 | list_del(&comm->list); |
93 | comm__free(comm); | 99 | comm__free(comm); |
94 | } | 100 | } |
101 | up_write(&thread->comm_lock); | ||
102 | |||
95 | unwind__finish_access(thread); | 103 | unwind__finish_access(thread); |
96 | nsinfo__zput(thread->nsinfo); | 104 | nsinfo__zput(thread->nsinfo); |
97 | 105 | ||
106 | exit_rwsem(&thread->namespaces_lock); | ||
107 | exit_rwsem(&thread->comm_lock); | ||
98 | free(thread); | 108 | free(thread); |
99 | } | 109 | } |
100 | 110 | ||
@@ -125,8 +135,8 @@ struct namespaces *thread__namespaces(const struct thread *thread) | |||
125 | return list_first_entry(&thread->namespaces_list, struct namespaces, list); | 135 | return list_first_entry(&thread->namespaces_list, struct namespaces, list); |
126 | } | 136 | } |
127 | 137 | ||
128 | int thread__set_namespaces(struct thread *thread, u64 timestamp, | 138 | static int __thread__set_namespaces(struct thread *thread, u64 timestamp, |
129 | struct namespaces_event *event) | 139 | struct namespaces_event *event) |
130 | { | 140 | { |
131 | struct namespaces *new, *curr = thread__namespaces(thread); | 141 | struct namespaces *new, *curr = thread__namespaces(thread); |
132 | 142 | ||
@@ -149,6 +159,17 @@ int thread__set_namespaces(struct thread *thread, u64 timestamp, | |||
149 | return 0; | 159 | return 0; |
150 | } | 160 | } |
151 | 161 | ||
162 | int thread__set_namespaces(struct thread *thread, u64 timestamp, | ||
163 | struct namespaces_event *event) | ||
164 | { | ||
165 | int ret; | ||
166 | |||
167 | down_write(&thread->namespaces_lock); | ||
168 | ret = __thread__set_namespaces(thread, timestamp, event); | ||
169 | up_write(&thread->namespaces_lock); | ||
170 | return ret; | ||
171 | } | ||
172 | |||
152 | struct comm *thread__comm(const struct thread *thread) | 173 | struct comm *thread__comm(const struct thread *thread) |
153 | { | 174 | { |
154 | if (list_empty(&thread->comm_list)) | 175 | if (list_empty(&thread->comm_list)) |
@@ -170,8 +191,8 @@ struct comm *thread__exec_comm(const struct thread *thread) | |||
170 | return last; | 191 | return last; |
171 | } | 192 | } |
172 | 193 | ||
173 | int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, | 194 | static int ____thread__set_comm(struct thread *thread, const char *str, |
174 | bool exec) | 195 | u64 timestamp, bool exec) |
175 | { | 196 | { |
176 | struct comm *new, *curr = thread__comm(thread); | 197 | struct comm *new, *curr = thread__comm(thread); |
177 | 198 | ||
@@ -195,6 +216,17 @@ int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, | |||
195 | return 0; | 216 | return 0; |
196 | } | 217 | } |
197 | 218 | ||
219 | int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, | ||
220 | bool exec) | ||
221 | { | ||
222 | int ret; | ||
223 | |||
224 | down_write(&thread->comm_lock); | ||
225 | ret = ____thread__set_comm(thread, str, timestamp, exec); | ||
226 | up_write(&thread->comm_lock); | ||
227 | return ret; | ||
228 | } | ||
229 | |||
198 | int thread__set_comm_from_proc(struct thread *thread) | 230 | int thread__set_comm_from_proc(struct thread *thread) |
199 | { | 231 | { |
200 | char path[64]; | 232 | char path[64]; |
@@ -212,7 +244,7 @@ int thread__set_comm_from_proc(struct thread *thread) | |||
212 | return err; | 244 | return err; |
213 | } | 245 | } |
214 | 246 | ||
215 | const char *thread__comm_str(const struct thread *thread) | 247 | static const char *__thread__comm_str(const struct thread *thread) |
216 | { | 248 | { |
217 | const struct comm *comm = thread__comm(thread); | 249 | const struct comm *comm = thread__comm(thread); |
218 | 250 | ||
@@ -222,6 +254,17 @@ const char *thread__comm_str(const struct thread *thread) | |||
222 | return comm__str(comm); | 254 | return comm__str(comm); |
223 | } | 255 | } |
224 | 256 | ||
257 | const char *thread__comm_str(const struct thread *thread) | ||
258 | { | ||
259 | const char *str; | ||
260 | |||
261 | down_read((struct rw_semaphore *)&thread->comm_lock); | ||
262 | str = __thread__comm_str(thread); | ||
263 | up_read((struct rw_semaphore *)&thread->comm_lock); | ||
264 | |||
265 | return str; | ||
266 | } | ||
267 | |||
225 | /* CHECKME: it should probably better return the max comm len from its comm list */ | 268 | /* CHECKME: it should probably better return the max comm len from its comm list */ |
226 | int thread__comm_len(struct thread *thread) | 269 | int thread__comm_len(struct thread *thread) |
227 | { | 270 | { |