| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | #include "builtin.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | #include "perf.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "util/util.h"
 | 
					
						
							| 
									
										
											  
											
												perf tools: Save some loops using perf_evlist__id2evsel
Since we already ask for PERF_SAMPLE_ID and use it to quickly find the
associated evsel, add handler func + data to struct perf_evsel to avoid
using chains of if(strcmp(event_name)) and also to avoid all the linear
list searches via trace_event_find.
To demonstrate the technique convert 'perf sched' to it:
 # perf sched record sleep 5m
And then:
 Performance counter stats for '/tmp/oldperf sched lat':
        646.929438 task-clock                #    0.999 CPUs utilized
                 9 context-switches          #    0.000 M/sec
                 0 CPU-migrations            #    0.000 M/sec
            20,901 page-faults               #    0.032 M/sec
     1,290,144,450 cycles                    #    1.994 GHz
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
     1,606,158,439 instructions              #    1.24  insns per cycle
       339,088,395 branches                  #  524.151 M/sec
         4,550,735 branch-misses             #    1.34% of all branches
       0.647524759 seconds time elapsed
Versus:
 Performance counter stats for 'perf sched lat':
        473.564691 task-clock                #    0.999 CPUs utilized
                 9 context-switches          #    0.000 M/sec
                 0 CPU-migrations            #    0.000 M/sec
            20,903 page-faults               #    0.044 M/sec
       944,367,984 cycles                    #    1.994 GHz
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
     1,442,385,571 instructions              #    1.53  insns per cycle
       308,383,106 branches                  #  651.195 M/sec
         4,481,784 branch-misses             #    1.45% of all branches
       0.474215751 seconds time elapsed
