aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/perf_counter/builtin-record.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2009-06-02 08:13:24 -0400
committerIngo Molnar <mingo@elte.hu>2009-06-02 10:16:26 -0400
commitf70e87d7a6d9c5a23d5f43ed0a0c224c157ef597 (patch)
tree4ab2bd0cf9db9ada8edd49266765d7c9df2ade5f /Documentation/perf_counter/builtin-record.c
parent709e50cf870e61745b39552044aa6c7c38e4f9e0 (diff)
perf_counter: tools: Expand the COMM,MMAP event synthesizer
Include code to pre-construct mappings based on /proc, on system wide recording. Fix the existing code to properly fill out ->pid and ->tid. The PID should be the Thread Group ID (PIDTYPE_PID of task->group_leader) The TID should be the Thread ID (PIDTYPE_PID of task) Furthermore, change the default sorting of report to comm,dso for a better quick overview. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Marcelo Tosatti <mtosatti@redhat.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: John Kacur <jkacur@redhat.com> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'Documentation/perf_counter/builtin-record.c')
-rw-r--r--Documentation/perf_counter/builtin-record.c84
1 files changed, 64 insertions, 20 deletions
diff --git a/Documentation/perf_counter/builtin-record.c b/Documentation/perf_counter/builtin-record.c
index 9c151ded22fa..810fc275ca65 100644
--- a/Documentation/perf_counter/builtin-record.c
+++ b/Documentation/perf_counter/builtin-record.c
@@ -162,7 +162,7 @@ struct comm_event {
162 char comm[16]; 162 char comm[16];
163}; 163};
164 164
165static pid_t pid_synthesize_comm_event(pid_t pid) 165static void pid_synthesize_comm_event(pid_t pid, int full)
166{ 166{
167 struct comm_event comm_ev; 167 struct comm_event comm_ev;
168 char filename[PATH_MAX]; 168 char filename[PATH_MAX];
@@ -170,6 +170,8 @@ static pid_t pid_synthesize_comm_event(pid_t pid)
170 int fd, ret; 170 int fd, ret;
171 size_t size; 171 size_t size;
172 char *field, *sep; 172 char *field, *sep;
173 DIR *tasks;
174 struct dirent dirent, *next;
173 175
174 snprintf(filename, sizeof(filename), "/proc/%d/stat", pid); 176 snprintf(filename, sizeof(filename), "/proc/%d/stat", pid);
175 177
@@ -194,29 +196,50 @@ static pid_t pid_synthesize_comm_event(pid_t pid)
194 goto out_failure; 196 goto out_failure;
195 size = sep - field; 197 size = sep - field;
196 memcpy(comm_ev.comm, field, size++); 198 memcpy(comm_ev.comm, field, size++);
197 field = strchr(sep + 4, ' '); 199
198 if (field == NULL) 200 comm_ev.pid = pid;
199 goto out_failure;
200 comm_ev.pid = atoi(++field);
201 comm_ev.header.type = PERF_EVENT_COMM; 201 comm_ev.header.type = PERF_EVENT_COMM;
202 comm_ev.tid = pid;
203 size = ALIGN(size, sizeof(uint64_t)); 202 size = ALIGN(size, sizeof(uint64_t));
204 comm_ev.header.size = sizeof(comm_ev) - (sizeof(comm_ev.comm) - size); 203 comm_ev.header.size = sizeof(comm_ev) - (sizeof(comm_ev.comm) - size);
205 204
206 ret = write(output, &comm_ev, comm_ev.header.size); 205 if (!full) {
207 if (ret < 0) { 206 comm_ev.tid = pid;
208 perror("failed to write"); 207
209 exit(-1); 208 ret = write(output, &comm_ev, comm_ev.header.size);
209 if (ret < 0) {
210 perror("failed to write");
211 exit(-1);
212 }
213 return;
214 }
215
216 snprintf(filename, sizeof(filename), "/proc/%d/task", pid);
217
218 tasks = opendir(filename);
219 while (!readdir_r(tasks, &dirent, &next) && next) {
220 char *end;
221 pid = strtol(dirent.d_name, &end, 10);
222 if (*end)
223 continue;
224
225 comm_ev.tid = pid;
226
227 ret = write(output, &comm_ev, comm_ev.header.size);
228 if (ret < 0) {
229 perror("failed to write");
230 exit(-1);
231 }
210 } 232 }
211 return comm_ev.pid; 233 closedir(tasks);
234 return;
235
212out_failure: 236out_failure:
213 fprintf(stderr, "couldn't get COMM and pgid, malformed %s\n", 237 fprintf(stderr, "couldn't get COMM and pgid, malformed %s\n",
214 filename); 238 filename);
215 exit(EXIT_FAILURE); 239 exit(EXIT_FAILURE);
216 return -1;
217} 240}
218 241
219static void pid_synthesize_mmap_events(pid_t pid, pid_t pgid) 242static void pid_synthesize_mmap_events(pid_t pid)
220{ 243{
221 char filename[PATH_MAX]; 244 char filename[PATH_MAX];
222 FILE *fp; 245 FILE *fp;
@@ -261,7 +284,7 @@ static void pid_synthesize_mmap_events(pid_t pid, pid_t pgid)
261 mmap_ev.len -= mmap_ev.start; 284 mmap_ev.len -= mmap_ev.start;
262 mmap_ev.header.size = (sizeof(mmap_ev) - 285 mmap_ev.header.size = (sizeof(mmap_ev) -
263 (sizeof(mmap_ev.filename) - size)); 286 (sizeof(mmap_ev.filename) - size));
264 mmap_ev.pid = pgid; 287 mmap_ev.pid = pid;
265 mmap_ev.tid = pid; 288 mmap_ev.tid = pid;
266 289
267 if (write(output, &mmap_ev, mmap_ev.header.size) < 0) { 290 if (write(output, &mmap_ev, mmap_ev.header.size) < 0) {
@@ -274,6 +297,28 @@ static void pid_synthesize_mmap_events(pid_t pid, pid_t pgid)
274 fclose(fp); 297 fclose(fp);
275} 298}
276 299
300static void synthesize_events(void)
301{
302 DIR *proc;
303 struct dirent dirent, *next;
304
305 proc = opendir("/proc");
306
307 while (!readdir_r(proc, &dirent, &next) && next) {
308 char *end;
309 pid_t pid;
310
311 pid = strtol(dirent.d_name, &end, 10);
312 if (*end) /* only interested in proper numerical dirents */
313 continue;
314
315 pid_synthesize_comm_event(pid, 1);
316 pid_synthesize_mmap_events(pid);
317 }
318
319 closedir(proc);
320}
321
277static void open_counters(int cpu, pid_t pid) 322static void open_counters(int cpu, pid_t pid)
278{ 323{
279 struct perf_counter_hw_event hw_event; 324 struct perf_counter_hw_event hw_event;
@@ -281,8 +326,8 @@ static void open_counters(int cpu, pid_t pid)
281 int track = 1; 326 int track = 1;
282 327
283 if (pid > 0) { 328 if (pid > 0) {
284 pid_t pgid = pid_synthesize_comm_event(pid); 329 pid_synthesize_comm_event(pid, 0);
285 pid_synthesize_mmap_events(pid, pgid); 330 pid_synthesize_mmap_events(pid);
286 } 331 }
287 332
288 group_fd = -1; 333 group_fd = -1;
@@ -348,7 +393,7 @@ static int __cmd_record(int argc, const char **argv)
348 assert(nr_cpus <= MAX_NR_CPUS); 393 assert(nr_cpus <= MAX_NR_CPUS);
349 assert(nr_cpus >= 0); 394 assert(nr_cpus >= 0);
350 395
351 output = open(output_name, O_CREAT|O_EXCL|O_RDWR, S_IRWXU); 396 output = open(output_name, O_CREAT|O_EXCL|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR);
352 if (output < 0) { 397 if (output < 0) {
353 perror("failed to create output file"); 398 perror("failed to create output file");
354 exit(-1); 399 exit(-1);
@@ -385,9 +430,8 @@ static int __cmd_record(int argc, const char **argv)
385 } 430 }
386 } 431 }
387 432
388 /* 433 if (system_wide)
389 * TODO: store the current /proc/$/maps information somewhere 434 synthesize_events();
390 */
391 435
392 while (!done) { 436 while (!done) {
393 int hits = events; 437 int hits = events;