aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorJoseph Schuchart <joseph.schuchart@tu-dresden.de>2014-07-10 07:50:51 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-07-16 16:57:33 -0400
commit0f5f5bcd112292f14b75750dde7461463bb1c7bb (patch)
treebb87bcdd3d703c5f397d46db0c7bd7c14d144e62 /tools/perf
parent05f832e3a267d6e45d092595bdf9339d127ea137 (diff)
perf script: Add callchain to generic and tracepoint events
This provides valuable information for tracing performance problems. Since this change alters the interface for the python scripts, also adjust the script generation and the provided scripts. Signed-off-by: Joseph Schuchart <joseph.schuchart@tu-dresden.de> Acked-by: Thomas Ilsche <thomas.ilsche@tu-dresden.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Thomas Ilsche <thomas.ilsche@tu-dresden.de> Link: http://lkml.kernel.org/r/53BE7E1B.10503@tu-dresden.de Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py3
-rw-r--r--tools/perf/scripts/python/check-perf-trace.py4
-rw-r--r--tools/perf/scripts/python/failed-syscalls-by-pid.py2
-rw-r--r--tools/perf/scripts/python/futex-contention.py4
-rwxr-xr-xtools/perf/scripts/python/net_dropmonitor.py2
-rw-r--r--tools/perf/scripts/python/netdev-times.py26
-rw-r--r--tools/perf/scripts/python/sched-migration.py41
-rw-r--r--tools/perf/scripts/python/sctop.py2
-rw-r--r--tools/perf/scripts/python/syscall-counts-by-pid.py2
-rw-r--r--tools/perf/scripts/python/syscall-counts.py2
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c106
11 files changed, 146 insertions, 48 deletions
diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py
index de7211e4fa47..38dfb720fb6f 100644
--- a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py
+++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py
@@ -107,12 +107,13 @@ def taskState(state):
107 107
108class EventHeaders: 108class EventHeaders:
109 def __init__(self, common_cpu, common_secs, common_nsecs, 109 def __init__(self, common_cpu, common_secs, common_nsecs,
110 common_pid, common_comm): 110 common_pid, common_comm, common_callchain):
111 self.cpu = common_cpu 111 self.cpu = common_cpu
112 self.secs = common_secs 112 self.secs = common_secs
113 self.nsecs = common_nsecs 113 self.nsecs = common_nsecs
114 self.pid = common_pid 114 self.pid = common_pid
115 self.comm = common_comm 115 self.comm = common_comm
116 self.callchain = common_callchain
116 117
117 def ts(self): 118 def ts(self):
118 return (self.secs * (10 ** 9)) + self.nsecs 119 return (self.secs * (10 ** 9)) + self.nsecs
diff --git a/tools/perf/scripts/python/check-perf-trace.py b/tools/perf/scripts/python/check-perf-trace.py
index 4647a7694cf6..334599c6032c 100644
--- a/tools/perf/scripts/python/check-perf-trace.py
+++ b/tools/perf/scripts/python/check-perf-trace.py
@@ -27,7 +27,7 @@ def trace_end():
27 27
28def irq__softirq_entry(event_name, context, common_cpu, 28def irq__softirq_entry(event_name, context, common_cpu,
29 common_secs, common_nsecs, common_pid, common_comm, 29 common_secs, common_nsecs, common_pid, common_comm,
30 vec): 30 common_callchain, vec):
31 print_header(event_name, common_cpu, common_secs, common_nsecs, 31 print_header(event_name, common_cpu, common_secs, common_nsecs,
32 common_pid, common_comm) 32 common_pid, common_comm)
33 33
@@ -38,7 +38,7 @@ def irq__softirq_entry(event_name, context, common_cpu,
38 38
39def kmem__kmalloc(event_name, context, common_cpu, 39def kmem__kmalloc(event_name, context, common_cpu,
40 common_secs, common_nsecs, common_pid, common_comm, 40 common_secs, common_nsecs, common_pid, common_comm,
41 call_site, ptr, bytes_req, bytes_alloc, 41 common_callchain, call_site, ptr, bytes_req, bytes_alloc,
42 gfp_flags): 42 gfp_flags):
43 print_header(event_name, common_cpu, common_secs, common_nsecs, 43 print_header(event_name, common_cpu, common_secs, common_nsecs,
44 common_pid, common_comm) 44 common_pid, common_comm)
diff --git a/tools/perf/scripts/python/failed-syscalls-by-pid.py b/tools/perf/scripts/python/failed-syscalls-by-pid.py
index 266a8364bce5..cafeff3d74db 100644
--- a/tools/perf/scripts/python/failed-syscalls-by-pid.py
+++ b/tools/perf/scripts/python/failed-syscalls-by-pid.py
@@ -39,7 +39,7 @@ def trace_end():
39 39
40def raw_syscalls__sys_exit(event_name, context, common_cpu, 40def raw_syscalls__sys_exit(event_name, context, common_cpu,
41 common_secs, common_nsecs, common_pid, common_comm, 41 common_secs, common_nsecs, common_pid, common_comm,
42 id, ret): 42 common_callchain, id, ret):
43 if (for_comm and common_comm != for_comm) or \ 43 if (for_comm and common_comm != for_comm) or \
44 (for_pid and common_pid != for_pid ): 44 (for_pid and common_pid != for_pid ):
45 return 45 return
diff --git a/tools/perf/scripts/python/futex-contention.py b/tools/perf/scripts/python/futex-contention.py
index 11e70a388d41..0f5cf437b602 100644
--- a/tools/perf/scripts/python/futex-contention.py
+++ b/tools/perf/scripts/python/futex-contention.py
@@ -21,7 +21,7 @@ thread_blocktime = {}
21lock_waits = {} # long-lived stats on (tid,lock) blockage elapsed time 21lock_waits = {} # long-lived stats on (tid,lock) blockage elapsed time
22process_names = {} # long-lived pid-to-execname mapping 22process_names = {} # long-lived pid-to-execname mapping
23 23
24def syscalls__sys_enter_futex(event, ctxt, cpu, s, ns, tid, comm, 24def syscalls__sys_enter_futex(event, ctxt, cpu, s, ns, tid, comm, callchain,
25 nr, uaddr, op, val, utime, uaddr2, val3): 25 nr, uaddr, op, val, utime, uaddr2, val3):
26 cmd = op & FUTEX_CMD_MASK 26 cmd = op & FUTEX_CMD_MASK
27 if cmd != FUTEX_WAIT: 27 if cmd != FUTEX_WAIT:
@@ -31,7 +31,7 @@ def syscalls__sys_enter_futex(event, ctxt, cpu, s, ns, tid, comm,
31 thread_thislock[tid] = uaddr 31 thread_thislock[tid] = uaddr
32 thread_blocktime[tid] = nsecs(s, ns) 32 thread_blocktime[tid] = nsecs(s, ns)
33 33
34def syscalls__sys_exit_futex(event, ctxt, cpu, s, ns, tid, comm, 34def syscalls__sys_exit_futex(event, ctxt, cpu, s, ns, tid, comm, callchain,
35 nr, ret): 35 nr, ret):
36 if thread_blocktime.has_key(tid): 36 if thread_blocktime.has_key(tid):
37 elapsed = nsecs(s, ns) - thread_blocktime[tid] 37 elapsed = nsecs(s, ns) - thread_blocktime[tid]
diff --git a/tools/perf/scripts/python/net_dropmonitor.py b/tools/perf/scripts/python/net_dropmonitor.py
index b5740599aabd..0b6ce8c253e8 100755
--- a/tools/perf/scripts/python/net_dropmonitor.py
+++ b/tools/perf/scripts/python/net_dropmonitor.py
@@ -66,7 +66,7 @@ def trace_end():
66 print_drop_table() 66 print_drop_table()
67 67
68# called from perf, when it finds a correspoinding event 68# called from perf, when it finds a correspoinding event
69def skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm, 69def skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm, callchain,
70 skbaddr, location, protocol): 70 skbaddr, location, protocol):
71 slocation = str(location) 71 slocation = str(location)
72 try: 72 try:
diff --git a/tools/perf/scripts/python/netdev-times.py b/tools/perf/scripts/python/netdev-times.py
index 9aa0a32972e8..4d21ef2d601d 100644
--- a/tools/perf/scripts/python/netdev-times.py
+++ b/tools/perf/scripts/python/netdev-times.py
@@ -224,75 +224,75 @@ def trace_end():
224 (len(rx_skb_list), of_count_rx_skb_list) 224 (len(rx_skb_list), of_count_rx_skb_list)
225 225
226# called from perf, when it finds a correspoinding event 226# called from perf, when it finds a correspoinding event
227def irq__softirq_entry(name, context, cpu, sec, nsec, pid, comm, vec): 227def irq__softirq_entry(name, context, cpu, sec, nsec, pid, comm, callchain, vec):
228 if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX": 228 if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX":
229 return 229 return
230 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec) 230 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec)
231 all_event_list.append(event_info) 231 all_event_list.append(event_info)
232 232
233def irq__softirq_exit(name, context, cpu, sec, nsec, pid, comm, vec): 233def irq__softirq_exit(name, context, cpu, sec, nsec, pid, comm, callchain, vec):
234 if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX": 234 if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX":
235 return 235 return
236 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec) 236 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec)
237 all_event_list.append(event_info) 237 all_event_list.append(event_info)
238 238
239def irq__softirq_raise(name, context, cpu, sec, nsec, pid, comm, vec): 239def irq__softirq_raise(name, context, cpu, sec, nsec, pid, comm, callchain, vec):
240 if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX": 240 if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX":
241 return 241 return
242 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec) 242 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec)
243 all_event_list.append(event_info) 243 all_event_list.append(event_info)
244 244
245def irq__irq_handler_entry(name, context, cpu, sec, nsec, pid, comm, 245def irq__irq_handler_entry(name, context, cpu, sec, nsec, pid, comm,
246 irq, irq_name): 246 callchain, irq, irq_name):
247 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, 247 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
248 irq, irq_name) 248 irq, irq_name)
249 all_event_list.append(event_info) 249 all_event_list.append(event_info)
250 250
251def irq__irq_handler_exit(name, context, cpu, sec, nsec, pid, comm, irq, ret): 251def irq__irq_handler_exit(name, context, cpu, sec, nsec, pid, comm, callchain, irq, ret):
252 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, irq, ret) 252 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, irq, ret)
253 all_event_list.append(event_info) 253 all_event_list.append(event_info)
254 254
255def napi__napi_poll(name, context, cpu, sec, nsec, pid, comm, napi, dev_name): 255def napi__napi_poll(name, context, cpu, sec, nsec, pid, comm, callchain, napi, dev_name):
256 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, 256 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
257 napi, dev_name) 257 napi, dev_name)
258 all_event_list.append(event_info) 258 all_event_list.append(event_info)
259 259
260def net__netif_receive_skb(name, context, cpu, sec, nsec, pid, comm, skbaddr, 260def net__netif_receive_skb(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr,
261 skblen, dev_name): 261 skblen, dev_name):
262 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, 262 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
263 skbaddr, skblen, dev_name) 263 skbaddr, skblen, dev_name)
264 all_event_list.append(event_info) 264 all_event_list.append(event_info)
265 265
266def net__netif_rx(name, context, cpu, sec, nsec, pid, comm, skbaddr, 266def net__netif_rx(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr,
267 skblen, dev_name): 267 skblen, dev_name):
268 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, 268 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
269 skbaddr, skblen, dev_name) 269 skbaddr, skblen, dev_name)
270 all_event_list.append(event_info) 270 all_event_list.append(event_info)
271 271
272def net__net_dev_queue(name, context, cpu, sec, nsec, pid, comm, 272def net__net_dev_queue(name, context, cpu, sec, nsec, pid, comm, callchain,
273 skbaddr, skblen, dev_name): 273 skbaddr, skblen, dev_name):
274 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, 274 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
275 skbaddr, skblen, dev_name) 275 skbaddr, skblen, dev_name)
276 all_event_list.append(event_info) 276 all_event_list.append(event_info)
277 277
278def net__net_dev_xmit(name, context, cpu, sec, nsec, pid, comm, 278def net__net_dev_xmit(name, context, cpu, sec, nsec, pid, comm, callchain,
279 skbaddr, skblen, rc, dev_name): 279 skbaddr, skblen, rc, dev_name):
280 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, 280 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
281 skbaddr, skblen, rc ,dev_name) 281 skbaddr, skblen, rc ,dev_name)
282 all_event_list.append(event_info) 282 all_event_list.append(event_info)
283 283
284def skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm, 284def skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm, callchain,
285 skbaddr, protocol, location): 285 skbaddr, protocol, location):
286 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, 286 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
287 skbaddr, protocol, location) 287 skbaddr, protocol, location)
288 all_event_list.append(event_info) 288 all_event_list.append(event_info)
289 289
290def skb__consume_skb(name, context, cpu, sec, nsec, pid, comm, skbaddr): 290def skb__consume_skb(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr):
291 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, 291 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
292 skbaddr) 292 skbaddr)
293 all_event_list.append(event_info) 293 all_event_list.append(event_info)
294 294
295def skb__skb_copy_datagram_iovec(name, context, cpu, sec, nsec, pid, comm, 295def skb__skb_copy_datagram_iovec(name, context, cpu, sec, nsec, pid, comm, callchain,
296 skbaddr, skblen): 296 skbaddr, skblen):
297 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, 297 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
298 skbaddr, skblen) 298 skbaddr, skblen)
diff --git a/tools/perf/scripts/python/sched-migration.py b/tools/perf/scripts/python/sched-migration.py
index 74d55ec08aed..de66cb3b72c9 100644
--- a/tools/perf/scripts/python/sched-migration.py
+++ b/tools/perf/scripts/python/sched-migration.py
@@ -369,93 +369,92 @@ def trace_end():
369 369
370def sched__sched_stat_runtime(event_name, context, common_cpu, 370def sched__sched_stat_runtime(event_name, context, common_cpu,
371 common_secs, common_nsecs, common_pid, common_comm, 371 common_secs, common_nsecs, common_pid, common_comm,
372 comm, pid, runtime, vruntime): 372 common_callchain, comm, pid, runtime, vruntime):
373 pass 373 pass
374 374
375def sched__sched_stat_iowait(event_name, context, common_cpu, 375def sched__sched_stat_iowait(event_name, context, common_cpu,
376 common_secs, common_nsecs, common_pid, common_comm, 376 common_secs, common_nsecs, common_pid, common_comm,
377 comm, pid, delay): 377 common_callchain, comm, pid, delay):
378 pass 378 pass
379 379
380def sched__sched_stat_sleep(event_name, context, common_cpu, 380def sched__sched_stat_sleep(event_name, context, common_cpu,
381 common_secs, common_nsecs, common_pid, common_comm, 381 common_secs, common_nsecs, common_pid, common_comm,
382 comm, pid, delay): 382 common_callchain, comm, pid, delay):
383 pass 383 pass
384 384
385def sched__sched_stat_wait(event_name, context, common_cpu, 385def sched__sched_stat_wait(event_name, context, common_cpu,
386 common_secs, common_nsecs, common_pid, common_comm, 386 common_secs, common_nsecs, common_pid, common_comm,
387 comm, pid, delay): 387 common_callchain, comm, pid, delay):
388 pass 388 pass
389 389
390def sched__sched_process_fork(event_name, context, common_cpu, 390def sched__sched_process_fork(event_name, context, common_cpu,
391 common_secs, common_nsecs, common_pid, common_comm, 391 common_secs, common_nsecs, common_pid, common_comm,
392 parent_comm, parent_pid, child_comm, child_pid): 392 common_callchain, parent_comm, parent_pid, child_comm, child_pid):
393 pass 393 pass
394 394
395def sched__sched_process_wait(event_name, context, common_cpu, 395def sched__sched_process_wait(event_name, context, common_cpu,
396 common_secs, common_nsecs, common_pid, common_comm, 396 common_secs, common_nsecs, common_pid, common_comm,
397 comm, pid, prio): 397 common_callchain, comm, pid, prio):
398 pass 398 pass
399 399
400def sched__sched_process_exit(event_name, context, common_cpu, 400def sched__sched_process_exit(event_name, context, common_cpu,
401 common_secs, common_nsecs, common_pid, common_comm, 401 common_secs, common_nsecs, common_pid, common_comm,
402 comm, pid, prio): 402 common_callchain, comm, pid, prio):
403 pass 403 pass
404 404
405def sched__sched_process_free(event_name, context, common_cpu, 405def sched__sched_process_free(event_name, context, common_cpu,
406 common_secs, common_nsecs, common_pid, common_comm, 406 common_secs, common_nsecs, common_pid, common_comm,
407 comm, pid, prio): 407 common_callchain, comm, pid, prio):
408 pass 408 pass
409 409
410def sched__sched_migrate_task(event_name, context, common_cpu, 410def sched__sched_migrate_task(event_name, context, common_cpu,
411 common_secs, common_nsecs, common_pid, common_comm, 411 common_secs, common_nsecs, common_pid, common_comm,
412 comm, pid, prio, orig_cpu, 412 common_callchain, comm, pid, prio, orig_cpu,
413 dest_cpu): 413 dest_cpu):
414 headers = EventHeaders(common_cpu, common_secs, common_nsecs, 414 headers = EventHeaders(common_cpu, common_secs, common_nsecs,
415 common_pid, common_comm) 415 common_pid, common_comm, common_callchain)
416 parser.migrate(headers, pid, prio, orig_cpu, dest_cpu) 416 parser.migrate(headers, pid, prio, orig_cpu, dest_cpu)
417 417
418def sched__sched_switch(event_name, context, common_cpu, 418def sched__sched_switch(event_name, context, common_cpu,
419 common_secs, common_nsecs, common_pid, common_comm, 419 common_secs, common_nsecs, common_pid, common_comm, common_callchain,
420 prev_comm, prev_pid, prev_prio, prev_state, 420 prev_comm, prev_pid, prev_prio, prev_state,
421 next_comm, next_pid, next_prio): 421 next_comm, next_pid, next_prio):
422 422
423 headers = EventHeaders(common_cpu, common_secs, common_nsecs, 423 headers = EventHeaders(common_cpu, common_secs, common_nsecs,
424 common_pid, common_comm) 424 common_pid, common_comm, common_callchain)
425 parser.sched_switch(headers, prev_comm, prev_pid, prev_prio, prev_state, 425 parser.sched_switch(headers, prev_comm, prev_pid, prev_prio, prev_state,
426 next_comm, next_pid, next_prio) 426 next_comm, next_pid, next_prio)
427 427
428def sched__sched_wakeup_new(event_name, context, common_cpu, 428def sched__sched_wakeup_new(event_name, context, common_cpu,
429 common_secs, common_nsecs, common_pid, common_comm, 429 common_secs, common_nsecs, common_pid, common_comm,
430 comm, pid, prio, success, 430 common_callchain, comm, pid, prio, success,
431 target_cpu): 431 target_cpu):
432 headers = EventHeaders(common_cpu, common_secs, common_nsecs, 432 headers = EventHeaders(common_cpu, common_secs, common_nsecs,
433 common_pid, common_comm) 433 common_pid, common_comm, common_callchain)
434 parser.wake_up(headers, comm, pid, success, target_cpu, 1) 434 parser.wake_up(headers, comm, pid, success, target_cpu, 1)
435 435
436def sched__sched_wakeup(event_name, context, common_cpu, 436def sched__sched_wakeup(event_name, context, common_cpu,
437 common_secs, common_nsecs, common_pid, common_comm, 437 common_secs, common_nsecs, common_pid, common_comm,
438 comm, pid, prio, success, 438 common_callchain, comm, pid, prio, success,
439 target_cpu): 439 target_cpu):
440 headers = EventHeaders(common_cpu, common_secs, common_nsecs, 440 headers = EventHeaders(common_cpu, common_secs, common_nsecs,
441 common_pid, common_comm) 441 common_pid, common_comm, common_callchain)
442 parser.wake_up(headers, comm, pid, success, target_cpu, 0) 442 parser.wake_up(headers, comm, pid, success, target_cpu, 0)
443 443
444def sched__sched_wait_task(event_name, context, common_cpu, 444def sched__sched_wait_task(event_name, context, common_cpu,
445 common_secs, common_nsecs, common_pid, common_comm, 445 common_secs, common_nsecs, common_pid, common_comm,
446 comm, pid, prio): 446 common_callchain, comm, pid, prio):
447 pass 447 pass
448 448
449def sched__sched_kthread_stop_ret(event_name, context, common_cpu, 449def sched__sched_kthread_stop_ret(event_name, context, common_cpu,
450 common_secs, common_nsecs, common_pid, common_comm, 450 common_secs, common_nsecs, common_pid, common_comm,
451 ret): 451 common_callchain, ret):
452 pass 452 pass
453 453
454def sched__sched_kthread_stop(event_name, context, common_cpu, 454def sched__sched_kthread_stop(event_name, context, common_cpu,
455 common_secs, common_nsecs, common_pid, common_comm, 455 common_secs, common_nsecs, common_pid, common_comm,
456 comm, pid): 456 common_callchain, comm, pid):
457 pass 457 pass
458 458
459def trace_unhandled(event_name, context, common_cpu, common_secs, common_nsecs, 459def trace_unhandled(event_name, context, event_fields_dict):
460 common_pid, common_comm):
461 pass 460 pass
diff --git a/tools/perf/scripts/python/sctop.py b/tools/perf/scripts/python/sctop.py
index c9f3058b7dd4..61621b93affb 100644
--- a/tools/perf/scripts/python/sctop.py
+++ b/tools/perf/scripts/python/sctop.py
@@ -44,7 +44,7 @@ def trace_begin():
44 44
45def raw_syscalls__sys_enter(event_name, context, common_cpu, 45def raw_syscalls__sys_enter(event_name, context, common_cpu,
46 common_secs, common_nsecs, common_pid, common_comm, 46 common_secs, common_nsecs, common_pid, common_comm,
47 id, args): 47 common_callchain, id, args):
48 if for_comm is not None: 48 if for_comm is not None:
49 if common_comm != for_comm: 49 if common_comm != for_comm:
50 return 50 return
diff --git a/tools/perf/scripts/python/syscall-counts-by-pid.py b/tools/perf/scripts/python/syscall-counts-by-pid.py
index cf2054c529c9..daf314cc5dd3 100644
--- a/tools/perf/scripts/python/syscall-counts-by-pid.py
+++ b/tools/perf/scripts/python/syscall-counts-by-pid.py
@@ -38,7 +38,7 @@ def trace_end():
38 38
39def raw_syscalls__sys_enter(event_name, context, common_cpu, 39def raw_syscalls__sys_enter(event_name, context, common_cpu,
40 common_secs, common_nsecs, common_pid, common_comm, 40 common_secs, common_nsecs, common_pid, common_comm,
41 id, args): 41 common_callchain, id, args):
42 42
43 if (for_comm and common_comm != for_comm) or \ 43 if (for_comm and common_comm != for_comm) or \
44 (for_pid and common_pid != for_pid ): 44 (for_pid and common_pid != for_pid ):
diff --git a/tools/perf/scripts/python/syscall-counts.py b/tools/perf/scripts/python/syscall-counts.py
index 92b29381bd39..e66a7730aeb5 100644
--- a/tools/perf/scripts/python/syscall-counts.py
+++ b/tools/perf/scripts/python/syscall-counts.py
@@ -35,7 +35,7 @@ def trace_end():
35 35
36def raw_syscalls__sys_enter(event_name, context, common_cpu, 36def raw_syscalls__sys_enter(event_name, context, common_cpu,
37 common_secs, common_nsecs, common_pid, common_comm, 37 common_secs, common_nsecs, common_pid, common_comm,
38 id, args): 38 common_callchain, id, args):
39 if for_comm is not None: 39 if for_comm is not None:
40 if common_comm != for_comm: 40 if common_comm != for_comm:
41 return 41 return
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index b6c1a69f2b18..cf65404472cb 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -32,6 +32,7 @@
32#include "../event.h" 32#include "../event.h"
33#include "../thread.h" 33#include "../thread.h"
34#include "../trace-event.h" 34#include "../trace-event.h"
35#include "../machine.h"
35 36
36PyMODINIT_FUNC initperf_trace_context(void); 37PyMODINIT_FUNC initperf_trace_context(void);
37 38
@@ -278,12 +279,90 @@ static PyObject *get_field_numeric_entry(struct event_format *event,
278 return obj; 279 return obj;
279} 280}
280 281
282
283static PyObject *python_process_callchain(struct perf_sample *sample,
284 struct perf_evsel *evsel,
285 struct addr_location *al)
286{
287 PyObject *pylist;
288
289 pylist = PyList_New(0);
290 if (!pylist)
291 Py_FatalError("couldn't create Python list");
292
293 if (!symbol_conf.use_callchain || !sample->callchain)
294 goto exit;
295
296 if (machine__resolve_callchain(al->machine, evsel, al->thread,
297 sample, NULL, NULL,
298 PERF_MAX_STACK_DEPTH) != 0) {
299 pr_err("Failed to resolve callchain. Skipping\n");
300 goto exit;
301 }
302 callchain_cursor_commit(&callchain_cursor);
303
304
305 while (1) {
306 PyObject *pyelem;
307 struct callchain_cursor_node *node;
308 node = callchain_cursor_current(&callchain_cursor);
309 if (!node)
310 break;
311
312 pyelem = PyDict_New();
313 if (!pyelem)
314 Py_FatalError("couldn't create Python dictionary");
315
316
317 pydict_set_item_string_decref(pyelem, "ip",
318 PyLong_FromUnsignedLongLong(node->ip));
319
320 if (node->sym) {
321 PyObject *pysym = PyDict_New();
322 if (!pysym)
323 Py_FatalError("couldn't create Python dictionary");
324 pydict_set_item_string_decref(pysym, "start",
325 PyLong_FromUnsignedLongLong(node->sym->start));
326 pydict_set_item_string_decref(pysym, "end",
327 PyLong_FromUnsignedLongLong(node->sym->end));
328 pydict_set_item_string_decref(pysym, "binding",
329 PyInt_FromLong(node->sym->binding));
330 pydict_set_item_string_decref(pysym, "name",
331 PyString_FromStringAndSize(node->sym->name,
332 node->sym->namelen));
333 pydict_set_item_string_decref(pyelem, "sym", pysym);
334 }
335
336 if (node->map) {
337 struct map *map = node->map;
338 const char *dsoname = "[unknown]";
339 if (map && map->dso && (map->dso->name || map->dso->long_name)) {
340 if (symbol_conf.show_kernel_path && map->dso->long_name)
341 dsoname = map->dso->long_name;
342 else if (map->dso->name)
343 dsoname = map->dso->name;
344 }
345 pydict_set_item_string_decref(pyelem, "dso",
346 PyString_FromString(dsoname));
347 }
348
349 callchain_cursor_advance(&callchain_cursor);
350 PyList_Append(pylist, pyelem);
351 Py_DECREF(pyelem);
352 }
353
354exit:
355 return pylist;
356}
357
358
281static void python_process_tracepoint(struct perf_sample *sample, 359static void python_process_tracepoint(struct perf_sample *sample,
282 struct perf_evsel *evsel, 360 struct perf_evsel *evsel,
283 struct thread *thread, 361 struct thread *thread,
284 struct addr_location *al) 362 struct addr_location *al)
285{ 363{
286 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; 364 PyObject *handler, *retval, *context, *t, *obj, *callchain;
365 PyObject *dict = NULL;
287 static char handler_name[256]; 366 static char handler_name[256];
288 struct format_field *field; 367 struct format_field *field;
289 unsigned long s, ns; 368 unsigned long s, ns;
@@ -326,18 +405,23 @@ static void python_process_tracepoint(struct perf_sample *sample,
326 PyTuple_SetItem(t, n++, PyString_FromString(handler_name)); 405 PyTuple_SetItem(t, n++, PyString_FromString(handler_name));
327 PyTuple_SetItem(t, n++, context); 406 PyTuple_SetItem(t, n++, context);
328 407
408 /* ip unwinding */
409 callchain = python_process_callchain(sample, evsel, al);
410
329 if (handler) { 411 if (handler) {
330 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu)); 412 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
331 PyTuple_SetItem(t, n++, PyInt_FromLong(s)); 413 PyTuple_SetItem(t, n++, PyInt_FromLong(s));
332 PyTuple_SetItem(t, n++, PyInt_FromLong(ns)); 414 PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
333 PyTuple_SetItem(t, n++, PyInt_FromLong(pid)); 415 PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
334 PyTuple_SetItem(t, n++, PyString_FromString(comm)); 416 PyTuple_SetItem(t, n++, PyString_FromString(comm));
417 PyTuple_SetItem(t, n++, callchain);
335 } else { 418 } else {
336 pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu)); 419 pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu));
337 pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s)); 420 pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s));
338 pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns)); 421 pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns));
339 pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid)); 422 pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid));
340 pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm)); 423 pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm));
424 pydict_set_item_string_decref(dict, "common_callchain", callchain);
341 } 425 }
342 for (field = event->format.fields; field; field = field->next) { 426 for (field = event->format.fields; field; field = field->next) {
343 if (field->flags & FIELD_IS_STRING) { 427 if (field->flags & FIELD_IS_STRING) {
@@ -357,6 +441,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
357 pydict_set_item_string_decref(dict, field->name, obj); 441 pydict_set_item_string_decref(dict, field->name, obj);
358 442
359 } 443 }
444
360 if (!handler) 445 if (!handler)
361 PyTuple_SetItem(t, n++, dict); 446 PyTuple_SetItem(t, n++, dict);
362 447
@@ -388,7 +473,7 @@ static void python_process_general_event(struct perf_sample *sample,
388 struct thread *thread, 473 struct thread *thread,
389 struct addr_location *al) 474 struct addr_location *al)
390{ 475{
391 PyObject *handler, *retval, *t, *dict; 476 PyObject *handler, *retval, *t, *dict, *callchain;
392 static char handler_name[64]; 477 static char handler_name[64];
393 unsigned n = 0; 478 unsigned n = 0;
394 479
@@ -428,6 +513,10 @@ static void python_process_general_event(struct perf_sample *sample,
428 PyString_FromString(al->sym->name)); 513 PyString_FromString(al->sym->name));
429 } 514 }
430 515
516 /* ip unwinding */
517 callchain = python_process_callchain(sample, evsel, al);
518 pydict_set_item_string_decref(dict, "callchain", callchain);
519
431 PyTuple_SetItem(t, n++, dict); 520 PyTuple_SetItem(t, n++, dict);
432 if (_PyTuple_Resize(&t, n) == -1) 521 if (_PyTuple_Resize(&t, n) == -1)
433 Py_FatalError("error resizing Python tuple"); 522 Py_FatalError("error resizing Python tuple");
@@ -624,6 +713,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
624 fprintf(ofp, "common_nsecs, "); 713 fprintf(ofp, "common_nsecs, ");
625 fprintf(ofp, "common_pid, "); 714 fprintf(ofp, "common_pid, ");
626 fprintf(ofp, "common_comm,\n\t"); 715 fprintf(ofp, "common_comm,\n\t");
716 fprintf(ofp, "common_callchain, ");
627 717
628 not_first = 0; 718 not_first = 0;
629 count = 0; 719 count = 0;
@@ -667,7 +757,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
667 fprintf(ofp, "%%u"); 757 fprintf(ofp, "%%u");
668 } 758 }
669 759
670 fprintf(ofp, "\\n\" %% \\\n\t\t("); 760 fprintf(ofp, "\" %% \\\n\t\t(");
671 761
672 not_first = 0; 762 not_first = 0;
673 count = 0; 763 count = 0;
@@ -703,7 +793,15 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
703 fprintf(ofp, "%s", f->name); 793 fprintf(ofp, "%s", f->name);
704 } 794 }
705 795
706 fprintf(ofp, "),\n\n"); 796 fprintf(ofp, ")\n\n");
797
798 fprintf(ofp, "\t\tfor node in common_callchain:");
799 fprintf(ofp, "\n\t\t\tif 'sym' in node:");
800 fprintf(ofp, "\n\t\t\t\tprint \"\\t[%%x] %%s\" %% (node['ip'], node['sym']['name'])");
801 fprintf(ofp, "\n\t\t\telse:");
802 fprintf(ofp, "\n\t\t\t\tprint \"\t[%%x]\" %% (node['ip'])\n\n");
803 fprintf(ofp, "\t\tprint \"\\n\"\n\n");
804
707 } 805 }
708 806
709 fprintf(ofp, "def trace_unhandled(event_name, context, " 807 fprintf(ofp, "def trace_unhandled(event_name, context, "