[root@emilia ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-1kbzpl74lwi6lavpqke2u2p3@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2011-11-28 17:57:40 -02:00
										 |  |  | #include "util/evlist.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | #include "util/cache.h"
 | 
					
						
							| 
									
										
										
										
											2011-11-16 17:02:54 -02:00
										 |  |  | #include "util/evsel.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | #include "util/symbol.h"
 | 
					
						
							|  |  |  | #include "util/thread.h"
 | 
					
						
							|  |  |  | #include "util/header.h"
 | 
					
						
							| 
									
										
										
										
											2009-12-11 21:24:02 -02:00
										 |  |  | #include "util/session.h"
 | 
					
						
							| 
									
										
										
										
											2011-11-28 08:30:20 -02:00
										 |  |  | #include "util/tool.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-30 22:28:47 +02:00
										 |  |  | #include "util/cloexec.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "util/parse-options.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | #include "util/trace-event.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "util/debug.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | #include <sys/prctl.h>
 | 
					
						
							| 
									
										
										
										
											2012-04-04 10:45:27 +02:00
										 |  |  | #include <sys/resource.h>
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | #include <semaphore.h>
 | 
					
						
							|  |  |  | #include <pthread.h>
 | 
					
						
							|  |  |  | #include <math.h>
 | 
					
						
							| 
									
										
										
										
											2009-09-12 03:59:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | #define PR_SET_NAME		15               /* Set process name */
 | 
					
						
							|  |  |  | #define MAX_CPUS		4096
 | 
					
						
							|  |  |  | #define COMM_LEN		20
 | 
					
						
							|  |  |  | #define SYM_LEN			129
 | 
					
						
							|  |  |  | #define MAX_PID			65536
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | struct sched_atom; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | struct task_desc { | 
					
						
							|  |  |  | 	unsigned long		nr; | 
					
						
							|  |  |  | 	unsigned long		pid; | 
					
						
							|  |  |  | 	char			comm[COMM_LEN]; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	unsigned long		nr_events; | 
					
						
							|  |  |  | 	unsigned long		curr_event; | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	struct sched_atom	**atoms; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	pthread_t		thread; | 
					
						
							|  |  |  | 	sem_t			sleep_sem; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	sem_t			ready_for_work; | 
					
						
							|  |  |  | 	sem_t			work_done_sem; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	u64			cpu_usage; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum sched_event_type { | 
					
						
							|  |  |  | 	SCHED_EVENT_RUN, | 
					
						
							|  |  |  | 	SCHED_EVENT_SLEEP, | 
					
						
							|  |  |  | 	SCHED_EVENT_WAKEUP, | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | 	SCHED_EVENT_MIGRATION, | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | struct sched_atom { | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	enum sched_event_type	type; | 
					
						
							| 
									
										
											  
											
												perf tools: Reorganize some structs to save space
Using 'pahole --packable' I found some structs that could be reorganized
to eliminate alignment holes, in some cases getting them to be cacheline
multiples.
[acme@doppio linux-2.6-tip]$ codiff perf.old ~/bin/perf
builtin-annotate.c:
  struct perf_session    |   -8
  struct perf_header     |   -8
 2 structs changed
builtin-diff.c:
  struct sample_data         |   -8
 1 struct changed
  diff__process_sample_event |   -8
 1 function changed, 8 bytes removed, diff: -8
builtin-sched.c:
  struct sched_atom      |   -8
 1 struct changed
builtin-timechart.c:
  struct per_pid         |   -8
 1 struct changed
  cmd_timechart          |  -16
 1 function changed, 16 bytes removed, diff: -16
builtin-probe.c:
  struct perf_probe_point |   -8
  struct perf_probe_event |   -8
 2 structs changed
  opt_add_probe_event     |   -3
 1 function changed, 3 bytes removed, diff: -3
util/probe-finder.c:
  struct probe_finder      |   -8
 1 struct changed
  find_kprobe_trace_events |  -16
 1 function changed, 16 bytes removed, diff: -16
/home/acme/bin/perf:
 4 functions changed, 43 bytes removed, diff: -43
[acme@doppio linux-2.6-tip]$
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2010-04-05 12:53:45 -03:00
										 |  |  | 	int			specific_wait; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	u64			timestamp; | 
					
						
							|  |  |  | 	u64			duration; | 
					
						
							|  |  |  | 	unsigned long		nr; | 
					
						
							|  |  |  | 	sem_t			*wait_sem; | 
					
						
							|  |  |  | 	struct task_desc	*wakee; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-05 16:05:54 +09:00
										 |  |  | #define TASK_STATE_TO_CHAR_STR "RSDTtZXxKWP"
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | enum thread_state { | 
					
						
							|  |  |  | 	THREAD_SLEEPING = 0, | 
					
						
							|  |  |  | 	THREAD_WAIT_CPU, | 
					
						
							|  |  |  | 	THREAD_SCHED_IN, | 
					
						
							|  |  |  | 	THREAD_IGNORE | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct work_atom { | 
					
						
							|  |  |  | 	struct list_head	list; | 
					
						
							|  |  |  | 	enum thread_state	state; | 
					
						
							| 
									
										
											  
											
												perf tools: Fix processing of randomly serialized sched traces
Currently it's possible to meet such too high latency results
with 'perf sched latency'.
 -----------------------------------------------------------------------------------
 Task              |  Runtime ms | Switches | Average delay ms | Maximum delay ms |
 -----------------------------------------------------------------------------------
 xfce4-panel       |    0.222 ms |        2 | avg: 4718.345 ms | max: 9436.493 ms |
 scsi_eh_3         |    3.962 ms |       36 | avg:   55.957 ms | max: 1977.829 ms |
The origin is on traces that are sometimes badly serialized across cpus.
For example the raw traces that raised such results for xfce4-panel:
(1)          [init]-0     [000]  1494.663899990: sched_switch: task swapper:0 [140] (R) ==> xfce4-panel:4569 [120]
(2)     xfce4-panel-4569  [000]  1494.663928373: sched_switch: task xfce4-panel:4569 [120] (S) ==> swapper:0 [140]
(3)            Xorg-4276  [001]  1494.663860125: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(4)            Xorg-4276  [001]  1504.098252756: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(5)            perf-5219  [000]  1504.100353302: sched_switch: task perf:5219 [120] (S) ==> xfce4-panel:4569 [120]
The traces are processed in the order they arrive. Then in (2),
xfce4-panel sleeps, it is first waken up in (3) and eventually
scheduled in (5).
The latency reported is then 1504 - 1495 = 9 secs, as reported by perf
sched. But this is wrong, we are confident in the fact the traces are
nicely serialized while we should actually more trust the timestamps.
If we reorder by timestamps we get:
(1)            Xorg-4276  [001]  1494.663860125: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(2)          [init]-0     [000]  1494.663899990: sched_switch: task swapper:0 [140] (R) ==> xfce4-panel:4569 [120]
(3)     xfce4-panel-4569  [000]  1494.663928373: sched_switch: task xfce4-panel:4569 [120] (S) ==> swapper:0 [140]
(4)            Xorg-4276  [001]  1504.098252756: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(5)            perf-5219  [000]  1504.100353302: sched_switch: task perf:5219 [120] (S) ==> xfce4-panel:4569 [120]
Now the trace make more sense, xfce4-panel is sleeping. Then it is
woken up in (1), scheduled in (2)
It goes to sleep in (3), woken up in (4) and scheduled in (5).
Now, latency captured between (1) and (2) is of 39 us.
And between (4) and (5) it is 2.1 ms.
Such pattern of bad serializing is the origin of the high latencies
reported by perf sched.
Basically, we need to check whether wake up time is higher than
schedule out time. If it's not the case, we need to tag the current
work atom as invalid.
Beside that, we may need to work later on a better ordering of the
traces given by the kernel.
After this patch:
xfce4-session     |    0.221 ms |        1 | avg:    0.538 ms | max:    0.538 ms |
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-14 03:01:12 +02:00
										 |  |  | 	u64			sched_out_time; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	u64			wake_up_time; | 
					
						
							|  |  |  | 	u64			sched_in_time; | 
					
						
							|  |  |  | 	u64			runtime; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | struct work_atoms { | 
					
						
							|  |  |  | 	struct list_head	work_list; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	struct thread		*thread; | 
					
						
							|  |  |  | 	struct rb_node		node; | 
					
						
							|  |  |  | 	u64			max_lat; | 
					
						
							| 
									
										
										
										
											2009-12-09 21:40:08 +01:00
										 |  |  | 	u64			max_lat_at; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	u64			total_lat; | 
					
						
							|  |  |  | 	u64			nb_atoms; | 
					
						
							|  |  |  | 	u64			total_runtime; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | typedef int (*sort_fn_t)(struct work_atoms *, struct work_atoms *); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | struct perf_sched; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | struct trace_sched_handler { | 
					
						
							|  |  |  | 	int (*switch_event)(struct perf_sched *sched, struct perf_evsel *evsel, | 
					
						
							|  |  |  | 			    struct perf_sample *sample, struct machine *machine); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	int (*runtime_event)(struct perf_sched *sched, struct perf_evsel *evsel, | 
					
						
							|  |  |  | 			     struct perf_sample *sample, struct machine *machine); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	int (*wakeup_event)(struct perf_sched *sched, struct perf_evsel *evsel, | 
					
						
							|  |  |  | 			    struct perf_sample *sample, struct machine *machine); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:47 -04:00
										 |  |  | 	/* PERF_RECORD_FORK event, not sched_process_fork tracepoint */ | 
					
						
							|  |  |  | 	int (*fork_event)(struct perf_sched *sched, union perf_event *event, | 
					
						
							|  |  |  | 			  struct machine *machine); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	int (*migrate_task_event)(struct perf_sched *sched, | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 				  struct perf_evsel *evsel, | 
					
						
							|  |  |  | 				  struct perf_sample *sample, | 
					
						
							|  |  |  | 				  struct machine *machine); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct perf_sched { | 
					
						
							|  |  |  | 	struct perf_tool tool; | 
					
						
							|  |  |  | 	const char	 *sort_order; | 
					
						
							|  |  |  | 	unsigned long	 nr_tasks; | 
					
						
							|  |  |  | 	struct task_desc *pid_to_task[MAX_PID]; | 
					
						
							|  |  |  | 	struct task_desc **tasks; | 
					
						
							|  |  |  | 	const struct trace_sched_handler *tp_handler; | 
					
						
							|  |  |  | 	pthread_mutex_t	 start_work_mutex; | 
					
						
							|  |  |  | 	pthread_mutex_t	 work_done_wait_mutex; | 
					
						
							|  |  |  | 	int		 profile_cpu; | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Track the current task - that way we can know whether there's any | 
					
						
							|  |  |  |  * weird events, such as a task being switched away that is not current. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 	int		 max_cpu; | 
					
						
							|  |  |  | 	u32		 curr_pid[MAX_CPUS]; | 
					
						
							|  |  |  | 	struct thread	 *curr_thread[MAX_CPUS]; | 
					
						
							|  |  |  | 	char		 next_shortname1; | 
					
						
							|  |  |  | 	char		 next_shortname2; | 
					
						
							|  |  |  | 	unsigned int	 replay_repeat; | 
					
						
							|  |  |  | 	unsigned long	 nr_run_events; | 
					
						
							|  |  |  | 	unsigned long	 nr_sleep_events; | 
					
						
							|  |  |  | 	unsigned long	 nr_wakeup_events; | 
					
						
							|  |  |  | 	unsigned long	 nr_sleep_corrections; | 
					
						
							|  |  |  | 	unsigned long	 nr_run_events_optimized; | 
					
						
							|  |  |  | 	unsigned long	 targetless_wakeups; | 
					
						
							|  |  |  | 	unsigned long	 multitarget_wakeups; | 
					
						
							|  |  |  | 	unsigned long	 nr_runs; | 
					
						
							|  |  |  | 	unsigned long	 nr_timestamps; | 
					
						
							|  |  |  | 	unsigned long	 nr_unordered_timestamps; | 
					
						
							|  |  |  | 	unsigned long	 nr_context_switch_bugs; | 
					
						
							|  |  |  | 	unsigned long	 nr_events; | 
					
						
							|  |  |  | 	unsigned long	 nr_lost_chunks; | 
					
						
							|  |  |  | 	unsigned long	 nr_lost_events; | 
					
						
							|  |  |  | 	u64		 run_measurement_overhead; | 
					
						
							|  |  |  | 	u64		 sleep_measurement_overhead; | 
					
						
							|  |  |  | 	u64		 start_time; | 
					
						
							|  |  |  | 	u64		 cpu_usage; | 
					
						
							|  |  |  | 	u64		 runavg_cpu_usage; | 
					
						
							|  |  |  | 	u64		 parent_cpu_usage; | 
					
						
							|  |  |  | 	u64		 runavg_parent_cpu_usage; | 
					
						
							|  |  |  | 	u64		 sum_runtime; | 
					
						
							|  |  |  | 	u64		 sum_fluct; | 
					
						
							|  |  |  | 	u64		 run_avg; | 
					
						
							|  |  |  | 	u64		 all_runtime; | 
					
						
							|  |  |  | 	u64		 all_count; | 
					
						
							|  |  |  | 	u64		 cpu_last_switched[MAX_CPUS]; | 
					
						
							|  |  |  | 	struct rb_root	 atom_root, sorted_atom_root; | 
					
						
							|  |  |  | 	struct list_head sort_list, cmp_pid; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | static u64 get_nsecs(void) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct timespec ts; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	clock_gettime(CLOCK_MONOTONIC, &ts); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ts.tv_sec * 1000000000ULL + ts.tv_nsec; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void burn_nsecs(struct perf_sched *sched, u64 nsecs) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	u64 T0 = get_nsecs(), T1; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	do { | 
					
						
							|  |  |  | 		T1 = get_nsecs(); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	} while (T1 + sched->run_measurement_overhead < T0 + nsecs); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | static void sleep_nsecs(u64 nsecs) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct timespec ts; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ts.tv_nsec = nsecs % 999999999; | 
					
						
							|  |  |  | 	ts.tv_sec = nsecs / 999999999; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	nanosleep(&ts, NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void calibrate_run_measurement_overhead(struct perf_sched *sched) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	u64 T0, T1, delta, min_delta = 1000000000ULL; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < 10; i++) { | 
					
						
							|  |  |  | 		T0 = get_nsecs(); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		burn_nsecs(sched, 0); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		T1 = get_nsecs(); | 
					
						
							|  |  |  | 		delta = T1-T0; | 
					
						
							|  |  |  | 		min_delta = min(min_delta, delta); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->run_measurement_overhead = min_delta; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-22 20:37:02 -02:00
										 |  |  | 	printf("run measurement overhead: %" PRIu64 " nsecs\n", min_delta); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void calibrate_sleep_measurement_overhead(struct perf_sched *sched) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	u64 T0, T1, delta, min_delta = 1000000000ULL; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < 10; i++) { | 
					
						
							|  |  |  | 		T0 = get_nsecs(); | 
					
						
							|  |  |  | 		sleep_nsecs(10000); | 
					
						
							|  |  |  | 		T1 = get_nsecs(); | 
					
						
							|  |  |  | 		delta = T1-T0; | 
					
						
							|  |  |  | 		min_delta = min(min_delta, delta); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	min_delta -= 10000; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->sleep_measurement_overhead = min_delta; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-22 20:37:02 -02:00
										 |  |  | 	printf("sleep measurement overhead: %" PRIu64 " nsecs\n", min_delta); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | static struct sched_atom * | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | get_new_event(struct task_desc *task, u64 timestamp) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-24 12:05:16 -02:00
										 |  |  | 	struct sched_atom *event = zalloc(sizeof(*event)); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	unsigned long idx = task->nr_events; | 
					
						
							|  |  |  | 	size_t size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	event->timestamp = timestamp; | 
					
						
							|  |  |  | 	event->nr = idx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	task->nr_events++; | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	size = sizeof(struct sched_atom *) * task->nr_events; | 
					
						
							|  |  |  | 	task->atoms = realloc(task->atoms, size); | 
					
						
							|  |  |  | 	BUG_ON(!task->atoms); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	task->atoms[idx] = event; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return event; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | static struct sched_atom *last_event(struct task_desc *task) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (!task->nr_events) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	return task->atoms[task->nr_events - 1]; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void add_sched_event_run(struct perf_sched *sched, struct task_desc *task, | 
					
						
							|  |  |  | 				u64 timestamp, u64 duration) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	struct sched_atom *event, *curr_event = last_event(task); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 	 * optimize an existing RUN event by merging this one | 
					
						
							|  |  |  | 	 * to it: | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	if (curr_event && curr_event->type == SCHED_EVENT_RUN) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		sched->nr_run_events_optimized++; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		curr_event->duration += duration; | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	event = get_new_event(task, timestamp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	event->type = SCHED_EVENT_RUN; | 
					
						
							|  |  |  | 	event->duration = duration; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->nr_run_events++; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void add_sched_event_wakeup(struct perf_sched *sched, struct task_desc *task, | 
					
						
							|  |  |  | 				   u64 timestamp, struct task_desc *wakee) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	struct sched_atom *event, *wakee_event; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	event = get_new_event(task, timestamp); | 
					
						
							|  |  |  | 	event->type = SCHED_EVENT_WAKEUP; | 
					
						
							|  |  |  | 	event->wakee = wakee; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wakee_event = last_event(wakee); | 
					
						
							|  |  |  | 	if (!wakee_event || wakee_event->type != SCHED_EVENT_SLEEP) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		sched->targetless_wakeups++; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (wakee_event->wait_sem) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		sched->multitarget_wakeups++; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-24 12:05:16 -02:00
										 |  |  | 	wakee_event->wait_sem = zalloc(sizeof(*wakee_event->wait_sem)); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	sem_init(wakee_event->wait_sem, 0, 0); | 
					
						
							|  |  |  | 	wakee_event->specific_wait = 1; | 
					
						
							|  |  |  | 	event->wait_sem = wakee_event->wait_sem; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->nr_wakeup_events++; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void add_sched_event_sleep(struct perf_sched *sched, struct task_desc *task, | 
					
						
							|  |  |  | 				  u64 timestamp, u64 task_state __maybe_unused) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	struct sched_atom *event = get_new_event(task, timestamp); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	event->type = SCHED_EVENT_SLEEP; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->nr_sleep_events++; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static struct task_desc *register_pid(struct perf_sched *sched, | 
					
						
							|  |  |  | 				      unsigned long pid, const char *comm) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct task_desc *task; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BUG_ON(pid >= MAX_PID); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	task = sched->pid_to_task[pid]; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (task) | 
					
						
							|  |  |  | 		return task; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-24 12:05:16 -02:00
										 |  |  | 	task = zalloc(sizeof(*task)); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	task->pid = pid; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	task->nr = sched->nr_tasks; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	strcpy(task->comm, comm); | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * every task starts in sleeping state - this gets ignored | 
					
						
							|  |  |  | 	 * if there's no wakeup pointing to this sleep state: | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	add_sched_event_sleep(sched, task, 0, 0); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->pid_to_task[pid] = task; | 
					
						
							|  |  |  | 	sched->nr_tasks++; | 
					
						
							|  |  |  | 	sched->tasks = realloc(sched->tasks, sched->nr_tasks * sizeof(struct task_task *)); | 
					
						
							|  |  |  | 	BUG_ON(!sched->tasks); | 
					
						
							|  |  |  | 	sched->tasks[task->nr] = task; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	if (verbose) | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		printf("registered task #%ld, PID %ld (%s)\n", sched->nr_tasks, pid, comm); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return task; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void print_task_traces(struct perf_sched *sched) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct task_desc *task; | 
					
						
							|  |  |  | 	unsigned long i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	for (i = 0; i < sched->nr_tasks; i++) { | 
					
						
							|  |  |  | 		task = sched->tasks[i]; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		printf("task %6ld (%20s:%10ld), nr_events: %ld\n", | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 			task->nr, task->comm, task->pid, task->nr_events); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void add_cross_task_wakeups(struct perf_sched *sched) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct task_desc *task1, *task2; | 
					
						
							|  |  |  | 	unsigned long i, j; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	for (i = 0; i < sched->nr_tasks; i++) { | 
					
						
							|  |  |  | 		task1 = sched->tasks[i]; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		j = i + 1; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		if (j == sched->nr_tasks) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 			j = 0; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		task2 = sched->tasks[j]; | 
					
						
							|  |  |  | 		add_sched_event_wakeup(sched, task1, 0, task2); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void perf_sched__process_event(struct perf_sched *sched, | 
					
						
							|  |  |  | 				      struct sched_atom *atom) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	int ret = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	switch (atom->type) { | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		case SCHED_EVENT_RUN: | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 			burn_nsecs(sched, atom->duration); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case SCHED_EVENT_SLEEP: | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 			if (atom->wait_sem) | 
					
						
							|  |  |  | 				ret = sem_wait(atom->wait_sem); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 			BUG_ON(ret); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SCHED_EVENT_WAKEUP: | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 			if (atom->wait_sem) | 
					
						
							|  |  |  | 				ret = sem_post(atom->wait_sem); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 			BUG_ON(ret); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | 		case SCHED_EVENT_MIGRATION: | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		default: | 
					
						
							|  |  |  | 			BUG_ON(1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | static u64 get_cpu_usage_nsec_parent(void) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct rusage ru; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	u64 sum; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = getrusage(RUSAGE_SELF, &ru); | 
					
						
							|  |  |  | 	BUG_ON(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sum =  ru.ru_utime.tv_sec*1e9 + ru.ru_utime.tv_usec*1e3; | 
					
						
							|  |  |  | 	sum += ru.ru_stime.tv_sec*1e9 + ru.ru_stime.tv_usec*1e3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return sum; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-09 17:51:30 +08:00
										 |  |  | static int self_open_counters(void) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-09 17:51:30 +08:00
										 |  |  | 	struct perf_event_attr attr; | 
					
						
							| 
									
										
										
										
											2014-08-14 02:22:47 +00:00
										 |  |  | 	char sbuf[STRERR_BUFSIZE]; | 
					
						
							| 
									
										
										
										
											2009-12-09 17:51:30 +08:00
										 |  |  | 	int fd; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-09 17:51:30 +08:00
										 |  |  | 	memset(&attr, 0, sizeof(attr)); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-09 17:51:30 +08:00
										 |  |  | 	attr.type = PERF_TYPE_SOFTWARE; | 
					
						
							|  |  |  | 	attr.config = PERF_COUNT_SW_TASK_CLOCK; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 22:28:47 +02:00
										 |  |  | 	fd = sys_perf_event_open(&attr, 0, -1, -1, | 
					
						
							|  |  |  | 				 perf_event_open_cloexec_flag()); | 
					
						
							| 
									
										
										
										
											2009-12-09 17:51:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (fd < 0) | 
					
						
							| 
									
										
										
										
											2012-09-12 11:11:06 +09:00
										 |  |  | 		pr_err("Error: sys_perf_event_open() syscall returned " | 
					
						
							| 
									
										
										
										
											2014-08-14 02:22:47 +00:00
										 |  |  | 		       "with %d (%s)\n", fd, | 
					
						
							|  |  |  | 		       strerror_r(errno, sbuf, sizeof(sbuf))); | 
					
						
							| 
									
										
										
										
											2009-12-09 17:51:30 +08:00
										 |  |  | 	return fd; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static u64 get_cpu_usage_nsec_self(int fd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u64 runtime; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = read(fd, &runtime, sizeof(runtime)); | 
					
						
							|  |  |  | 	BUG_ON(ret != sizeof(runtime)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return runtime; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | struct sched_thread_parms { | 
					
						
							|  |  |  | 	struct task_desc  *task; | 
					
						
							|  |  |  | 	struct perf_sched *sched; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | static void *thread_func(void *ctx) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	struct sched_thread_parms *parms = ctx; | 
					
						
							|  |  |  | 	struct task_desc *this_task = parms->task; | 
					
						
							|  |  |  | 	struct perf_sched *sched = parms->sched; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	u64 cpu_usage_0, cpu_usage_1; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	unsigned long i, ret; | 
					
						
							|  |  |  | 	char comm2[22]; | 
					
						
							| 
									
										
										
										
											2009-12-09 17:51:30 +08:00
										 |  |  | 	int fd; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-27 16:55:14 -03:00
										 |  |  | 	zfree(&parms); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	sprintf(comm2, ":%s", this_task->comm); | 
					
						
							|  |  |  | 	prctl(PR_SET_NAME, comm2); | 
					
						
							| 
									
										
										
										
											2009-12-09 17:51:30 +08:00
										 |  |  | 	fd = self_open_counters(); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	if (fd < 0) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | again: | 
					
						
							|  |  |  | 	ret = sem_post(&this_task->ready_for_work); | 
					
						
							|  |  |  | 	BUG_ON(ret); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	ret = pthread_mutex_lock(&sched->start_work_mutex); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	BUG_ON(ret); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	ret = pthread_mutex_unlock(&sched->start_work_mutex); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	BUG_ON(ret); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-09 17:51:30 +08:00
										 |  |  | 	cpu_usage_0 = get_cpu_usage_nsec_self(fd); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < this_task->nr_events; i++) { | 
					
						
							|  |  |  | 		this_task->curr_event = i; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		perf_sched__process_event(sched, this_task->atoms[i]); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-09 17:51:30 +08:00
										 |  |  | 	cpu_usage_1 = get_cpu_usage_nsec_self(fd); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	this_task->cpu_usage = cpu_usage_1 - cpu_usage_0; | 
					
						
							|  |  |  | 	ret = sem_post(&this_task->work_done_sem); | 
					
						
							|  |  |  | 	BUG_ON(ret); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	ret = pthread_mutex_lock(&sched->work_done_wait_mutex); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	BUG_ON(ret); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	ret = pthread_mutex_unlock(&sched->work_done_wait_mutex); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	BUG_ON(ret); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	goto again; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void create_tasks(struct perf_sched *sched) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct task_desc *task; | 
					
						
							|  |  |  | 	pthread_attr_t attr; | 
					
						
							|  |  |  | 	unsigned long i; | 
					
						
							|  |  |  | 	int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = pthread_attr_init(&attr); | 
					
						
							|  |  |  | 	BUG_ON(err); | 
					
						
							| 
									
										
										
										
											2011-01-10 14:14:23 -02:00
										 |  |  | 	err = pthread_attr_setstacksize(&attr, | 
					
						
							|  |  |  | 			(size_t) max(16 * 1024, PTHREAD_STACK_MIN)); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	BUG_ON(err); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	err = pthread_mutex_lock(&sched->start_work_mutex); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	BUG_ON(err); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	err = pthread_mutex_lock(&sched->work_done_wait_mutex); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	BUG_ON(err); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	for (i = 0; i < sched->nr_tasks; i++) { | 
					
						
							|  |  |  | 		struct sched_thread_parms *parms = malloc(sizeof(*parms)); | 
					
						
							|  |  |  | 		BUG_ON(parms == NULL); | 
					
						
							|  |  |  | 		parms->task = task = sched->tasks[i]; | 
					
						
							|  |  |  | 		parms->sched = sched; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		sem_init(&task->sleep_sem, 0, 0); | 
					
						
							|  |  |  | 		sem_init(&task->ready_for_work, 0, 0); | 
					
						
							|  |  |  | 		sem_init(&task->work_done_sem, 0, 0); | 
					
						
							|  |  |  | 		task->curr_event = 0; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		err = pthread_create(&task->thread, &attr, thread_func, parms); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		BUG_ON(err); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void wait_for_tasks(struct perf_sched *sched) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	u64 cpu_usage_0, cpu_usage_1; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	struct task_desc *task; | 
					
						
							|  |  |  | 	unsigned long i, ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->start_time = get_nsecs(); | 
					
						
							|  |  |  | 	sched->cpu_usage = 0; | 
					
						
							|  |  |  | 	pthread_mutex_unlock(&sched->work_done_wait_mutex); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	for (i = 0; i < sched->nr_tasks; i++) { | 
					
						
							|  |  |  | 		task = sched->tasks[i]; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		ret = sem_wait(&task->ready_for_work); | 
					
						
							|  |  |  | 		BUG_ON(ret); | 
					
						
							|  |  |  | 		sem_init(&task->ready_for_work, 0, 0); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	ret = pthread_mutex_lock(&sched->work_done_wait_mutex); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	BUG_ON(ret); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cpu_usage_0 = get_cpu_usage_nsec_parent(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	pthread_mutex_unlock(&sched->start_work_mutex); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	for (i = 0; i < sched->nr_tasks; i++) { | 
					
						
							|  |  |  | 		task = sched->tasks[i]; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		ret = sem_wait(&task->work_done_sem); | 
					
						
							|  |  |  | 		BUG_ON(ret); | 
					
						
							|  |  |  | 		sem_init(&task->work_done_sem, 0, 0); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		sched->cpu_usage += task->cpu_usage; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		task->cpu_usage = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cpu_usage_1 = get_cpu_usage_nsec_parent(); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	if (!sched->runavg_cpu_usage) | 
					
						
							|  |  |  | 		sched->runavg_cpu_usage = sched->cpu_usage; | 
					
						
							|  |  |  | 	sched->runavg_cpu_usage = (sched->runavg_cpu_usage * 9 + sched->cpu_usage) / 10; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->parent_cpu_usage = cpu_usage_1 - cpu_usage_0; | 
					
						
							|  |  |  | 	if (!sched->runavg_parent_cpu_usage) | 
					
						
							|  |  |  | 		sched->runavg_parent_cpu_usage = sched->parent_cpu_usage; | 
					
						
							|  |  |  | 	sched->runavg_parent_cpu_usage = (sched->runavg_parent_cpu_usage * 9 + | 
					
						
							|  |  |  | 					 sched->parent_cpu_usage)/10; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	ret = pthread_mutex_lock(&sched->start_work_mutex); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	BUG_ON(ret); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	for (i = 0; i < sched->nr_tasks; i++) { | 
					
						
							|  |  |  | 		task = sched->tasks[i]; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		sem_init(&task->sleep_sem, 0, 0); | 
					
						
							|  |  |  | 		task->curr_event = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void run_one_test(struct perf_sched *sched) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-01-24 11:13:04 -05:00
										 |  |  | 	u64 T0, T1, delta, avg_delta, fluct; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	T0 = get_nsecs(); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	wait_for_tasks(sched); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	T1 = get_nsecs(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	delta = T1 - T0; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->sum_runtime += delta; | 
					
						
							|  |  |  | 	sched->nr_runs++; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	avg_delta = sched->sum_runtime / sched->nr_runs; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	if (delta < avg_delta) | 
					
						
							|  |  |  | 		fluct = avg_delta - delta; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		fluct = delta - avg_delta; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->sum_fluct += fluct; | 
					
						
							|  |  |  | 	if (!sched->run_avg) | 
					
						
							|  |  |  | 		sched->run_avg = delta; | 
					
						
							|  |  |  | 	sched->run_avg = (sched->run_avg * 9 + delta) / 10; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	printf("#%-3ld: %0.3f, ", sched->nr_runs, (double)delta / 1000000.0); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	printf("ravg: %0.2f, ", (double)sched->run_avg / 1e6); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	printf("cpu: %0.2f / %0.2f", | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		(double)sched->cpu_usage / 1e6, (double)sched->runavg_cpu_usage / 1e6); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 	 * rusage statistics done by the parent, these are less | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	 * accurate than the sched->sum_exec_runtime based statistics: | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	printf(" [%0.2f / %0.2f]", | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		(double)sched->parent_cpu_usage/1e6, | 
					
						
							|  |  |  | 		(double)sched->runavg_parent_cpu_usage/1e6); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	printf("\n"); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	if (sched->nr_sleep_corrections) | 
					
						
							|  |  |  | 		printf(" (%ld sleep corrections)\n", sched->nr_sleep_corrections); | 
					
						
							|  |  |  | 	sched->nr_sleep_corrections = 0; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void test_calibrations(struct perf_sched *sched) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	u64 T0, T1; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	T0 = get_nsecs(); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	burn_nsecs(sched, 1e6); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	T1 = get_nsecs(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-22 20:37:02 -02:00
										 |  |  | 	printf("the run test took %" PRIu64 " nsecs\n", T1 - T0); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	T0 = get_nsecs(); | 
					
						
							|  |  |  | 	sleep_nsecs(1e6); | 
					
						
							|  |  |  | 	T1 = get_nsecs(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-22 20:37:02 -02:00
										 |  |  | 	printf("the sleep test took %" PRIu64 " nsecs\n", T1 - T0); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | replay_wakeup_event(struct perf_sched *sched, | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 		    struct perf_evsel *evsel, struct perf_sample *sample, | 
					
						
							|  |  |  | 		    struct machine *machine __maybe_unused) | 
					
						
							| 
									
										
										
										
											2009-09-12 03:59:01 +02:00
										 |  |  | { | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	const char *comm = perf_evsel__strval(evsel, sample, "comm"); | 
					
						
							|  |  |  | 	const u32 pid	 = perf_evsel__intval(evsel, sample, "pid"); | 
					
						
							| 
									
										
										
										
											2009-09-12 03:59:01 +02:00
										 |  |  | 	struct task_desc *waker, *wakee; | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	if (verbose) { | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 		printf("sched_wakeup event %p\n", evsel); | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 		printf(" ... pid %d woke up %s/%d\n", sample->tid, comm, pid); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	waker = register_pid(sched, sample->tid, "<unknown>"); | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	wakee = register_pid(sched, pid, comm); | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	add_sched_event_wakeup(sched, waker, sample->time, wakee); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | static int replay_switch_event(struct perf_sched *sched, | 
					
						
							|  |  |  | 			       struct perf_evsel *evsel, | 
					
						
							|  |  |  | 			       struct perf_sample *sample, | 
					
						
							|  |  |  | 			       struct machine *machine __maybe_unused) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	const char *prev_comm  = perf_evsel__strval(evsel, sample, "prev_comm"), | 
					
						
							|  |  |  | 		   *next_comm  = perf_evsel__strval(evsel, sample, "next_comm"); | 
					
						
							|  |  |  | 	const u32 prev_pid = perf_evsel__intval(evsel, sample, "prev_pid"), | 
					
						
							|  |  |  | 		  next_pid = perf_evsel__intval(evsel, sample, "next_pid"); | 
					
						
							|  |  |  | 	const u64 prev_state = perf_evsel__intval(evsel, sample, "prev_state"); | 
					
						
							| 
									
										
										
										
											2012-09-11 01:15:03 +03:00
										 |  |  | 	struct task_desc *prev, __maybe_unused *next; | 
					
						
							| 
									
										
										
										
											2012-08-07 11:33:42 -03:00
										 |  |  | 	u64 timestamp0, timestamp = sample->time; | 
					
						
							|  |  |  | 	int cpu = sample->cpu; | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 	s64 delta; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	if (verbose) | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 		printf("sched_switch event %p\n", evsel); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 	if (cpu >= MAX_CPUS || cpu < 0) | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	timestamp0 = sched->cpu_last_switched[cpu]; | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 	if (timestamp0) | 
					
						
							|  |  |  | 		delta = timestamp - timestamp0; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		delta = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	if (delta < 0) { | 
					
						
							| 
									
										
										
										
											2012-09-12 11:11:06 +09:00
										 |  |  | 		pr_err("hm, delta: %" PRIu64 " < 0 ?\n", delta); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	pr_debug(" ... switch from %s/%d to %s/%d [ran %" PRIu64 " nsecs]\n", | 
					
						
							|  |  |  | 		 prev_comm, prev_pid, next_comm, next_pid, delta); | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	prev = register_pid(sched, prev_pid, prev_comm); | 
					
						
							|  |  |  | 	next = register_pid(sched, next_pid, next_comm); | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->cpu_last_switched[cpu] = timestamp; | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	add_sched_event_run(sched, prev, timestamp, delta); | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	add_sched_event_sleep(sched, prev, timestamp, prev_state); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:47 -04:00
										 |  |  | static int replay_fork_event(struct perf_sched *sched, | 
					
						
							|  |  |  | 			     union perf_event *event, | 
					
						
							|  |  |  | 			     struct machine *machine) | 
					
						
							| 
									
										
										
										
											2009-09-12 03:59:01 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:47 -04:00
										 |  |  | 	struct thread *child, *parent; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-27 11:23:03 +03:00
										 |  |  | 	child = machine__findnew_thread(machine, event->fork.pid, | 
					
						
							|  |  |  | 					event->fork.tid); | 
					
						
							|  |  |  | 	parent = machine__findnew_thread(machine, event->fork.ppid, | 
					
						
							|  |  |  | 					 event->fork.ptid); | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (child == NULL || parent == NULL) { | 
					
						
							|  |  |  | 		pr_debug("thread does not exist on fork event: child %p, parent %p\n", | 
					
						
							|  |  |  | 				 child, parent); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-12 03:59:01 +02:00
										 |  |  | 	if (verbose) { | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:47 -04:00
										 |  |  | 		printf("fork event\n"); | 
					
						
							| 
									
										
										
										
											2013-09-11 14:46:56 +02:00
										 |  |  | 		printf("... parent: %s/%d\n", thread__comm_str(parent), parent->tid); | 
					
						
							|  |  |  | 		printf("...  child: %s/%d\n", thread__comm_str(child), child->tid); | 
					
						
							| 
									
										
										
										
											2009-09-12 03:59:01 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 14:46:56 +02:00
										 |  |  | 	register_pid(sched, parent->tid, thread__comm_str(parent)); | 
					
						
							|  |  |  | 	register_pid(sched, child->tid, thread__comm_str(child)); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-12 03:59:01 +02:00
										 |  |  | } | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | struct sort_dimension { | 
					
						
							|  |  |  | 	const char		*name; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	sort_fn_t		cmp; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	struct list_head	list; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | thread_lat_cmp(struct list_head *list, struct work_atoms *l, struct work_atoms *r) | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct sort_dimension *sort; | 
					
						
							|  |  |  | 	int ret = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	BUG_ON(list_empty(list)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 	list_for_each_entry(sort, list, list) { | 
					
						
							|  |  |  | 		ret = sort->cmp(l, r); | 
					
						
							|  |  |  | 		if (ret) | 
					
						
							|  |  |  | 			return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | static struct work_atoms * | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | thread_atoms_search(struct rb_root *root, struct thread *thread, | 
					
						
							|  |  |  | 			 struct list_head *sort_list) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct rb_node *node = root->rb_node; | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	struct work_atoms key = { .thread = thread }; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while (node) { | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 		struct work_atoms *atoms; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		int cmp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 		atoms = container_of(node, struct work_atoms, node); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		cmp = thread_lat_cmp(sort_list, &key, atoms); | 
					
						
							|  |  |  | 		if (cmp > 0) | 
					
						
							|  |  |  | 			node = node->rb_left; | 
					
						
							|  |  |  | 		else if (cmp < 0) | 
					
						
							|  |  |  | 			node = node->rb_right; | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			BUG_ON(thread != atoms->thread); | 
					
						
							|  |  |  | 			return atoms; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | __thread_latency_insert(struct rb_root *root, struct work_atoms *data, | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 			 struct list_head *sort_list) | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct rb_node **new = &(root->rb_node), *parent = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (*new) { | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 		struct work_atoms *this; | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 		int cmp; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 		this = container_of(*new, struct work_atoms, node); | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 		parent = *new; | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		cmp = thread_lat_cmp(sort_list, data, this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (cmp > 0) | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 			new = &((*new)->rb_left); | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 			new = &((*new)->rb_right); | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rb_link_node(&data->node, parent, new); | 
					
						
							|  |  |  | 	rb_insert_color(&data->node, root); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static int thread_atoms_insert(struct perf_sched *sched, struct thread *thread) | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-24 12:05:16 -02:00
										 |  |  | 	struct work_atoms *atoms = zalloc(sizeof(*atoms)); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	if (!atoms) { | 
					
						
							|  |  |  | 		pr_err("No memory at %s\n", __func__); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-12 23:11:32 +02:00
										 |  |  | 	atoms->thread = thread; | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	INIT_LIST_HEAD(&atoms->work_list); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	__thread_latency_insert(&sched->atom_root, atoms, &sched->cmp_pid); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | static char sched_out_state(u64 prev_state) | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	const char *str = TASK_STATE_TO_CHAR_STR; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	return str[prev_state]; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | add_sched_out_event(struct work_atoms *atoms, | 
					
						
							|  |  |  | 		    char run_state, | 
					
						
							|  |  |  | 		    u64 timestamp) | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-24 12:05:16 -02:00
										 |  |  | 	struct work_atom *atom = zalloc(sizeof(*atom)); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	if (!atom) { | 
					
						
							|  |  |  | 		pr_err("Non memory at %s", __func__); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf tools: Fix processing of randomly serialized sched traces
Currently it's possible to meet such too high latency results
with 'perf sched latency'.
 -----------------------------------------------------------------------------------
 Task              |  Runtime ms | Switches | Average delay ms | Maximum delay ms |
 -----------------------------------------------------------------------------------
 xfce4-panel       |    0.222 ms |        2 | avg: 4718.345 ms | max: 9436.493 ms |
 scsi_eh_3         |    3.962 ms |       36 | avg:   55.957 ms | max: 1977.829 ms |
The origin is on traces that are sometimes badly serialized across cpus.
For example the raw traces that raised such results for xfce4-panel:
(1)          [init]-0     [000]  1494.663899990: sched_switch: task swapper:0 [140] (R) ==> xfce4-panel:4569 [120]
(2)     xfce4-panel-4569  [000]  1494.663928373: sched_switch: task xfce4-panel:4569 [120] (S) ==> swapper:0 [140]
(3)            Xorg-4276  [001]  1494.663860125: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(4)            Xorg-4276  [001]  1504.098252756: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(5)            perf-5219  [000]  1504.100353302: sched_switch: task perf:5219 [120] (S) ==> xfce4-panel:4569 [120]
The traces are processed in the order they arrive. Then in (2),
xfce4-panel sleeps, it is first waken up in (3) and eventually
scheduled in (5).
The latency reported is then 1504 - 1495 = 9 secs, as reported by perf
sched. But this is wrong, we are confident in the fact the traces are
nicely serialized while we should actually more trust the timestamps.
If we reorder by timestamps we get:
(1)            Xorg-4276  [001]  1494.663860125: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(2)          [init]-0     [000]  1494.663899990: sched_switch: task swapper:0 [140] (R) ==> xfce4-panel:4569 [120]
(3)     xfce4-panel-4569  [000]  1494.663928373: sched_switch: task xfce4-panel:4569 [120] (S) ==> swapper:0 [140]
(4)            Xorg-4276  [001]  1504.098252756: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(5)            perf-5219  [000]  1504.100353302: sched_switch: task perf:5219 [120] (S) ==> xfce4-panel:4569 [120]
Now the trace make more sense, xfce4-panel is sleeping. Then it is
woken up in (1), scheduled in (2)
It goes to sleep in (3), woken up in (4) and scheduled in (5).
Now, latency captured between (1) and (2) is of 39 us.
And between (4) and (5) it is 2.1 ms.
Such pattern of bad serializing is the origin of the high latencies
reported by perf sched.
Basically, we need to check whether wake up time is higher than
schedule out time. If it's not the case, we need to tag the current
work atom as invalid.
Beside that, we may need to work later on a better ordering of the
traces given by the kernel.
After this patch:
xfce4-session     |    0.221 ms |        1 | avg:    0.538 ms | max:    0.538 ms |
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-14 03:01:12 +02:00
										 |  |  | 	atom->sched_out_time = timestamp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	if (run_state == 'R') { | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		atom->state = THREAD_WAIT_CPU; | 
					
						
							| 
									
										
											  
											
												perf tools: Fix processing of randomly serialized sched traces
Currently it's possible to meet such too high latency results
with 'perf sched latency'.
 -----------------------------------------------------------------------------------
 Task              |  Runtime ms | Switches | Average delay ms | Maximum delay ms |
 -----------------------------------------------------------------------------------
 xfce4-panel       |    0.222 ms |        2 | avg: 4718.345 ms | max: 9436.493 ms |
 scsi_eh_3         |    3.962 ms |       36 | avg:   55.957 ms | max: 1977.829 ms |
The origin is on traces that are sometimes badly serialized across cpus.
For example the raw traces that raised such results for xfce4-panel:
(1)          [init]-0     [000]  1494.663899990: sched_switch: task swapper:0 [140] (R) ==> xfce4-panel:4569 [120]
(2)     xfce4-panel-4569  [000]  1494.663928373: sched_switch: task xfce4-panel:4569 [120] (S) ==> swapper:0 [140]
(3)            Xorg-4276  [001]  1494.663860125: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(4)            Xorg-4276  [001]  1504.098252756: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(5)            perf-5219  [000]  1504.100353302: sched_switch: task perf:5219 [120] (S) ==> xfce4-panel:4569 [120]
The traces are processed in the order they arrive. Then in (2),
xfce4-panel sleeps, it is first waken up in (3) and eventually
scheduled in (5).
The latency reported is then 1504 - 1495 = 9 secs, as reported by perf
sched. But this is wrong, we are confident in the fact the traces are
nicely serialized while we should actually more trust the timestamps.
If we reorder by timestamps we get:
(1)            Xorg-4276  [001]  1494.663860125: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(2)          [init]-0     [000]  1494.663899990: sched_switch: task swapper:0 [140] (R) ==> xfce4-panel:4569 [120]
(3)     xfce4-panel-4569  [000]  1494.663928373: sched_switch: task xfce4-panel:4569 [120] (S) ==> swapper:0 [140]
(4)            Xorg-4276  [001]  1504.098252756: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(5)            perf-5219  [000]  1504.100353302: sched_switch: task perf:5219 [120] (S) ==> xfce4-panel:4569 [120]
Now the trace make more sense, xfce4-panel is sleeping. Then it is
woken up in (1), scheduled in (2)
It goes to sleep in (3), woken up in (4) and scheduled in (5).
Now, latency captured between (1) and (2) is of 39 us.
And between (4) and (5) it is 2.1 ms.
Such pattern of bad serializing is the origin of the high latencies
reported by perf sched.
Basically, we need to check whether wake up time is higher than
schedule out time. If it's not the case, we need to tag the current
work atom as invalid.
Beside that, we may need to work later on a better ordering of the
traces given by the kernel.
After this patch:
xfce4-session     |    0.221 ms |        1 | avg:    0.538 ms | max:    0.538 ms |
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-14 03:01:12 +02:00
										 |  |  | 		atom->wake_up_time = atom->sched_out_time; | 
					
						
							| 
									
										
										
										
											2009-09-13 00:46:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	list_add_tail(&atom->list, &atoms->work_list); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2012-09-11 01:15:03 +03:00
										 |  |  | add_runtime_event(struct work_atoms *atoms, u64 delta, | 
					
						
							|  |  |  | 		  u64 timestamp __maybe_unused) | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct work_atom *atom; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BUG_ON(list_empty(&atoms->work_list)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	atom = list_entry(atoms->work_list.prev, struct work_atom, list); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	atom->runtime += delta; | 
					
						
							|  |  |  | 	atoms->total_runtime += delta; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | add_sched_in_event(struct work_atoms *atoms, u64 timestamp) | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	struct work_atom *atom; | 
					
						
							| 
									
										
										
										
											2009-09-13 01:56:25 +02:00
										 |  |  | 	u64 delta; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	if (list_empty(&atoms->work_list)) | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	atom = list_entry(atoms->work_list.prev, struct work_atom, list); | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	if (atom->state != THREAD_WAIT_CPU) | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	if (timestamp < atom->wake_up_time) { | 
					
						
							|  |  |  | 		atom->state = THREAD_IGNORE; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	atom->state = THREAD_SCHED_IN; | 
					
						
							|  |  |  | 	atom->sched_in_time = timestamp; | 
					
						
							| 
									
										
										
										
											2009-09-13 01:56:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	delta = atom->sched_in_time - atom->wake_up_time; | 
					
						
							| 
									
										
										
										
											2009-09-13 01:56:25 +02:00
										 |  |  | 	atoms->total_lat += delta; | 
					
						
							| 
									
										
										
										
											2009-12-09 21:40:08 +01:00
										 |  |  | 	if (delta > atoms->max_lat) { | 
					
						
							| 
									
										
										
										
											2009-09-13 01:56:25 +02:00
										 |  |  | 		atoms->max_lat = delta; | 
					
						
							| 
									
										
										
										
											2009-12-09 21:40:08 +01:00
										 |  |  | 		atoms->max_lat_at = timestamp; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-09-13 01:56:25 +02:00
										 |  |  | 	atoms->nb_atoms++; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | static int latency_switch_event(struct perf_sched *sched, | 
					
						
							|  |  |  | 				struct perf_evsel *evsel, | 
					
						
							|  |  |  | 				struct perf_sample *sample, | 
					
						
							|  |  |  | 				struct machine *machine) | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	const u32 prev_pid = perf_evsel__intval(evsel, sample, "prev_pid"), | 
					
						
							|  |  |  | 		  next_pid = perf_evsel__intval(evsel, sample, "next_pid"); | 
					
						
							|  |  |  | 	const u64 prev_state = perf_evsel__intval(evsel, sample, "prev_state"); | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	struct work_atoms *out_events, *in_events; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 	struct thread *sched_out, *sched_in; | 
					
						
							| 
									
										
										
										
											2012-08-07 11:33:42 -03:00
										 |  |  | 	u64 timestamp0, timestamp = sample->time; | 
					
						
							|  |  |  | 	int cpu = sample->cpu; | 
					
						
							| 
									
										
										
										
											2009-09-12 10:08:34 +02:00
										 |  |  | 	s64 delta; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	BUG_ON(cpu >= MAX_CPUS || cpu < 0); | 
					
						
							| 
									
										
										
										
											2009-09-12 10:08:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	timestamp0 = sched->cpu_last_switched[cpu]; | 
					
						
							|  |  |  | 	sched->cpu_last_switched[cpu] = timestamp; | 
					
						
							| 
									
										
										
										
											2009-09-12 10:08:34 +02:00
										 |  |  | 	if (timestamp0) | 
					
						
							|  |  |  | 		delta = timestamp - timestamp0; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		delta = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	if (delta < 0) { | 
					
						
							|  |  |  | 		pr_err("hm, delta: %" PRIu64 " < 0 ?\n", delta); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-14 13:02:25 +03:00
										 |  |  | 	sched_out = machine__findnew_thread(machine, -1, prev_pid); | 
					
						
							|  |  |  | 	sched_in = machine__findnew_thread(machine, -1, next_pid); | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	out_events = thread_atoms_search(&sched->atom_root, sched_out, &sched->cmp_pid); | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	if (!out_events) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		if (thread_atoms_insert(sched, sched_out)) | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		out_events = thread_atoms_search(&sched->atom_root, sched_out, &sched->cmp_pid); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		if (!out_events) { | 
					
						
							|  |  |  | 			pr_err("out-event: Internal tree error"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	if (add_sched_out_event(out_events, sched_out_state(prev_state), timestamp)) | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	in_events = thread_atoms_search(&sched->atom_root, sched_in, &sched->cmp_pid); | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	if (!in_events) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		if (thread_atoms_insert(sched, sched_in)) | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		in_events = thread_atoms_search(&sched->atom_root, sched_in, &sched->cmp_pid); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		if (!in_events) { | 
					
						
							|  |  |  | 			pr_err("in-event: Internal tree error"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * Take came in we have not heard about yet, | 
					
						
							|  |  |  | 		 * add in an initial atom in runnable state: | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		if (add_sched_out_event(in_events, 'R', timestamp)) | 
					
						
							|  |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	add_sched_in_event(in_events, timestamp); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | static int latency_runtime_event(struct perf_sched *sched, | 
					
						
							|  |  |  | 				 struct perf_evsel *evsel, | 
					
						
							|  |  |  | 				 struct perf_sample *sample, | 
					
						
							|  |  |  | 				 struct machine *machine) | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | { | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	const u32 pid	   = perf_evsel__intval(evsel, sample, "pid"); | 
					
						
							|  |  |  | 	const u64 runtime  = perf_evsel__intval(evsel, sample, "runtime"); | 
					
						
							| 
									
										
										
										
											2014-07-14 13:02:25 +03:00
										 |  |  | 	struct thread *thread = machine__findnew_thread(machine, -1, pid); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	struct work_atoms *atoms = thread_atoms_search(&sched->atom_root, thread, &sched->cmp_pid); | 
					
						
							| 
									
										
										
										
											2012-08-07 11:33:42 -03:00
										 |  |  | 	u64 timestamp = sample->time; | 
					
						
							|  |  |  | 	int cpu = sample->cpu; | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	BUG_ON(cpu >= MAX_CPUS || cpu < 0); | 
					
						
							|  |  |  | 	if (!atoms) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		if (thread_atoms_insert(sched, thread)) | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		atoms = thread_atoms_search(&sched->atom_root, thread, &sched->cmp_pid); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		if (!atoms) { | 
					
						
							| 
									
										
										
										
											2012-09-12 11:11:06 +09:00
										 |  |  | 			pr_err("in-event: Internal tree error"); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (add_sched_out_event(atoms, 'R', timestamp)) | 
					
						
							|  |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	add_runtime_event(atoms, runtime, timestamp); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | static int latency_wakeup_event(struct perf_sched *sched, | 
					
						
							|  |  |  | 				struct perf_evsel *evsel, | 
					
						
							|  |  |  | 				struct perf_sample *sample, | 
					
						
							|  |  |  | 				struct machine *machine) | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-05-12 20:19:46 +02:00
										 |  |  | 	const u32 pid	  = perf_evsel__intval(evsel, sample, "pid"); | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	struct work_atoms *atoms; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	struct work_atom *atom; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 	struct thread *wakee; | 
					
						
							| 
									
										
										
										
											2012-08-07 11:33:42 -03:00
										 |  |  | 	u64 timestamp = sample->time; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-14 13:02:25 +03:00
										 |  |  | 	wakee = machine__findnew_thread(machine, -1, pid); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	atoms = thread_atoms_search(&sched->atom_root, wakee, &sched->cmp_pid); | 
					
						
							| 
									
										
										
										
											2009-09-12 23:11:32 +02:00
										 |  |  | 	if (!atoms) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		if (thread_atoms_insert(sched, wakee)) | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		atoms = thread_atoms_search(&sched->atom_root, wakee, &sched->cmp_pid); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		if (!atoms) { | 
					
						
							| 
									
										
										
										
											2012-09-12 11:11:06 +09:00
										 |  |  | 			pr_err("wakeup-event: Internal tree error"); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (add_sched_out_event(atoms, 'S', timestamp)) | 
					
						
							|  |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	BUG_ON(list_empty(&atoms->work_list)); | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	atom = list_entry(atoms->work_list.prev, struct work_atom, list); | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | 	/*
 | 
					
						
							| 
									
										
										
										
											2014-05-13 10:38:21 +09:00
										 |  |  | 	 * As we do not guarantee the wakeup event happens when | 
					
						
							|  |  |  | 	 * task is out of run queue, also may happen when task is | 
					
						
							|  |  |  | 	 * on run queue and wakeup only change ->state to TASK_RUNNING, | 
					
						
							|  |  |  | 	 * then we should not set the ->wake_up_time when wake up a | 
					
						
							|  |  |  | 	 * task which is on run queue. | 
					
						
							|  |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | 	 * You WILL be missing events if you've recorded only | 
					
						
							|  |  |  | 	 * one CPU, or are only looking at only one, so don't | 
					
						
							| 
									
										
										
										
											2014-05-13 10:38:21 +09:00
										 |  |  | 	 * skip in this case. | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	if (sched->profile_cpu == -1 && atom->state != THREAD_SLEEPING) | 
					
						
							| 
									
										
										
										
											2014-05-13 10:38:21 +09:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->nr_timestamps++; | 
					
						
							| 
									
										
										
										
											2009-09-13 18:15:54 +02:00
										 |  |  | 	if (atom->sched_out_time > timestamp) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		sched->nr_unordered_timestamps++; | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2009-09-13 18:15:54 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
											  
											
												perf tools: Fix processing of randomly serialized sched traces
Currently it's possible to meet such too high latency results
with 'perf sched latency'.
 -----------------------------------------------------------------------------------
 Task              |  Runtime ms | Switches | Average delay ms | Maximum delay ms |
 -----------------------------------------------------------------------------------
 xfce4-panel       |    0.222 ms |        2 | avg: 4718.345 ms | max: 9436.493 ms |
 scsi_eh_3         |    3.962 ms |       36 | avg:   55.957 ms | max: 1977.829 ms |
The origin is on traces that are sometimes badly serialized across cpus.
For example the raw traces that raised such results for xfce4-panel:
(1)          [init]-0     [000]  1494.663899990: sched_switch: task swapper:0 [140] (R) ==> xfce4-panel:4569 [120]
(2)     xfce4-panel-4569  [000]  1494.663928373: sched_switch: task xfce4-panel:4569 [120] (S) ==> swapper:0 [140]
(3)            Xorg-4276  [001]  1494.663860125: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(4)            Xorg-4276  [001]  1504.098252756: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(5)            perf-5219  [000]  1504.100353302: sched_switch: task perf:5219 [120] (S) ==> xfce4-panel:4569 [120]
The traces are processed in the order they arrive. Then in (2),
xfce4-panel sleeps, it is first waken up in (3) and eventually
scheduled in (5).
The latency reported is then 1504 - 1495 = 9 secs, as reported by perf
sched. But this is wrong, we are confident in the fact the traces are
nicely serialized while we should actually more trust the timestamps.
If we reorder by timestamps we get:
(1)            Xorg-4276  [001]  1494.663860125: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(2)          [init]-0     [000]  1494.663899990: sched_switch: task swapper:0 [140] (R) ==> xfce4-panel:4569 [120]
(3)     xfce4-panel-4569  [000]  1494.663928373: sched_switch: task xfce4-panel:4569 [120] (S) ==> swapper:0 [140]
(4)            Xorg-4276  [001]  1504.098252756: sched_wakeup: task xfce4-panel:4569 [120] success=1 [000]
(5)            perf-5219  [000]  1504.100353302: sched_switch: task perf:5219 [120] (S) ==> xfce4-panel:4569 [120]
Now the trace make more sense, xfce4-panel is sleeping. Then it is
woken up in (1), scheduled in (2)
It goes to sleep in (3), woken up in (4) and scheduled in (5).
Now, latency captured between (1) and (2) is of 39 us.
And between (4) and (5) it is 2.1 ms.
Such pattern of bad serializing is the origin of the high latencies
reported by perf sched.
Basically, we need to check whether wake up time is higher than
schedule out time. If it's not the case, we need to tag the current
work atom as invalid.
Beside that, we may need to work later on a better ordering of the
traces given by the kernel.
After this patch:
xfce4-session     |    0.221 ms |        1 | avg:    0.538 ms | max:    0.538 ms |
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-14 03:01:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	atom->state = THREAD_WAIT_CPU; | 
					
						
							|  |  |  | 	atom->wake_up_time = timestamp; | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | static int latency_migrate_task_event(struct perf_sched *sched, | 
					
						
							|  |  |  | 				      struct perf_evsel *evsel, | 
					
						
							|  |  |  | 				      struct perf_sample *sample, | 
					
						
							|  |  |  | 				      struct machine *machine) | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	const u32 pid = perf_evsel__intval(evsel, sample, "pid"); | 
					
						
							| 
									
										
										
										
											2012-08-07 11:33:42 -03:00
										 |  |  | 	u64 timestamp = sample->time; | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | 	struct work_atoms *atoms; | 
					
						
							|  |  |  | 	struct work_atom *atom; | 
					
						
							|  |  |  | 	struct thread *migrant; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Only need to worry about migration when profiling one CPU. | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	if (sched->profile_cpu == -1) | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-14 13:02:25 +03:00
										 |  |  | 	migrant = machine__findnew_thread(machine, -1, pid); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid); | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | 	if (!atoms) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		if (thread_atoms_insert(sched, migrant)) | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2013-09-11 14:46:56 +02:00
										 |  |  | 		register_pid(sched, migrant->tid, thread__comm_str(migrant)); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		if (!atoms) { | 
					
						
							| 
									
										
										
										
											2012-09-12 11:11:06 +09:00
										 |  |  | 			pr_err("migration-event: Internal tree error"); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (add_sched_out_event(atoms, 'R', timestamp)) | 
					
						
							|  |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BUG_ON(list_empty(&atoms->work_list)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	atom = list_entry(atoms->work_list.prev, struct work_atom, list); | 
					
						
							|  |  |  | 	atom->sched_in_time = atom->sched_out_time = atom->wake_up_time = timestamp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->nr_timestamps++; | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (atom->sched_out_time > timestamp) | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		sched->nr_unordered_timestamps++; | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void output_lat_thread(struct perf_sched *sched, struct work_atoms *work_list) | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							| 
									
										
										
										
											2009-09-13 01:56:25 +02:00
										 |  |  | 	u64 avg; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	if (!work_list->nb_atoms) | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2009-09-13 18:15:54 +02:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Ignore idle threads: | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2013-09-11 14:46:56 +02:00
										 |  |  | 	if (!strcmp(thread__comm_str(work_list->thread), "swapper")) | 
					
						
							| 
									
										
										
										
											2009-09-13 18:15:54 +02:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->all_runtime += work_list->total_runtime; | 
					
						
							|  |  |  | 	sched->all_count   += work_list->nb_atoms; | 
					
						
							| 
									
										
										
										
											2009-09-13 01:56:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 14:46:56 +02:00
										 |  |  | 	ret = printf("  %s:%d ", thread__comm_str(work_list->thread), work_list->thread->tid); | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 18:30:44 +02:00
										 |  |  | 	for (i = 0; i < 24 - ret; i++) | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 		printf(" "); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	avg = work_list->total_lat / work_list->nb_atoms; | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-17 10:18:21 -04:00
										 |  |  | 	printf("|%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max at: %13.6f s\n", | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 	      (double)work_list->total_runtime / 1e6, | 
					
						
							|  |  |  | 		 work_list->nb_atoms, (double)avg / 1e6, | 
					
						
							| 
									
										
										
										
											2009-12-09 21:40:08 +01:00
										 |  |  | 		 (double)work_list->max_lat / 1e6, | 
					
						
							|  |  |  | 		 (double)work_list->max_lat_at / 1e9); | 
					
						
							| 
									
										
										
										
											2009-09-12 08:06:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | static int pid_cmp(struct work_atoms *l, struct work_atoms *r) | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-04 16:20:31 +03:00
										 |  |  | 	if (l->thread->tid < r->thread->tid) | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2013-07-04 16:20:31 +03:00
										 |  |  | 	if (l->thread->tid > r->thread->tid) | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 		return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | static int avg_cmp(struct work_atoms *l, struct work_atoms *r) | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	u64 avgl, avgr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!l->nb_atoms) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!r->nb_atoms) | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	avgl = l->total_lat / l->nb_atoms; | 
					
						
							|  |  |  | 	avgr = r->total_lat / r->nb_atoms; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (avgl < avgr) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	if (avgl > avgr) | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | static int max_cmp(struct work_atoms *l, struct work_atoms *r) | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (l->max_lat < r->max_lat) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	if (l->max_lat > r->max_lat) | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | static int switch_cmp(struct work_atoms *l, struct work_atoms *r) | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (l->nb_atoms < r->nb_atoms) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	if (l->nb_atoms > r->nb_atoms) | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | static int runtime_cmp(struct work_atoms *l, struct work_atoms *r) | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (l->total_runtime < r->total_runtime) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	if (l->total_runtime > r->total_runtime) | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 13:17:29 -07:00
										 |  |  | static int sort_dimension__add(const char *tok, struct list_head *list) | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	size_t i; | 
					
						
							|  |  |  | 	static struct sort_dimension avg_sort_dimension = { | 
					
						
							|  |  |  | 		.name = "avg", | 
					
						
							|  |  |  | 		.cmp  = avg_cmp, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	static struct sort_dimension max_sort_dimension = { | 
					
						
							|  |  |  | 		.name = "max", | 
					
						
							|  |  |  | 		.cmp  = max_cmp, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	static struct sort_dimension pid_sort_dimension = { | 
					
						
							|  |  |  | 		.name = "pid", | 
					
						
							|  |  |  | 		.cmp  = pid_cmp, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	static struct sort_dimension runtime_sort_dimension = { | 
					
						
							|  |  |  | 		.name = "runtime", | 
					
						
							|  |  |  | 		.cmp  = runtime_cmp, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	static struct sort_dimension switch_sort_dimension = { | 
					
						
							|  |  |  | 		.name = "switch", | 
					
						
							|  |  |  | 		.cmp  = switch_cmp, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	struct sort_dimension *available_sorts[] = { | 
					
						
							|  |  |  | 		&pid_sort_dimension, | 
					
						
							|  |  |  | 		&avg_sort_dimension, | 
					
						
							|  |  |  | 		&max_sort_dimension, | 
					
						
							|  |  |  | 		&switch_sort_dimension, | 
					
						
							|  |  |  | 		&runtime_sort_dimension, | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	for (i = 0; i < ARRAY_SIZE(available_sorts); i++) { | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 		if (!strcmp(available_sorts[i]->name, tok)) { | 
					
						
							|  |  |  | 			list_add_tail(&available_sorts[i]->list, list); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void perf_sched__sort_lat(struct perf_sched *sched) | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct rb_node *node; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 		struct work_atoms *data; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		node = rb_first(&sched->atom_root); | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 		if (!node) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		rb_erase(node, &sched->atom_root); | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 		data = rb_entry(node, struct work_atoms, node); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		__thread_latency_insert(&sched->sorted_atom_root, data, &sched->sort_list); | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static int process_sched_wakeup_event(struct perf_tool *tool, | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 				      struct perf_evsel *evsel, | 
					
						
							| 
									
										
										
										
											2012-09-11 01:15:03 +03:00
										 |  |  | 				      struct perf_sample *sample, | 
					
						
							| 
									
										
										
										
											2012-09-11 13:18:47 -03:00
										 |  |  | 				      struct machine *machine) | 
					
						
							| 
									
										
										
										
											2009-09-12 03:59:01 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	struct perf_sched *sched = container_of(tool, struct perf_sched, tool); | 
					
						
							| 
									
										
										
										
											2009-09-12 03:59:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	if (sched->tp_handler->wakeup_event) | 
					
						
							|  |  |  | 		return sched->tp_handler->wakeup_event(sched, evsel, sample, machine); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-12 03:59:01 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, | 
					
						
							|  |  |  | 			    struct perf_sample *sample, struct machine *machine) | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-05-16 14:37:05 +09:00
										 |  |  | 	const u32 next_pid = perf_evsel__intval(evsel, sample, "next_pid"); | 
					
						
							|  |  |  | 	struct thread *sched_in; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 	int new_shortname; | 
					
						
							| 
									
										
										
										
											2012-08-07 11:33:42 -03:00
										 |  |  | 	u64 timestamp0, timestamp = sample->time; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 	s64 delta; | 
					
						
							| 
									
										
										
										
											2012-08-07 11:33:42 -03:00
										 |  |  | 	int cpu, this_cpu = sample->cpu; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	if (this_cpu > sched->max_cpu) | 
					
						
							|  |  |  | 		sched->max_cpu = this_cpu; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	timestamp0 = sched->cpu_last_switched[this_cpu]; | 
					
						
							|  |  |  | 	sched->cpu_last_switched[this_cpu] = timestamp; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 	if (timestamp0) | 
					
						
							|  |  |  | 		delta = timestamp - timestamp0; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		delta = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	if (delta < 0) { | 
					
						
							| 
									
										
										
										
											2012-09-12 11:11:06 +09:00
										 |  |  | 		pr_err("hm, delta: %" PRIu64 " < 0 ?\n", delta); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-14 13:02:25 +03:00
										 |  |  | 	sched_in = machine__findnew_thread(machine, -1, next_pid); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->curr_thread[this_cpu] = sched_in; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	printf("  "); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	new_shortname = 0; | 
					
						
							|  |  |  | 	if (!sched_in->shortname[0]) { | 
					
						
							| 
									
										
										
										
											2014-05-06 14:39:01 +09:00
										 |  |  | 		if (!strcmp(thread__comm_str(sched_in), "swapper")) { | 
					
						
							|  |  |  | 			/*
 | 
					
						
							|  |  |  | 			 * Don't allocate a letter-number for swapper:0 | 
					
						
							|  |  |  | 			 * as a shortname. Instead, we use '.' for it. | 
					
						
							|  |  |  | 			 */ | 
					
						
							|  |  |  | 			sched_in->shortname[0] = '.'; | 
					
						
							|  |  |  | 			sched_in->shortname[1] = ' '; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2014-05-06 14:39:01 +09:00
										 |  |  | 			sched_in->shortname[0] = sched->next_shortname1; | 
					
						
							|  |  |  | 			sched_in->shortname[1] = sched->next_shortname2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (sched->next_shortname1 < 'Z') { | 
					
						
							|  |  |  | 				sched->next_shortname1++; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2014-05-06 14:39:01 +09:00
										 |  |  | 				sched->next_shortname1 = 'A'; | 
					
						
							|  |  |  | 				if (sched->next_shortname2 < '9') | 
					
						
							|  |  |  | 					sched->next_shortname2++; | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					sched->next_shortname2 = '0'; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		new_shortname = 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	for (cpu = 0; cpu <= sched->max_cpu; cpu++) { | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 		if (cpu != this_cpu) | 
					
						
							|  |  |  | 			printf(" "); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			printf("*"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-06 14:39:01 +09:00
										 |  |  | 		if (sched->curr_thread[cpu]) | 
					
						
							|  |  |  | 			printf("%2s ", sched->curr_thread[cpu]->shortname); | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 			printf("   "); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	printf("  %12.6f secs ", (double)timestamp/1e9); | 
					
						
							|  |  |  | 	if (new_shortname) { | 
					
						
							|  |  |  | 		printf("%s => %s:%d\n", | 
					
						
							| 
									
										
										
										
											2013-09-11 14:46:56 +02:00
										 |  |  | 		       sched_in->shortname, thread__comm_str(sched_in), sched_in->tid); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		printf("\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static int process_sched_switch_event(struct perf_tool *tool, | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 				      struct perf_evsel *evsel, | 
					
						
							| 
									
										
										
										
											2012-09-11 01:15:03 +03:00
										 |  |  | 				      struct perf_sample *sample, | 
					
						
							| 
									
										
										
										
											2012-09-11 13:18:47 -03:00
										 |  |  | 				      struct machine *machine) | 
					
						
							| 
									
										
										
										
											2009-09-12 03:59:01 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	struct perf_sched *sched = container_of(tool, struct perf_sched, tool); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	int this_cpu = sample->cpu, err = 0; | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	u32 prev_pid = perf_evsel__intval(evsel, sample, "prev_pid"), | 
					
						
							|  |  |  | 	    next_pid = perf_evsel__intval(evsel, sample, "next_pid"); | 
					
						
							| 
									
										
										
										
											2009-09-12 03:59:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	if (sched->curr_pid[this_cpu] != (u32)-1) { | 
					
						
							| 
									
										
										
										
											2009-09-16 14:07:00 +02:00
										 |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * Are we trying to switch away a PID that is | 
					
						
							|  |  |  | 		 * not current? | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 		if (sched->curr_pid[this_cpu] != prev_pid) | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 			sched->nr_context_switch_bugs++; | 
					
						
							| 
									
										
										
										
											2009-09-16 14:07:00 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	if (sched->tp_handler->switch_event) | 
					
						
							|  |  |  | 		err = sched->tp_handler->switch_event(sched, evsel, sample, machine); | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	sched->curr_pid[this_cpu] = next_pid; | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	return err; | 
					
						
							| 
									
										
										
										
											2009-09-12 03:59:01 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static int process_sched_runtime_event(struct perf_tool *tool, | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 				       struct perf_evsel *evsel, | 
					
						
							| 
									
										
										
										
											2012-09-11 01:15:03 +03:00
										 |  |  | 				       struct perf_sample *sample, | 
					
						
							| 
									
										
										
										
											2012-09-11 13:18:47 -03:00
										 |  |  | 				       struct machine *machine) | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	struct perf_sched *sched = container_of(tool, struct perf_sched, tool); | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	if (sched->tp_handler->runtime_event) | 
					
						
							|  |  |  | 		return sched->tp_handler->runtime_event(sched, evsel, sample, machine); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-14 20:04:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:47 -04:00
										 |  |  | static int perf_sched__process_fork_event(struct perf_tool *tool, | 
					
						
							|  |  |  | 					  union perf_event *event, | 
					
						
							|  |  |  | 					  struct perf_sample *sample, | 
					
						
							|  |  |  | 					  struct machine *machine) | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	struct perf_sched *sched = container_of(tool, struct perf_sched, tool); | 
					
						
							| 
									
										
										
										
											2009-09-12 02:43:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:47 -04:00
										 |  |  | 	/* run the fork event through the perf machineruy */ | 
					
						
							|  |  |  | 	perf_event__process_fork(tool, event, sample, machine); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* and then run additional processing needed for this command */ | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	if (sched->tp_handler->fork_event) | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:47 -04:00
										 |  |  | 		return sched->tp_handler->fork_event(sched, event, machine); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
											  
											
												perf sched: Implement the scheduling workload replay engine
Integrate the schedbench.c bits with the raw trace events
that we get from the perf machinery, and activate the
workload replayer/simulator.
Example of a captured 'make -j' workload:
$ perf sched
  run measurement overhead: 90 nsecs
  sleep measurement overhead: 2724743 nsecs
  the run test took 1000081 nsecs
  the sleep test took 2981111 nsecs
  version = 0.5
  ...
  nr_run_events:        70
  nr_sleep_events:      66
  nr_wakeup_events:     9
  target-less wakeups:  71
  multi-target wakeups: 47
  run events optimized: 139
  task      0 (                perf:      6607), nr_events: 2
  task      1 (                perf:      6608), nr_events: 6
  task      2 (                    :         0), nr_events: 1
  task      3 (                make:      6609), nr_events: 5
  task      4 (                  sh:      6610), nr_events: 4
  task      5 (                make:      6611), nr_events: 6
  task      6 (                  sh:      6612), nr_events: 4
  task      7 (                make:      6613), nr_events: 5
  task      8 (        migration/11:        25), nr_events: 1
  task      9 (        migration/13:        29), nr_events: 1
  task     10 (        migration/15:        33), nr_events: 1
  task     11 (         migration/9:        21), nr_events: 1
  task     12 (                  sh:      6614), nr_events: 4
  task     13 (                make:      6615), nr_events: 5
  task     14 (                  sh:      6616), nr_events: 4
  task     15 (                make:      6617), nr_events: 7
  task     16 (         migration/3:         9), nr_events: 1
  task     17 (         migration/5:        13), nr_events: 1
  task     18 (         migration/7:        17), nr_events: 1
  task     19 (         migration/1:         5), nr_events: 1
  task     20 (                  sh:      6618), nr_events: 4
  task     21 (                make:      6619), nr_events: 5
  task     22 (                  sh:      6620), nr_events: 4
  task     23 (                make:      6621), nr_events: 10
  task     24 (                  sh:      6623), nr_events: 3
  task     25 (                 gcc:      6624), nr_events: 4
  task     26 (                 gcc:      6625), nr_events: 4
  task     27 (                 gcc:      6626), nr_events: 5
  task     28 (            collect2:      6627), nr_events: 5
  task     29 (                  sh:      6622), nr_events: 1
  task     30 (                make:      6628), nr_events: 7
  task     31 (                  sh:      6630), nr_events: 4
  task     32 (                 gcc:      6631), nr_events: 4
  task     33 (                  sh:      6629), nr_events: 1
  task     34 (                 gcc:      6632), nr_events: 4
  task     35 (                 gcc:      6633), nr_events: 4
  task     36 (            collect2:      6634), nr_events: 4
  task     37 (                make:      6635), nr_events: 8
  task     38 (                  sh:      6637), nr_events: 4
  task     39 (                  sh:      6636), nr_events: 1
  task     40 (                 gcc:      6638), nr_events: 4
  task     41 (                 gcc:      6639), nr_events: 4
  task     42 (                 gcc:      6640), nr_events: 4
  task     43 (            collect2:      6641), nr_events: 4
  task     44 (                make:      6642), nr_events: 6
  task     45 (                  sh:      6643), nr_events: 5
  task     46 (                  sh:      6644), nr_events: 3
  task     47 (                  sh:      6645), nr_events: 4
  task     48 (                make:      6646), nr_events: 6
  task     49 (                  sh:      6647), nr_events: 3
  task     50 (                make:      6648), nr_events: 5
  task     51 (                  sh:      6649), nr_events: 5
  task     52 (                  sh:      6650), nr_events: 6
  task     53 (                make:      6651), nr_events: 4
  task     54 (                make:      6652), nr_events: 5
  task     55 (                make:      6653), nr_events: 4
  task     56 (                make:      6654), nr_events: 4
  task     57 (                make:      6655), nr_events: 5
  task     58 (                  sh:      6656), nr_events: 4
  task     59 (                 gcc:      6657), nr_events: 9
  task     60 (         ksoftirqd/3:        10), nr_events: 1
  task     61 (                 gcc:      6658), nr_events: 4
  task     62 (                make:      6659), nr_events: 5
  task     63 (                  sh:      6660), nr_events: 3
  task     64 (                 gcc:      6661), nr_events: 5
  task     65 (            collect2:      6662), nr_events: 4
  ------------------------------------------------------------
  #1  : 256.745, ravg: 256.74, cpu: 0.00 / 0.00
  #2  : 439.372, ravg: 275.01, cpu: 0.00 / 0.00
  #3  : 411.971, ravg: 288.70, cpu: 0.00 / 0.00
  #4  : 385.500, ravg: 298.38, cpu: 0.00 / 0.00
  #5  : 366.526, ravg: 305.20, cpu: 0.00 / 0.00
  #6  : 381.281, ravg: 312.81, cpu: 0.00 / 0.00
  #7  : 410.756, ravg: 322.60, cpu: 0.00 / 0.00
  #8  : 368.009, ravg: 327.14, cpu: 0.00 / 0.00
  #9  : 408.098, ravg: 335.24, cpu: 0.00 / 0.00
  #10 : 368.582, ravg: 338.57, cpu: 0.00 / 0.00
I.e. we successfully analyzed the trace, replayed it
via real threads and measured the replayed workload's
scheduling properties.
This is how it looked like in 'top' output:
   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  7164 mingo     20   0 1434m 8080  888 R 57.0  0.1   0:02.04 :perf
  7165 mingo     20   0 1434m 8080  888 R 41.8  0.1   0:01.52 :perf
  7228 mingo     20   0 1434m 8080  888 R 39.8  0.1   0:01.44 :gcc
  7225 mingo     20   0 1434m 8080  888 R 33.8  0.1   0:01.26 :gcc
  7202 mingo     20   0 1434m 8080  888 R 31.2  0.1   0:01.16 :sh
  7222 mingo     20   0 1434m 8080  888 R 25.2  0.1   0:00.96 :sh
  7211 mingo     20   0 1434m 8080  888 R 21.9  0.1   0:00.82 :sh
  7213 mingo     20   0 1434m 8080  888 D 19.2  0.1   0:00.74 :sh
  7194 mingo     20   0 1434m 8080  888 D 18.6  0.1   0:00.72 :make
There's still various kinks in it - more patches to come.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
											
										 
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static int process_sched_migrate_task_event(struct perf_tool *tool, | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 					    struct perf_evsel *evsel, | 
					
						
							| 
									
										
										
										
											2012-09-11 01:15:03 +03:00
										 |  |  | 					    struct perf_sample *sample, | 
					
						
							| 
									
										
										
										
											2012-09-11 13:18:47 -03:00
										 |  |  | 					    struct machine *machine) | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	struct perf_sched *sched = container_of(tool, struct perf_sched, tool); | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Don't read all tracepoint variables in advance
Do it just at the actual consumer of these fields, that way we avoid
needless lookups:
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
         98.848272 task-clock                #    0.993 CPUs utilized            ( +-  0.48% )
                11 context-switches          #    0.112 K/sec                    ( +-  2.83% )
                 0 cpu-migrations            #    0.003 K/sec                    ( +- 50.92% )
             7,604 page-faults               #    0.077 M/sec                    ( +-  0.00% )
       332,216,085 cycles                    #    3.361 GHz                      ( +-  0.14% ) [82.87%]
       100,623,710 stalled-cycles-frontend   #   30.29% frontend cycles idle     ( +-  0.53% ) [82.95%]
        58,788,692 stalled-cycles-backend    #   17.70% backend  cycles idle     ( +-  0.59% ) [67.15%]
       609,402,433 instructions              #    1.83  insns per cycle
                                             #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.76%]
       131,277,138 branches                  # 1328.067 M/sec                    ( +-  0.06% ) [83.77%]
         1,117,871 branch-misses             #    0.85% of all branches          ( +-  0.32% ) [83.51%]
       0.099580430 seconds time elapsed                                          ( +-  0.48% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-kracdpw8wqlr0xjh75uk8g11@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	if (sched->tp_handler->migrate_task_event) | 
					
						
							|  |  |  | 		return sched->tp_handler->migrate_task_event(sched, evsel, sample, machine); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-10-10 14:46:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | typedef int (*tracepoint_handler)(struct perf_tool *tool, | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 				  struct perf_evsel *evsel, | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 				  struct perf_sample *sample, | 
					
						
							| 
									
										
										
										
											2012-09-11 13:18:47 -03:00
										 |  |  | 				  struct machine *machine); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 01:15:03 +03:00
										 |  |  | static int perf_sched__process_tracepoint_sample(struct perf_tool *tool __maybe_unused, | 
					
						
							|  |  |  | 						 union perf_event *event __maybe_unused, | 
					
						
							| 
									
										
											  
											
												perf tools: Save some loops using perf_evlist__id2evsel
Since we already ask for PERF_SAMPLE_ID and use it to quickly find the
associated evsel, add handler func + data to struct perf_evsel to avoid
using chains of if(strcmp(event_name)) and also to avoid all the linear
list searches via trace_event_find.
To demonstrate the technique convert 'perf sched' to it:
 # perf sched record sleep 5m
And then:
 Performance counter stats for '/tmp/oldperf sched lat':
        646.929438 task-clock                #    0.999 CPUs utilized
                 9 context-switches          #    0.000 M/sec
                 0 CPU-migrations            #    0.000 M/sec
            20,901 page-faults               #    0.032 M/sec
     1,290,144,450 cycles                    #    1.994 GHz
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
     1,606,158,439 instructions              #    1.24  insns per cycle
       339,088,395 branches                  #  524.151 M/sec
         4,550,735 branch-misses             #    1.34% of all branches
       0.647524759 seconds time elapsed
Versus:
 Performance counter stats for 'perf sched lat':
        473.564691 task-clock                #    0.999 CPUs utilized
                 9 context-switches          #    0.000 M/sec
                 0 CPU-migrations            #    0.000 M/sec
            20,903 page-faults               #    0.044 M/sec
       944,367,984 cycles                    #    1.994 GHz
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
     1,442,385,571 instructions              #    1.53  insns per cycle
       308,383,106 branches                  #  651.195 M/sec
         4,481,784 branch-misses             #    1.45% of all branches
       0.474215751 seconds time elapsed
[root@emilia ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-1kbzpl74lwi6lavpqke2u2p3@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2011-11-28 17:57:40 -02:00
										 |  |  | 						 struct perf_sample *sample, | 
					
						
							|  |  |  | 						 struct perf_evsel *evsel, | 
					
						
							|  |  |  | 						 struct machine *machine) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	int err = 0; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-06 10:17:38 -03:00
										 |  |  | 	if (evsel->handler != NULL) { | 
					
						
							|  |  |  | 		tracepoint_handler f = evsel->handler; | 
					
						
							| 
									
										
											  
											
												perf sched: Use perf_evsel__{int,str}val
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
  [root@sandy ~]# perf sched record sleep 30s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          129.117838 task-clock                #    0.994 CPUs utilized            ( +-  0.28% )
                  14 context-switches          #    0.111 K/sec                    ( +-  2.10% )
                   0 cpu-migrations            #    0.002 K/sec                    ( +- 66.67% )
               7,654 page-faults               #    0.059 M/sec                    ( +-  0.67% )
         438,121,661 cycles                    #    3.393 GHz                      ( +-  0.06% ) [83.06%]
         150,808,605 stalled-cycles-frontend   #   34.42% frontend cycles idle     ( +-  0.14% ) [83.10%]
          80,748,941 stalled-cycles-backend    #   18.43% backend  cycles idle     ( +-  0.64% ) [66.73%]
         758,605,879 instructions              #    1.73  insns per cycle
                                               #    0.20  stalled cycles per insn  ( +-  0.08% ) [83.54%]
         162,164,321 branches                  # 1255.940 M/sec                    ( +-  0.10% ) [83.70%]
           1,609,903 branch-misses             #    0.99% of all branches          ( +-  0.08% ) [83.62%]
         0.129949153 seconds time elapsed                                          ( +-  0.28% )
After:
  [root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
   Performance counter stats for 'perf sched lat' (10 runs):
          103.592215 task-clock                #    0.993 CPUs utilized            ( +-  0.33% )
                  12 context-switches          #    0.114 K/sec                    ( +-  3.29% )
                   0 cpu-migrations            #    0.000 K/sec
               7,605 page-faults               #    0.073 M/sec                    ( +-  0.00% )
         345,796,112 cycles                    #    3.338 GHz                      ( +-  0.07% ) [82.90%]
         106,876,796 stalled-cycles-frontend   #   30.91% frontend cycles idle     ( +-  0.38% ) [83.23%]
          62,060,877 stalled-cycles-backend    #   17.95% backend  cycles idle     ( +-  0.80% ) [67.14%]
         628,246,586 instructions              #    1.82  insns per cycle
                                               #    0.17  stalled cycles per insn  ( +-  0.04% ) [83.64%]
         134,962,057 branches                  # 1302.820 M/sec                    ( +-  0.10% ) [83.64%]
           1,233,037 branch-misses             #    0.91% of all branches          ( +-  0.29% ) [83.41%]
         0.104333272 seconds time elapsed                                          ( +-  0.33% )
  [root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2012-09-11 19:29:17 -03:00
										 |  |  | 		err = f(tool, evsel, sample, machine); | 
					
						
							| 
									
										
											  
											
												perf tools: Save some loops using perf_evlist__id2evsel
Since we already ask for PERF_SAMPLE_ID and use it to quickly find the
associated evsel, add handler func + data to struct perf_evsel to avoid
using chains of if(strcmp(event_name)) and also to avoid all the linear
list searches via trace_event_find.
To demonstrate the technique convert 'perf sched' to it:
 # perf sched record sleep 5m
And then:
 Performance counter stats for '/tmp/oldperf sched lat':
        646.929438 task-clock                #    0.999 CPUs utilized
                 9 context-switches          #    0.000 M/sec
                 0 CPU-migrations            #    0.000 M/sec
            20,901 page-faults               #    0.032 M/sec
     1,290,144,450 cycles                    #    1.994 GHz
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
     1,606,158,439 instructions              #    1.24  insns per cycle
       339,088,395 branches                  #  524.151 M/sec
         4,550,735 branch-misses             #    1.34% of all branches
       0.647524759 seconds time elapsed
Versus:
 Performance counter stats for 'perf sched lat':
        473.564691 task-clock                #    0.999 CPUs utilized
                 9 context-switches          #    0.000 M/sec
                 0 CPU-migrations            #    0.000 M/sec
            20,903 page-faults               #    0.044 M/sec
       944,367,984 cycles                    #    1.994 GHz
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
     1,442,385,571 instructions              #    1.53  insns per cycle
       308,383,106 branches                  #  651.195 M/sec
         4,481,784 branch-misses             #    1.45% of all branches
       0.474215751 seconds time elapsed
[root@emilia ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-1kbzpl74lwi6lavpqke2u2p3@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2011-11-28 17:57:40 -02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	return err; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:44 -04:00
										 |  |  | static int perf_sched__read_events(struct perf_sched *sched, | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 				   struct perf_session **psession) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
											  
											
												perf tools: Save some loops using perf_evlist__id2evsel
Since we already ask for PERF_SAMPLE_ID and use it to quickly find the
associated evsel, add handler func + data to struct perf_evsel to avoid
using chains of if(strcmp(event_name)) and also to avoid all the linear
list searches via trace_event_find.
To demonstrate the technique convert 'perf sched' to it:
 # perf sched record sleep 5m
And then:
 Performance counter stats for '/tmp/oldperf sched lat':
        646.929438 task-clock                #    0.999 CPUs utilized
                 9 context-switches          #    0.000 M/sec
                 0 CPU-migrations            #    0.000 M/sec
            20,901 page-faults               #    0.032 M/sec
     1,290,144,450 cycles                    #    1.994 GHz
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
     1,606,158,439 instructions              #    1.24  insns per cycle
       339,088,395 branches                  #  524.151 M/sec
         4,550,735 branch-misses             #    1.34% of all branches
       0.647524759 seconds time elapsed
Versus:
 Performance counter stats for 'perf sched lat':
        473.564691 task-clock                #    0.999 CPUs utilized
                 9 context-switches          #    0.000 M/sec
                 0 CPU-migrations            #    0.000 M/sec
            20,903 page-faults               #    0.044 M/sec
       944,367,984 cycles                    #    1.994 GHz
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
     1,442,385,571 instructions              #    1.53  insns per cycle
       308,383,106 branches                  #  651.195 M/sec
         4,481,784 branch-misses             #    1.45% of all branches
       0.474215751 seconds time elapsed
[root@emilia ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-1kbzpl74lwi6lavpqke2u2p3@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2011-11-28 17:57:40 -02:00
										 |  |  | 	const struct perf_evsel_str_handler handlers[] = { | 
					
						
							|  |  |  | 		{ "sched:sched_switch",	      process_sched_switch_event, }, | 
					
						
							|  |  |  | 		{ "sched:sched_stat_runtime", process_sched_runtime_event, }, | 
					
						
							|  |  |  | 		{ "sched:sched_wakeup",	      process_sched_wakeup_event, }, | 
					
						
							|  |  |  | 		{ "sched:sched_wakeup_new",   process_sched_wakeup_event, }, | 
					
						
							|  |  |  | 		{ "sched:sched_migrate_task", process_sched_migrate_task_event, }, | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2012-06-27 13:08:42 -03:00
										 |  |  | 	struct perf_session *session; | 
					
						
							| 
									
										
										
										
											2013-10-15 16:27:32 +02:00
										 |  |  | 	struct perf_data_file file = { | 
					
						
							|  |  |  | 		.path = input_name, | 
					
						
							|  |  |  | 		.mode = PERF_DATA_MODE_READ, | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2012-06-27 13:08:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-15 16:27:32 +02:00
										 |  |  | 	session = perf_session__new(&file, false, &sched->tool); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	if (session == NULL) { | 
					
						
							|  |  |  | 		pr_debug("No Memory for session\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-12-11 21:24:02 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-12 15:40:45 +09:00
										 |  |  | 	symbol__init(&session->header.env); | 
					
						
							| 
									
										
										
										
											2014-08-12 15:40:41 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	if (perf_session__set_tracepoints_handlers(session, handlers)) | 
					
						
							|  |  |  | 		goto out_delete; | 
					
						
							| 
									
										
											  
											
												perf tools: Save some loops using perf_evlist__id2evsel
Since we already ask for PERF_SAMPLE_ID and use it to quickly find the
associated evsel, add handler func + data to struct perf_evsel to avoid
using chains of if(strcmp(event_name)) and also to avoid all the linear
list searches via trace_event_find.
To demonstrate the technique convert 'perf sched' to it:
 # perf sched record sleep 5m
And then:
 Performance counter stats for '/tmp/oldperf sched lat':
        646.929438 task-clock                #    0.999 CPUs utilized
                 9 context-switches          #    0.000 M/sec
                 0 CPU-migrations            #    0.000 M/sec
            20,901 page-faults               #    0.032 M/sec
     1,290,144,450 cycles                    #    1.994 GHz
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
     1,606,158,439 instructions              #    1.24  insns per cycle
       339,088,395 branches                  #  524.151 M/sec
         4,550,735 branch-misses             #    1.34% of all branches
       0.647524759 seconds time elapsed
Versus:
 Performance counter stats for 'perf sched lat':
        473.564691 task-clock                #    0.999 CPUs utilized
                 9 context-switches          #    0.000 M/sec
                 0 CPU-migrations            #    0.000 M/sec
            20,903 page-faults               #    0.044 M/sec
       944,367,984 cycles                    #    1.994 GHz
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
     1,442,385,571 instructions              #    1.53  insns per cycle
       308,383,106 branches                  #  651.195 M/sec
         4,481,784 branch-misses             #    1.45% of all branches
       0.474215751 seconds time elapsed
[root@emilia ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-1kbzpl74lwi6lavpqke2u2p3@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
											
										 
											2011-11-28 17:57:40 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:16:55 -03:00
										 |  |  | 	if (perf_session__has_traces(session, "record -R")) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		int err = perf_session__process_events(session, &sched->tool); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		if (err) { | 
					
						
							|  |  |  | 			pr_err("Failed to process events, error %d", err); | 
					
						
							|  |  |  | 			goto out_delete; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-08-08 23:03:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 16:24:46 -03:00
										 |  |  | 		sched->nr_events      = session->stats.nr_events[0]; | 
					
						
							|  |  |  | 		sched->nr_lost_events = session->stats.total_lost; | 
					
						
							|  |  |  | 		sched->nr_lost_chunks = session->stats.nr_events[PERF_RECORD_LOST]; | 
					
						
							| 
									
										
										
										
											2010-05-14 13:16:55 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-12-27 21:37:02 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-08 23:03:34 +02:00
										 |  |  | 	if (psession) | 
					
						
							|  |  |  | 		*psession = session; | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:44 -04:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		perf_session__delete(session); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | out_delete: | 
					
						
							|  |  |  | 	perf_session__delete(session); | 
					
						
							|  |  |  | 	return -1; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void print_bad_events(struct perf_sched *sched) | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	if (sched->nr_unordered_timestamps && sched->nr_timestamps) { | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 		printf("  INFO: %.3f%% unordered timestamps (%ld out of %ld)\n", | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 			(double)sched->nr_unordered_timestamps/(double)sched->nr_timestamps*100.0, | 
					
						
							|  |  |  | 			sched->nr_unordered_timestamps, sched->nr_timestamps); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	if (sched->nr_lost_events && sched->nr_events) { | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 		printf("  INFO: %.3f%% lost events (%ld out of %ld, in %ld chunks)\n", | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 			(double)sched->nr_lost_events/(double)sched->nr_events * 100.0, | 
					
						
							|  |  |  | 			sched->nr_lost_events, sched->nr_events, sched->nr_lost_chunks); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	if (sched->nr_context_switch_bugs && sched->nr_timestamps) { | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 		printf("  INFO: %.3f%% context switch bugs (%ld out of %ld)", | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 			(double)sched->nr_context_switch_bugs/(double)sched->nr_timestamps*100.0, | 
					
						
							|  |  |  | 			sched->nr_context_switch_bugs, sched->nr_timestamps); | 
					
						
							|  |  |  | 		if (sched->nr_lost_events) | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 			printf(" (due to lost events?)"); | 
					
						
							|  |  |  | 		printf("\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static int perf_sched__lat(struct perf_sched *sched) | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct rb_node *next; | 
					
						
							| 
									
										
										
										
											2011-08-08 23:03:34 +02:00
										 |  |  | 	struct perf_session *session; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	setup_pager(); | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* save session -- references to threads are held in work_list */ | 
					
						
							|  |  |  | 	if (perf_sched__read_events(sched, &session)) | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	perf_sched__sort_lat(sched); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-17 10:18:21 -04:00
										 |  |  | 	printf("\n -----------------------------------------------------------------------------------------------------------------\n"); | 
					
						
							|  |  |  | 	printf("  Task                  |   Runtime ms  | Switches | Average delay ms | Maximum delay ms | Maximum delay at       |\n"); | 
					
						
							|  |  |  | 	printf(" -----------------------------------------------------------------------------------------------------------------\n"); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	next = rb_first(&sched->sorted_atom_root); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while (next) { | 
					
						
							|  |  |  | 		struct work_atoms *work_list; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		work_list = rb_entry(next, struct work_atoms, node); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		output_lat_thread(sched, work_list); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 		next = rb_next(next); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-17 10:18:21 -04:00
										 |  |  | 	printf(" -----------------------------------------------------------------------------------------------------------------\n"); | 
					
						
							| 
									
										
										
										
											2011-01-22 20:37:02 -02:00
										 |  |  | 	printf("  TOTAL:                |%11.3f ms |%9" PRIu64 " |\n", | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		(double)sched->all_runtime / 1e6, sched->all_count); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	printf(" ---------------------------------------------------\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	print_bad_events(sched); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 	printf("\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-08 23:03:34 +02:00
										 |  |  | 	perf_session__delete(session); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static int perf_sched__map(struct perf_sched *sched) | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sched->max_cpu = sysconf(_SC_NPROCESSORS_CONF); | 
					
						
							| 
									
										
										
										
											2009-09-17 18:24:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 	setup_pager(); | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:44 -04:00
										 |  |  | 	if (perf_sched__read_events(sched, NULL)) | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	print_bad_events(sched); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static int perf_sched__replay(struct perf_sched *sched) | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned long i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	calibrate_run_measurement_overhead(sched); | 
					
						
							|  |  |  | 	calibrate_sleep_measurement_overhead(sched); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	test_calibrations(sched); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-07 22:50:44 -04:00
										 |  |  | 	if (perf_sched__read_events(sched, NULL)) | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	printf("nr_run_events:        %ld\n", sched->nr_run_events); | 
					
						
							|  |  |  | 	printf("nr_sleep_events:      %ld\n", sched->nr_sleep_events); | 
					
						
							|  |  |  | 	printf("nr_wakeup_events:     %ld\n", sched->nr_wakeup_events); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	if (sched->targetless_wakeups) | 
					
						
							|  |  |  | 		printf("target-less wakeups:  %ld\n", sched->targetless_wakeups); | 
					
						
							|  |  |  | 	if (sched->multitarget_wakeups) | 
					
						
							|  |  |  | 		printf("multi-target wakeups: %ld\n", sched->multitarget_wakeups); | 
					
						
							|  |  |  | 	if (sched->nr_run_events_optimized) | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 		printf("run atoms optimized: %ld\n", | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 			sched->nr_run_events_optimized); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	print_task_traces(sched); | 
					
						
							|  |  |  | 	add_cross_task_wakeups(sched); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	create_tasks(sched); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 	printf("------------------------------------------------------------\n"); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	for (i = 0; i < sched->replay_repeat; i++) | 
					
						
							|  |  |  | 		run_one_test(sched); | 
					
						
							| 
									
										
										
										
											2012-09-08 22:53:06 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | static void setup_sorting(struct perf_sched *sched, const struct option *options, | 
					
						
							|  |  |  | 			  const char * const usage_msg[]) | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	char *tmp, *tok, *str = strdup(sched->sort_order); | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (tok = strtok_r(str, ", ", &tmp); | 
					
						
							|  |  |  | 			tok; tok = strtok_r(NULL, ", ", &tmp)) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		if (sort_dimension__add(tok, &sched->sort_list) < 0) { | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 			error("Unknown --sort key: `%s'", tok); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 			usage_with_options(usage_msg, options); | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	free(str); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	sort_dimension__add("pid", &sched->cmp_pid); | 
					
						
							| 
									
										
										
										
											2009-09-13 03:36:29 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-13 09:44:29 +02:00
										 |  |  | static int __cmd_record(int argc, const char **argv) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned int rec_argc, i, j; | 
					
						
							|  |  |  | 	const char **rec_argv; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	const char * const record_args[] = { | 
					
						
							|  |  |  | 		"record", | 
					
						
							|  |  |  | 		"-a", | 
					
						
							|  |  |  | 		"-R", | 
					
						
							|  |  |  | 		"-m", "1024", | 
					
						
							|  |  |  | 		"-c", "1", | 
					
						
							|  |  |  | 		"-e", "sched:sched_switch", | 
					
						
							|  |  |  | 		"-e", "sched:sched_stat_wait", | 
					
						
							|  |  |  | 		"-e", "sched:sched_stat_sleep", | 
					
						
							|  |  |  | 		"-e", "sched:sched_stat_iowait", | 
					
						
							|  |  |  | 		"-e", "sched:sched_stat_runtime", | 
					
						
							|  |  |  | 		"-e", "sched:sched_process_fork", | 
					
						
							|  |  |  | 		"-e", "sched:sched_wakeup", | 
					
						
							| 
									
										
										
										
											2014-05-05 16:05:53 +09:00
										 |  |  | 		"-e", "sched:sched_wakeup_new", | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		"-e", "sched:sched_migrate_task", | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2009-09-13 09:44:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	rec_argc = ARRAY_SIZE(record_args) + argc - 1; | 
					
						
							|  |  |  | 	rec_argv = calloc(rec_argc + 1, sizeof(char *)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-10 10:48:47 -02:00
										 |  |  | 	if (rec_argv == NULL) | 
					
						
							| 
									
										
										
										
											2010-11-13 13:35:06 +11:00
										 |  |  | 		return -ENOMEM; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-13 09:44:29 +02:00
										 |  |  | 	for (i = 0; i < ARRAY_SIZE(record_args); i++) | 
					
						
							|  |  |  | 		rec_argv[i] = strdup(record_args[i]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (j = 1; j < (unsigned int)argc; j++, i++) | 
					
						
							|  |  |  | 		rec_argv[i] = argv[j]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BUG_ON(i != rec_argc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return cmd_record(i, rec_argv, NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 01:15:03 +03:00
										 |  |  | int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-10-22 10:34:15 +03:00
										 |  |  | 	const char default_sort_order[] = "avg, max, switch, runtime"; | 
					
						
							|  |  |  | 	struct perf_sched sched = { | 
					
						
							|  |  |  | 		.tool = { | 
					
						
							|  |  |  | 			.sample		 = perf_sched__process_tracepoint_sample, | 
					
						
							|  |  |  | 			.comm		 = perf_event__process_comm, | 
					
						
							|  |  |  | 			.lost		 = perf_event__process_lost, | 
					
						
							|  |  |  | 			.fork		 = perf_sched__process_fork_event, | 
					
						
							| 
									
										
										
										
											2014-07-06 14:18:21 +02:00
										 |  |  | 			.ordered_events = true, | 
					
						
							| 
									
										
										
										
											2013-10-22 10:34:15 +03:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		.cmp_pid	      = LIST_HEAD_INIT(sched.cmp_pid), | 
					
						
							|  |  |  | 		.sort_list	      = LIST_HEAD_INIT(sched.sort_list), | 
					
						
							|  |  |  | 		.start_work_mutex     = PTHREAD_MUTEX_INITIALIZER, | 
					
						
							|  |  |  | 		.work_done_wait_mutex = PTHREAD_MUTEX_INITIALIZER, | 
					
						
							|  |  |  | 		.sort_order	      = default_sort_order, | 
					
						
							|  |  |  | 		.replay_repeat	      = 10, | 
					
						
							|  |  |  | 		.profile_cpu	      = -1, | 
					
						
							|  |  |  | 		.next_shortname1      = 'A', | 
					
						
							|  |  |  | 		.next_shortname2      = '0', | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 	const struct option latency_options[] = { | 
					
						
							|  |  |  | 	OPT_STRING('s', "sort", &sched.sort_order, "key[,key2...]", | 
					
						
							|  |  |  | 		   "sort by key(s): runtime, switch, avg, max"), | 
					
						
							|  |  |  | 	OPT_INCR('v', "verbose", &verbose, | 
					
						
							|  |  |  | 		    "be more verbose (show symbol address, etc)"), | 
					
						
							|  |  |  | 	OPT_INTEGER('C', "CPU", &sched.profile_cpu, | 
					
						
							|  |  |  | 		    "CPU to profile on"), | 
					
						
							|  |  |  | 	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, | 
					
						
							|  |  |  | 		    "dump raw trace in ASCII"), | 
					
						
							|  |  |  | 	OPT_END() | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	const struct option replay_options[] = { | 
					
						
							|  |  |  | 	OPT_UINTEGER('r', "repeat", &sched.replay_repeat, | 
					
						
							|  |  |  | 		     "repeat the workload replay N times (-1: infinite)"), | 
					
						
							|  |  |  | 	OPT_INCR('v', "verbose", &verbose, | 
					
						
							|  |  |  | 		    "be more verbose (show symbol address, etc)"), | 
					
						
							|  |  |  | 	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, | 
					
						
							|  |  |  | 		    "dump raw trace in ASCII"), | 
					
						
							|  |  |  | 	OPT_END() | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	const struct option sched_options[] = { | 
					
						
							| 
									
										
										
										
											2012-10-30 11:56:02 +08:00
										 |  |  | 	OPT_STRING('i', "input", &input_name, "file", | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		    "input file name"), | 
					
						
							|  |  |  | 	OPT_INCR('v', "verbose", &verbose, | 
					
						
							|  |  |  | 		    "be more verbose (show symbol address, etc)"), | 
					
						
							|  |  |  | 	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, | 
					
						
							|  |  |  | 		    "dump raw trace in ASCII"), | 
					
						
							|  |  |  | 	OPT_END() | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	const char * const latency_usage[] = { | 
					
						
							|  |  |  | 		"perf sched latency [<options>]", | 
					
						
							|  |  |  | 		NULL | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	const char * const replay_usage[] = { | 
					
						
							|  |  |  | 		"perf sched replay [<options>]", | 
					
						
							|  |  |  | 		NULL | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2014-03-14 23:17:54 -04:00
										 |  |  | 	const char *const sched_subcommands[] = { "record", "latency", "map", | 
					
						
							|  |  |  | 						  "replay", "script", NULL }; | 
					
						
							|  |  |  | 	const char *sched_usage[] = { | 
					
						
							|  |  |  | 		NULL, | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		NULL | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	struct trace_sched_handler lat_ops  = { | 
					
						
							|  |  |  | 		.wakeup_event	    = latency_wakeup_event, | 
					
						
							|  |  |  | 		.switch_event	    = latency_switch_event, | 
					
						
							|  |  |  | 		.runtime_event	    = latency_runtime_event, | 
					
						
							|  |  |  | 		.migrate_task_event = latency_migrate_task_event, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	struct trace_sched_handler map_ops  = { | 
					
						
							|  |  |  | 		.switch_event	    = map_switch_event, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	struct trace_sched_handler replay_ops  = { | 
					
						
							|  |  |  | 		.wakeup_event	    = replay_wakeup_event, | 
					
						
							|  |  |  | 		.switch_event	    = replay_switch_event, | 
					
						
							|  |  |  | 		.fork_event	    = replay_fork_event, | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2013-10-22 10:34:16 +03:00
										 |  |  | 	unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < ARRAY_SIZE(sched.curr_pid); i++) | 
					
						
							|  |  |  | 		sched.curr_pid[i] = -1; | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 23:17:54 -04:00
										 |  |  | 	argc = parse_options_subcommand(argc, argv, sched_options, sched_subcommands, | 
					
						
							|  |  |  | 					sched_usage, PARSE_OPT_STOP_AT_NON_OPTION); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	if (!argc) | 
					
						
							|  |  |  | 		usage_with_options(sched_usage, sched_options); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 12:04:49 +08:00
										 |  |  | 	/*
 | 
					
						
							| 
									
										
										
										
											2010-11-16 18:45:39 +01:00
										 |  |  | 	 * Aliased to 'perf script' for now: | 
					
						
							| 
									
										
										
										
											2009-12-07 12:04:49 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2010-11-16 18:45:39 +01:00
										 |  |  | 	if (!strcmp(argv[0], "script")) | 
					
						
							|  |  |  | 		return cmd_script(argc, argv, prefix); | 
					
						
							| 
									
										
										
										
											2009-12-07 12:04:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-13 09:44:29 +02:00
										 |  |  | 	if (!strncmp(argv[0], "rec", 3)) { | 
					
						
							|  |  |  | 		return __cmd_record(argc, argv); | 
					
						
							|  |  |  | 	} else if (!strncmp(argv[0], "lat", 3)) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		sched.tp_handler = &lat_ops; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		if (argc > 1) { | 
					
						
							|  |  |  | 			argc = parse_options(argc, argv, latency_options, latency_usage, 0); | 
					
						
							|  |  |  | 			if (argc) | 
					
						
							|  |  |  | 				usage_with_options(latency_usage, latency_options); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		setup_sorting(&sched, latency_options, latency_usage); | 
					
						
							|  |  |  | 		return perf_sched__lat(&sched); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:40:48 +02:00
										 |  |  | 	} else if (!strcmp(argv[0], "map")) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		sched.tp_handler = &map_ops; | 
					
						
							|  |  |  | 		setup_sorting(&sched, latency_options, latency_usage); | 
					
						
							|  |  |  | 		return perf_sched__map(&sched); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	} else if (!strncmp(argv[0], "rep", 3)) { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		sched.tp_handler = &replay_ops; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 		if (argc) { | 
					
						
							|  |  |  | 			argc = parse_options(argc, argv, replay_options, replay_usage, 0); | 
					
						
							|  |  |  | 			if (argc) | 
					
						
							|  |  |  | 				usage_with_options(replay_usage, replay_options); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-09-11 17:29:27 -03:00
										 |  |  | 		return perf_sched__replay(&sched); | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		usage_with_options(sched_usage, sched_options); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-11 12:12:54 +02:00
										 |  |  | } |