1e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "builtin.h" 2e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "perf.h" 3e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 4e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "util/util.h" 5e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "util/cache.h" 6e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "util/symbol.h" 7e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "util/thread.h" 8e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "util/header.h" 9e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "util/session.h" 10e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 11e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "util/parse-options.h" 12e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "util/trace-event.h" 13e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 14e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "util/debug.h" 15e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 167d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng/* ANDROID_CHANGE_BEGIN */ 177d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng#ifndef __APPLE__ 18e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <sys/prctl.h> 197d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng#endif 207d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng/* ANDROID_CHANGE_END */ 21e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 22e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <semaphore.h> 23e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* ANDROID_CHANGE_BEGIN */ 24e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#ifdef __BIONIC__ 25e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* PTHREAD_STACK_MIN is defined as (2 * PAGE_SIZE) */ 26e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <asm/page.h> 27e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#endif 28e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* ANDROID_CHANGE_END */ 29e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <pthread.h> 30e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <math.h> 31e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 32e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic char const *input_name = "perf.data"; 33e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 34e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic char default_sort_order[] = "avg, max, switch, runtime"; 35e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const char *sort_order = default_sort_order; 36e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 37e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int profile_cpu = -1; 38e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 39e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define PR_SET_NAME 15 /* Set process name */ 40e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define MAX_CPUS 4096 41e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 42e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 run_measurement_overhead; 43e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 sleep_measurement_overhead; 44e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 45e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define COMM_LEN 20 46e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define SYM_LEN 129 47e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 48e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define MAX_PID 65536 49e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 50e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_tasks; 51e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 52e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct sched_atom; 53e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 54e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct task_desc { 55e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned long nr; 56e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned long pid; 57e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char comm[COMM_LEN]; 58e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 59e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned long nr_events; 60e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned long curr_event; 61e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct sched_atom **atoms; 62e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 63e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pthread_t thread; 64e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sem_t sleep_sem; 65e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 66e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sem_t ready_for_work; 67e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sem_t work_done_sem; 68e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 69e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 cpu_usage; 70e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 71e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 72e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengenum sched_event_type { 73e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng SCHED_EVENT_RUN, 74e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng SCHED_EVENT_SLEEP, 75e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng SCHED_EVENT_WAKEUP, 76e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng SCHED_EVENT_MIGRATION, 77e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 78e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 79e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct sched_atom { 80e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng enum sched_event_type type; 81e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int specific_wait; 82e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp; 83e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 duration; 84e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned long nr; 85e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sem_t *wait_sem; 86e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct task_desc *wakee; 87e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 88e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 89e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct task_desc *pid_to_task[MAX_PID]; 90e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 91e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct task_desc **tasks; 92e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 93e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic pthread_mutex_t start_work_mutex = PTHREAD_MUTEX_INITIALIZER; 94e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 start_time; 95e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 96e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic pthread_mutex_t work_done_wait_mutex = PTHREAD_MUTEX_INITIALIZER; 97e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 98e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_run_events; 99e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_sleep_events; 100e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_wakeup_events; 101e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 102e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_sleep_corrections; 103e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_run_events_optimized; 104e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 105e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long targetless_wakeups; 106e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long multitarget_wakeups; 107e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 108e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 cpu_usage; 109e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 runavg_cpu_usage; 110e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 parent_cpu_usage; 111e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 runavg_parent_cpu_usage; 112e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 113e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_runs; 114e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 sum_runtime; 115e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 sum_fluct; 116e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 run_avg; 117e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 118e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned int replay_repeat = 10; 119e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_timestamps; 120e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_unordered_timestamps; 121e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_state_machine_bugs; 122e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_context_switch_bugs; 123e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_events; 124e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_lost_chunks; 125e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned long nr_lost_events; 126e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 127e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define TASK_STATE_TO_CHAR_STR "RSDTtZX" 128e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 129e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengenum thread_state { 130e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng THREAD_SLEEPING = 0, 131e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng THREAD_WAIT_CPU, 132e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng THREAD_SCHED_IN, 133e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng THREAD_IGNORE 134e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 135e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 136e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct work_atom { 137e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct list_head list; 138e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng enum thread_state state; 139e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 sched_out_time; 140e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 wake_up_time; 141e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 sched_in_time; 142e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 runtime; 143e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 144e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 145e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct work_atoms { 146e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct list_head work_list; 147e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread; 148e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct rb_node node; 149e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 max_lat; 150e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 max_lat_at; 151e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 total_lat; 152e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 nb_atoms; 153e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 total_runtime; 154e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 155e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 156e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengtypedef int (*sort_fn_t)(struct work_atoms *, struct work_atoms *); 157e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 158e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct rb_root atom_root, sorted_atom_root; 159e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 160e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 all_runtime; 161e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 all_count; 162e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 163e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 164e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 get_nsecs(void) 165e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1667d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng /* ANDROID_CHANGE_BEGIN */ 1677d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng#ifndef __APPLE__ 168e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct timespec ts; 169e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 170e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng clock_gettime(CLOCK_MONOTONIC, &ts); 171e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 172e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return ts.tv_sec * 1000000000ULL + ts.tv_nsec; 1737d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng#else 1747d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng return 0; 1757d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng#endif 1767d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng /* ANDROID_CHANGE_END */ 177e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 178e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 179e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void burn_nsecs(u64 nsecs) 180e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 181e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 T0 = get_nsecs(), T1; 182e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 183e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng do { 184e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng T1 = get_nsecs(); 185e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } while (T1 + run_measurement_overhead < T0 + nsecs); 186e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 187e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 188e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void sleep_nsecs(u64 nsecs) 189e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 190e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct timespec ts; 191e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 192e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ts.tv_nsec = nsecs % 999999999; 193e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ts.tv_sec = nsecs / 999999999; 194e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 195e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nanosleep(&ts, NULL); 196e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 197e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 198e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void calibrate_run_measurement_overhead(void) 199e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 200e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 T0, T1, delta, min_delta = 1000000000ULL; 201e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int i; 202e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 203e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < 10; i++) { 204e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng T0 = get_nsecs(); 205e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng burn_nsecs(0); 206e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng T1 = get_nsecs(); 207e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng delta = T1-T0; 208e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng min_delta = min(min_delta, delta); 209e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 210e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng run_measurement_overhead = min_delta; 211e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 212e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("run measurement overhead: %" PRIu64 " nsecs\n", min_delta); 213e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 214e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 215e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void calibrate_sleep_measurement_overhead(void) 216e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 217e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 T0, T1, delta, min_delta = 1000000000ULL; 218e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int i; 219e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 220e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < 10; i++) { 221e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng T0 = get_nsecs(); 222e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sleep_nsecs(10000); 223e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng T1 = get_nsecs(); 224e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng delta = T1-T0; 225e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng min_delta = min(min_delta, delta); 226e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 227e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng min_delta -= 10000; 228e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sleep_measurement_overhead = min_delta; 229e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 230e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("sleep measurement overhead: %" PRIu64 " nsecs\n", min_delta); 231e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 232e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 233e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct sched_atom * 234e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengget_new_event(struct task_desc *task, u64 timestamp) 235e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 236e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct sched_atom *event = zalloc(sizeof(*event)); 237e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned long idx = task->nr_events; 238e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng size_t size; 239e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 240e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event->timestamp = timestamp; 241e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event->nr = idx; 242e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 243e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task->nr_events++; 244e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng size = sizeof(struct sched_atom *) * task->nr_events; 245e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task->atoms = realloc(task->atoms, size); 246e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(!task->atoms); 247e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 248e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task->atoms[idx] = event; 249e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 250e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return event; 251e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 252e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 253e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct sched_atom *last_event(struct task_desc *task) 254e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 255e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!task->nr_events) 256e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return NULL; 257e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 258e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return task->atoms[task->nr_events - 1]; 259e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 260e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 261e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 262e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengadd_sched_event_run(struct task_desc *task, u64 timestamp, u64 duration) 263e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 264e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct sched_atom *event, *curr_event = last_event(task); 265e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 266e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 267e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * optimize an existing RUN event by merging this one 268e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * to it: 269e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 270e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (curr_event && curr_event->type == SCHED_EVENT_RUN) { 271e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_run_events_optimized++; 272e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng curr_event->duration += duration; 273e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 274e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 275e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 276e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event = get_new_event(task, timestamp); 277e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 278e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event->type = SCHED_EVENT_RUN; 279e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event->duration = duration; 280e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 281e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_run_events++; 282e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 283e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 284e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 285e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengadd_sched_event_wakeup(struct task_desc *task, u64 timestamp, 286e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct task_desc *wakee) 287e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 288e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct sched_atom *event, *wakee_event; 289e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 290e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event = get_new_event(task, timestamp); 291e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event->type = SCHED_EVENT_WAKEUP; 292e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event->wakee = wakee; 293e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 294e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng wakee_event = last_event(wakee); 295e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!wakee_event || wakee_event->type != SCHED_EVENT_SLEEP) { 296e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng targetless_wakeups++; 297e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 298e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 299e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (wakee_event->wait_sem) { 300e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng multitarget_wakeups++; 301e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 302e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 303e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 304e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng wakee_event->wait_sem = zalloc(sizeof(*wakee_event->wait_sem)); 305e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sem_init(wakee_event->wait_sem, 0, 0); 306e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng wakee_event->specific_wait = 1; 307e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event->wait_sem = wakee_event->wait_sem; 308e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 309e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_wakeup_events++; 310e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 311e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 312e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 313e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengadd_sched_event_sleep(struct task_desc *task, u64 timestamp, 314e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 task_state __used) 315e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 316e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct sched_atom *event = get_new_event(task, timestamp); 317e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 318e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event->type = SCHED_EVENT_SLEEP; 319e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 320e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_sleep_events++; 321e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 322e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 323e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct task_desc *register_pid(unsigned long pid, const char *comm) 324e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 325e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct task_desc *task; 326e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 327e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(pid >= MAX_PID); 328e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 329e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task = pid_to_task[pid]; 330e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 331e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (task) 332e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return task; 333e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 334e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task = zalloc(sizeof(*task)); 335e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task->pid = pid; 336e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task->nr = nr_tasks; 337e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng strcpy(task->comm, comm); 338e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 339e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * every task starts in sleeping state - this gets ignored 340e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * if there's no wakeup pointing to this sleep state: 341e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 342e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng add_sched_event_sleep(task, 0, 0); 343e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 344e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pid_to_task[pid] = task; 345e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_tasks++; 346e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng tasks = realloc(tasks, nr_tasks*sizeof(struct task_task *)); 347e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(!tasks); 348e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng tasks[task->nr] = task; 349e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 350e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (verbose) 351e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("registered task #%ld, PID %ld (%s)\n", nr_tasks, pid, comm); 352e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 353e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return task; 354e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 355e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 356e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 357e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void print_task_traces(void) 358e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 359e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct task_desc *task; 360e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned long i; 361e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 362e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < nr_tasks; i++) { 363e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task = tasks[i]; 364e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("task %6ld (%20s:%10ld), nr_events: %ld\n", 365e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task->nr, task->comm, task->pid, task->nr_events); 366e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 367e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 368e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 369e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void add_cross_task_wakeups(void) 370e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 371e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct task_desc *task1, *task2; 372e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned long i, j; 373e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 374e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < nr_tasks; i++) { 375e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task1 = tasks[i]; 376e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng j = i + 1; 377e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (j == nr_tasks) 378e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng j = 0; 379e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task2 = tasks[j]; 380e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng add_sched_event_wakeup(task1, 0, task2); 381e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 382e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 383e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 384e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 385e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengprocess_sched_event(struct task_desc *this_task __used, struct sched_atom *atom) 386e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 387e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int ret = 0; 388e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 389e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng switch (atom->type) { 390e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng case SCHED_EVENT_RUN: 391e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng burn_nsecs(atom->duration); 392e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 393e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng case SCHED_EVENT_SLEEP: 394e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (atom->wait_sem) 395e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = sem_wait(atom->wait_sem); 396e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(ret); 397e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 398e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng case SCHED_EVENT_WAKEUP: 399e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (atom->wait_sem) 400e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = sem_post(atom->wait_sem); 401e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(ret); 402e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 403e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng case SCHED_EVENT_MIGRATION: 404e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 405e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng default: 406e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(1); 407e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 408e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 409e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 410e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 get_cpu_usage_nsec_parent(void) 411e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 412e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct rusage ru; 413e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 sum; 414e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int err; 415e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 416e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng err = getrusage(RUSAGE_SELF, &ru); 417e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(err); 418e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 419e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sum = ru.ru_utime.tv_sec*1e9 + ru.ru_utime.tv_usec*1e3; 420e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sum += ru.ru_stime.tv_sec*1e9 + ru.ru_stime.tv_usec*1e3; 421e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 422e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return sum; 423e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 424e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 425e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int self_open_counters(void) 426e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 4277d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng/* ANDROID_CHANGE_BEGIN */ 4287d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng#ifndef __APPLE__ 429e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_event_attr attr; 430e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int fd; 431e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 432e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng memset(&attr, 0, sizeof(attr)); 433e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 434e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng attr.type = PERF_TYPE_SOFTWARE; 435e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng attr.config = PERF_COUNT_SW_TASK_CLOCK; 436e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 437e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fd = sys_perf_event_open(&attr, 0, -1, -1, 0); 438e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 439e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (fd < 0) 440e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng die("Error: sys_perf_event_open() syscall returned" 441e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "with %d (%s)\n", fd, strerror(errno)); 442e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return fd; 4437d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng#else 4447d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng die("Error: sys_perf_event_open() syscall not supported on host\n"); 4457d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng#endif 4467d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng/* ANDROID_CHANGE_END */ 447e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 448e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 449e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 get_cpu_usage_nsec_self(int fd) 450e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 451e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 runtime; 452e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int ret; 453e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 454e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = read(fd, &runtime, sizeof(runtime)); 455e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(ret != sizeof(runtime)); 456e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 457e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return runtime; 458e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 459e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 460e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void *thread_func(void *ctx) 461e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 4627d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng/* ANDROID_CHANGE_BEGIN */ 4637d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng#ifndef __APPLE__ 4647d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng/* ANDROID_CHANGE_END */ 465e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct task_desc *this_task = ctx; 466e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 cpu_usage_0, cpu_usage_1; 467e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned long i, ret; 468e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char comm2[22]; 469e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int fd; 470e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 471e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sprintf(comm2, ":%s", this_task->comm); 472e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng prctl(PR_SET_NAME, comm2); 473e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fd = self_open_counters(); 474e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 475e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengagain: 476e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = sem_post(&this_task->ready_for_work); 477e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(ret); 478e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = pthread_mutex_lock(&start_work_mutex); 479e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(ret); 480e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = pthread_mutex_unlock(&start_work_mutex); 481e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(ret); 482e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 483e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cpu_usage_0 = get_cpu_usage_nsec_self(fd); 484e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 485e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < this_task->nr_events; i++) { 486e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng this_task->curr_event = i; 487e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng process_sched_event(this_task, this_task->atoms[i]); 488e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 489e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 490e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cpu_usage_1 = get_cpu_usage_nsec_self(fd); 491e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng this_task->cpu_usage = cpu_usage_1 - cpu_usage_0; 492e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = sem_post(&this_task->work_done_sem); 493e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(ret); 494e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 495e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = pthread_mutex_lock(&work_done_wait_mutex); 496e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(ret); 497e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = pthread_mutex_unlock(&work_done_wait_mutex); 498e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(ret); 499e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 500e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto again; 5017d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng/* ANDROID_CHANGE_BEGIN */ 5027d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng#endif // __APPLE__ 5037d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng/* ANDROID_CHANGE_END */ 504e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* ANDROID_CHANGE_BEGIN */ 5057d82a4640abdcc3ffbd89c7971a11e4ac7953b7fBen Cheng#if defined(__BIONIC__) || defined(__APPLE__) 506e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return NULL; 507e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#endif 508e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* ANDROID_CHANGE_END */ 509e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 510e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 511e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void create_tasks(void) 512e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 513e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct task_desc *task; 514e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pthread_attr_t attr; 515e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned long i; 516e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int err; 517e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 518e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng err = pthread_attr_init(&attr); 519e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(err); 520e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* ANDROID_CHANGE_BEGIN */ 521e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#if 0 522e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng err = pthread_attr_setstacksize(&attr, 523e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (size_t) max(16 * 1024, PTHREAD_STACK_MIN)); 524e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#else 525e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng err = pthread_attr_setstacksize(&attr, 526e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (size_t) max((unsigned) 16 * 1024, (unsigned) PTHREAD_STACK_MIN)); 527e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#endif 528e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* ANDROID_CHANGE_END */ 529e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(err); 530e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng err = pthread_mutex_lock(&start_work_mutex); 531e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(err); 532e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng err = pthread_mutex_lock(&work_done_wait_mutex); 533e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(err); 534e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < nr_tasks; i++) { 535e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task = tasks[i]; 536e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sem_init(&task->sleep_sem, 0, 0); 537e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sem_init(&task->ready_for_work, 0, 0); 538e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sem_init(&task->work_done_sem, 0, 0); 539e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task->curr_event = 0; 540e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng err = pthread_create(&task->thread, &attr, thread_func, task); 541e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(err); 542e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 543e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 544e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 545e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void wait_for_tasks(void) 546e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 547e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 cpu_usage_0, cpu_usage_1; 548e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct task_desc *task; 549e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned long i, ret; 550e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 551e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng start_time = get_nsecs(); 552e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cpu_usage = 0; 553e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pthread_mutex_unlock(&work_done_wait_mutex); 554e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 555e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < nr_tasks; i++) { 556e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task = tasks[i]; 557e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = sem_wait(&task->ready_for_work); 558e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(ret); 559e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sem_init(&task->ready_for_work, 0, 0); 560e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 561e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = pthread_mutex_lock(&work_done_wait_mutex); 562e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(ret); 563e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 564e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cpu_usage_0 = get_cpu_usage_nsec_parent(); 565e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 566e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pthread_mutex_unlock(&start_work_mutex); 567e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 568e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < nr_tasks; i++) { 569e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task = tasks[i]; 570e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = sem_wait(&task->work_done_sem); 571e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(ret); 572e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sem_init(&task->work_done_sem, 0, 0); 573e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cpu_usage += task->cpu_usage; 574e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task->cpu_usage = 0; 575e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 576e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 577e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cpu_usage_1 = get_cpu_usage_nsec_parent(); 578e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!runavg_cpu_usage) 579e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng runavg_cpu_usage = cpu_usage; 580e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng runavg_cpu_usage = (runavg_cpu_usage*9 + cpu_usage)/10; 581e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 582e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng parent_cpu_usage = cpu_usage_1 - cpu_usage_0; 583e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!runavg_parent_cpu_usage) 584e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng runavg_parent_cpu_usage = parent_cpu_usage; 585e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng runavg_parent_cpu_usage = (runavg_parent_cpu_usage*9 + 586e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng parent_cpu_usage)/10; 587e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 588e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = pthread_mutex_lock(&start_work_mutex); 589e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(ret); 590e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 591e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < nr_tasks; i++) { 592e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task = tasks[i]; 593e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sem_init(&task->sleep_sem, 0, 0); 594e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng task->curr_event = 0; 595e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 596e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 597e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 598e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void run_one_test(void) 599e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 600e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 T0, T1, delta, avg_delta, fluct; 601e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 602e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng T0 = get_nsecs(); 603e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng wait_for_tasks(); 604e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng T1 = get_nsecs(); 605e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 606e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng delta = T1 - T0; 607e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sum_runtime += delta; 608e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_runs++; 609e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 610e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng avg_delta = sum_runtime / nr_runs; 611e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (delta < avg_delta) 612e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fluct = avg_delta - delta; 613e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else 614e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fluct = delta - avg_delta; 615e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sum_fluct += fluct; 616e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!run_avg) 617e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng run_avg = delta; 618e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng run_avg = (run_avg*9 + delta)/10; 619e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 620e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("#%-3ld: %0.3f, ", 621e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_runs, (double)delta/1000000.0); 622e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 623e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("ravg: %0.2f, ", 624e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (double)run_avg/1e6); 625e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 626e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("cpu: %0.2f / %0.2f", 627e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (double)cpu_usage/1e6, (double)runavg_cpu_usage/1e6); 628e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 629e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#if 0 630e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 631e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * rusage statistics done by the parent, these are less 632e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * accurate than the sum_exec_runtime based statistics: 633e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 634e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" [%0.2f / %0.2f]", 635e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (double)parent_cpu_usage/1e6, 636e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (double)runavg_parent_cpu_usage/1e6); 637e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#endif 638e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 639e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("\n"); 640e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 641e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nr_sleep_corrections) 642e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" (%ld sleep corrections)\n", nr_sleep_corrections); 643e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_sleep_corrections = 0; 644e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 645e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 646e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void test_calibrations(void) 647e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 648e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 T0, T1; 649e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 650e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng T0 = get_nsecs(); 651e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng burn_nsecs(1e6); 652e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng T1 = get_nsecs(); 653e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 654e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("the run test took %" PRIu64 " nsecs\n", T1 - T0); 655e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 656e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng T0 = get_nsecs(); 657e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sleep_nsecs(1e6); 658e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng T1 = get_nsecs(); 659e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 660e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("the sleep test took %" PRIu64 " nsecs\n", T1 - T0); 661e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 662e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 663e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define FILL_FIELD(ptr, field, event, data) \ 664e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ptr.field = (typeof(ptr.field)) raw_field_value(event, #field, data) 665e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 666e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define FILL_ARRAY(ptr, array, event, data) \ 667e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengdo { \ 668e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng void *__array = raw_field_ptr(event, #array, data); \ 669e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng memcpy(ptr.array, __array, sizeof(ptr.array)); \ 670e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} while(0) 671e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 672e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define FILL_COMMON_FIELDS(ptr, event, data) \ 673e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengdo { \ 674e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(ptr, common_type, event, data); \ 675e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(ptr, common_flags, event, data); \ 676e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(ptr, common_preempt_count, event, data); \ 677e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(ptr, common_pid, event, data); \ 678e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(ptr, common_tgid, event, data); \ 679e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} while (0) 680e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 681e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 682e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 683e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct trace_switch_event { 684e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 size; 685e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 686e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u16 common_type; 687e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u8 common_flags; 688e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u8 common_preempt_count; 689e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 common_pid; 690e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 common_tgid; 691e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 692e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char prev_comm[16]; 693e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 prev_pid; 694e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 prev_prio; 695e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 prev_state; 696e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char next_comm[16]; 697e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 next_pid; 698e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 next_prio; 699e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 700e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 701e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct trace_runtime_event { 702e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 size; 703e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 704e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u16 common_type; 705e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u8 common_flags; 706e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u8 common_preempt_count; 707e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 common_pid; 708e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 common_tgid; 709e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 710e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char comm[16]; 711e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 pid; 712e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 runtime; 713e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 vruntime; 714e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 715e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 716e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct trace_wakeup_event { 717e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 size; 718e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 719e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u16 common_type; 720e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u8 common_flags; 721e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u8 common_preempt_count; 722e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 common_pid; 723e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 common_tgid; 724e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 725e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char comm[16]; 726e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 pid; 727e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 728e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 prio; 729e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 success; 730e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 cpu; 731e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 732e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 733e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct trace_fork_event { 734e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 size; 735e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 736e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u16 common_type; 737e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u8 common_flags; 738e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u8 common_preempt_count; 739e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 common_pid; 740e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 common_tgid; 741e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 742e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char parent_comm[16]; 743e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 parent_pid; 744e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char child_comm[16]; 745e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 child_pid; 746e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 747e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 748e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct trace_migrate_task_event { 749e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 size; 750e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 751e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u16 common_type; 752e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u8 common_flags; 753e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u8 common_preempt_count; 754e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 common_pid; 755e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 common_tgid; 756e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 757e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char comm[16]; 758e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 pid; 759e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 760e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 prio; 761e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 cpu; 762e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 763e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 764e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct trace_sched_handler { 765e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng void (*switch_event)(struct trace_switch_event *, 766e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *, 767e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *, 768e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu, 769e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp, 770e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread); 771e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 772e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng void (*runtime_event)(struct trace_runtime_event *, 773e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *, 774e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *, 775e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu, 776e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp, 777e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread); 778e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 779e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng void (*wakeup_event)(struct trace_wakeup_event *, 780e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *, 781e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *, 782e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu, 783e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp, 784e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread); 785e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 786e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng void (*fork_event)(struct trace_fork_event *, 787e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *, 788e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu, 789e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp, 790e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread); 791e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 792e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng void (*migrate_task_event)(struct trace_migrate_task_event *, 793e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *session, 794e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *, 795e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu, 796e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp, 797e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread); 798e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 799e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 800e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 801e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 802e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengreplay_wakeup_event(struct trace_wakeup_event *wakeup_event, 803e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *session __used, 804e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *event, 805e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu __used, 806e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp __used, 807e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 808e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 809e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct task_desc *waker, *wakee; 810e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 811e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (verbose) { 812e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("sched_wakeup event %p\n", event); 813e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 814e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" ... pid %d woke up %s/%d\n", 815e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng wakeup_event->common_pid, 816e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng wakeup_event->comm, 817e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng wakeup_event->pid); 818e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 819e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 820e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng waker = register_pid(wakeup_event->common_pid, "<unknown>"); 821e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng wakee = register_pid(wakeup_event->pid, wakeup_event->comm); 822e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 823e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng add_sched_event_wakeup(waker, timestamp, wakee); 824e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 825e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 826e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u64 cpu_last_switched[MAX_CPUS]; 827e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 828e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 829e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengreplay_switch_event(struct trace_switch_event *switch_event, 830e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *session __used, 831e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *event, 832e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu, 833e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp, 834e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 835e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 836e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct task_desc *prev, __used *next; 837e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp0; 838e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng s64 delta; 839e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 840e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (verbose) 841e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("sched_switch event %p\n", event); 842e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 843e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (cpu >= MAX_CPUS || cpu < 0) 844e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 845e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 846e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng timestamp0 = cpu_last_switched[cpu]; 847e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (timestamp0) 848e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng delta = timestamp - timestamp0; 849e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else 850e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng delta = 0; 851e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 852e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (delta < 0) 853e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng die("hm, delta: %" PRIu64 " < 0 ?\n", delta); 854e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 855e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (verbose) { 856e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" ... switch from %s/%d to %s/%d [ran %" PRIu64 " nsecs]\n", 857e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng switch_event->prev_comm, switch_event->prev_pid, 858e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng switch_event->next_comm, switch_event->next_pid, 859e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng delta); 860e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 861e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 862e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng prev = register_pid(switch_event->prev_pid, switch_event->prev_comm); 863e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng next = register_pid(switch_event->next_pid, switch_event->next_comm); 864e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 865e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cpu_last_switched[cpu] = timestamp; 866e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 867e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng add_sched_event_run(prev, timestamp, delta); 868e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng add_sched_event_sleep(prev, timestamp, switch_event->prev_state); 869e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 870e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 871e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 872e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 873e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengreplay_fork_event(struct trace_fork_event *fork_event, 874e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *event, 875e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu __used, 876e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp __used, 877e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 878e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 879e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (verbose) { 880e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("sched_fork event %p\n", event); 881e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("... parent: %s/%d\n", fork_event->parent_comm, fork_event->parent_pid); 882e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("... child: %s/%d\n", fork_event->child_comm, fork_event->child_pid); 883e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 884e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng register_pid(fork_event->parent_pid, fork_event->parent_comm); 885e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng register_pid(fork_event->child_pid, fork_event->child_comm); 886e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 887e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 888e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct trace_sched_handler replay_ops = { 889e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .wakeup_event = replay_wakeup_event, 890e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .switch_event = replay_switch_event, 891e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .fork_event = replay_fork_event, 892e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 893e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 894e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct sort_dimension { 895e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char *name; 896e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sort_fn_t cmp; 897e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct list_head list; 898e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 899e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 900e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic LIST_HEAD(cmp_pid); 901e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 902e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int 903e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengthread_lat_cmp(struct list_head *list, struct work_atoms *l, struct work_atoms *r) 904e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 905e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct sort_dimension *sort; 906e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int ret = 0; 907e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 908e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(list_empty(list)); 909e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 910e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_for_each_entry(sort, list, list) { 911e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = sort->cmp(l, r); 912e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (ret) 913e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return ret; 914e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 915e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 916e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return ret; 917e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 918e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 919e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct work_atoms * 920e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengthread_atoms_search(struct rb_root *root, struct thread *thread, 921e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct list_head *sort_list) 922e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 923e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct rb_node *node = root->rb_node; 924e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atoms key = { .thread = thread }; 925e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 926e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng while (node) { 927e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atoms *atoms; 928e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cmp; 929e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 930e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atoms = container_of(node, struct work_atoms, node); 931e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 932e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cmp = thread_lat_cmp(sort_list, &key, atoms); 933e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (cmp > 0) 934e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng node = node->rb_left; 935e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else if (cmp < 0) 936e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng node = node->rb_right; 937e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else { 938e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(thread != atoms->thread); 939e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return atoms; 940e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 941e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 942e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return NULL; 943e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 944e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 945e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 946e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng__thread_latency_insert(struct rb_root *root, struct work_atoms *data, 947e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct list_head *sort_list) 948e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 949e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct rb_node **new = &(root->rb_node), *parent = NULL; 950e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 951e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng while (*new) { 952e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atoms *this; 953e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cmp; 954e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 955e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng this = container_of(*new, struct work_atoms, node); 956e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng parent = *new; 957e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 958e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cmp = thread_lat_cmp(sort_list, data, this); 959e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 960e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (cmp > 0) 961e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng new = &((*new)->rb_left); 962e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else 963e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng new = &((*new)->rb_right); 964e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 965e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 966e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng rb_link_node(&data->node, parent, new); 967e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng rb_insert_color(&data->node, root); 968e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 969e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 970e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void thread_atoms_insert(struct thread *thread) 971e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 972e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atoms *atoms = zalloc(sizeof(*atoms)); 973e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!atoms) 974e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng die("No memory"); 975e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 976e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atoms->thread = thread; 977e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng INIT_LIST_HEAD(&atoms->work_list); 978e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng __thread_latency_insert(&atom_root, atoms, &cmp_pid); 979e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 980e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 981e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 982e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chenglatency_fork_event(struct trace_fork_event *fork_event __used, 983e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *event __used, 984e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu __used, 985e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp __used, 986e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 987e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 988e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* should insert the newcomer */ 989e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 990e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 991e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng__used 992e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic char sched_out_state(struct trace_switch_event *switch_event) 993e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 994e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char *str = TASK_STATE_TO_CHAR_STR; 995e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 996e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return str[switch_event->prev_state]; 997e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 998e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 999e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1000e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengadd_sched_out_event(struct work_atoms *atoms, 1001e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char run_state, 1002e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp) 1003e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1004e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atom *atom = zalloc(sizeof(*atom)); 1005e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!atom) 1006e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng die("Non memory"); 1007e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1008e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom->sched_out_time = timestamp; 1009e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1010e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (run_state == 'R') { 1011e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom->state = THREAD_WAIT_CPU; 1012e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom->wake_up_time = atom->sched_out_time; 1013e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1014e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1015e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_add_tail(&atom->list, &atoms->work_list); 1016e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1017e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1018e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1019e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengadd_runtime_event(struct work_atoms *atoms, u64 delta, u64 timestamp __used) 1020e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1021e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atom *atom; 1022e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1023e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(list_empty(&atoms->work_list)); 1024e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1025e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom = list_entry(atoms->work_list.prev, struct work_atom, list); 1026e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1027e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom->runtime += delta; 1028e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atoms->total_runtime += delta; 1029e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1030e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1031e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1032e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengadd_sched_in_event(struct work_atoms *atoms, u64 timestamp) 1033e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1034e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atom *atom; 1035e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 delta; 1036e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1037e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (list_empty(&atoms->work_list)) 1038e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 1039e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1040e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom = list_entry(atoms->work_list.prev, struct work_atom, list); 1041e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1042e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (atom->state != THREAD_WAIT_CPU) 1043e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 1044e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1045e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (timestamp < atom->wake_up_time) { 1046e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom->state = THREAD_IGNORE; 1047e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 1048e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1049e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1050e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom->state = THREAD_SCHED_IN; 1051e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom->sched_in_time = timestamp; 1052e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1053e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng delta = atom->sched_in_time - atom->wake_up_time; 1054e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atoms->total_lat += delta; 1055e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (delta > atoms->max_lat) { 1056e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atoms->max_lat = delta; 1057e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atoms->max_lat_at = timestamp; 1058e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1059e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atoms->nb_atoms++; 1060e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1061e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1062e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1063e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chenglatency_switch_event(struct trace_switch_event *switch_event, 1064e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *session, 1065e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *event __used, 1066e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu, 1067e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp, 1068e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 1069e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1070e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atoms *out_events, *in_events; 1071e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *sched_out, *sched_in; 1072e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp0; 1073e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng s64 delta; 1074e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1075e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(cpu >= MAX_CPUS || cpu < 0); 1076e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1077e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng timestamp0 = cpu_last_switched[cpu]; 1078e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cpu_last_switched[cpu] = timestamp; 1079e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (timestamp0) 1080e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng delta = timestamp - timestamp0; 1081e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else 1082e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng delta = 0; 1083e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1084e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (delta < 0) 1085e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng die("hm, delta: %" PRIu64 " < 0 ?\n", delta); 1086e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1087e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1088e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sched_out = perf_session__findnew(session, switch_event->prev_pid); 1089e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sched_in = perf_session__findnew(session, switch_event->next_pid); 1090e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1091e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng out_events = thread_atoms_search(&atom_root, sched_out, &cmp_pid); 1092e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!out_events) { 1093e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng thread_atoms_insert(sched_out); 1094e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng out_events = thread_atoms_search(&atom_root, sched_out, &cmp_pid); 1095e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!out_events) 1096e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng die("out-event: Internal tree error"); 1097e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1098e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng add_sched_out_event(out_events, sched_out_state(switch_event), timestamp); 1099e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1100e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng in_events = thread_atoms_search(&atom_root, sched_in, &cmp_pid); 1101e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!in_events) { 1102e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng thread_atoms_insert(sched_in); 1103e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng in_events = thread_atoms_search(&atom_root, sched_in, &cmp_pid); 1104e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!in_events) 1105e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng die("in-event: Internal tree error"); 1106e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 1107e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Take came in we have not heard about yet, 1108e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * add in an initial atom in runnable state: 1109e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 1110e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng add_sched_out_event(in_events, 'R', timestamp); 1111e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1112e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng add_sched_in_event(in_events, timestamp); 1113e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1114e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1115e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1116e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chenglatency_runtime_event(struct trace_runtime_event *runtime_event, 1117e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *session, 1118e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *event __used, 1119e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu, 1120e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp, 1121e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *this_thread __used) 1122e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1123e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread = perf_session__findnew(session, runtime_event->pid); 1124e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atoms *atoms = thread_atoms_search(&atom_root, thread, &cmp_pid); 1125e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1126e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(cpu >= MAX_CPUS || cpu < 0); 1127e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!atoms) { 1128e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng thread_atoms_insert(thread); 1129e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atoms = thread_atoms_search(&atom_root, thread, &cmp_pid); 1130e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!atoms) 1131e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng die("in-event: Internal tree error"); 1132e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng add_sched_out_event(atoms, 'R', timestamp); 1133e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1134e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1135e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng add_runtime_event(atoms, runtime_event->runtime, timestamp); 1136e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1137e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1138e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1139e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chenglatency_wakeup_event(struct trace_wakeup_event *wakeup_event, 1140e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *session, 1141e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *__event __used, 1142e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu __used, 1143e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp, 1144e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 1145e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1146e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atoms *atoms; 1147e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atom *atom; 1148e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *wakee; 1149e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1150e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Note for later, it may be interesting to observe the failing cases */ 1151e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!wakeup_event->success) 1152e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 1153e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1154e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng wakee = perf_session__findnew(session, wakeup_event->pid); 1155e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atoms = thread_atoms_search(&atom_root, wakee, &cmp_pid); 1156e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!atoms) { 1157e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng thread_atoms_insert(wakee); 1158e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atoms = thread_atoms_search(&atom_root, wakee, &cmp_pid); 1159e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!atoms) 1160e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng die("wakeup-event: Internal tree error"); 1161e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng add_sched_out_event(atoms, 'S', timestamp); 1162e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1163e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1164e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(list_empty(&atoms->work_list)); 1165e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1166e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom = list_entry(atoms->work_list.prev, struct work_atom, list); 1167e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1168e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 1169e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * You WILL be missing events if you've recorded only 1170e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * one CPU, or are only looking at only one, so don't 1171e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * make useless noise. 1172e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 1173e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (profile_cpu == -1 && atom->state != THREAD_SLEEPING) 1174e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_state_machine_bugs++; 1175e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1176e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_timestamps++; 1177e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (atom->sched_out_time > timestamp) { 1178e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_unordered_timestamps++; 1179e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 1180e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1181e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1182e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom->state = THREAD_WAIT_CPU; 1183e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom->wake_up_time = timestamp; 1184e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1185e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1186e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1187e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chenglatency_migrate_task_event(struct trace_migrate_task_event *migrate_task_event, 1188e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *session, 1189e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *__event __used, 1190e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu __used, 1191e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp, 1192e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 1193e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1194e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atoms *atoms; 1195e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atom *atom; 1196e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *migrant; 1197e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1198e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 1199e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Only need to worry about migration when profiling one CPU. 1200e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 1201e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (profile_cpu == -1) 1202e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 1203e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1204e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng migrant = perf_session__findnew(session, migrate_task_event->pid); 1205e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atoms = thread_atoms_search(&atom_root, migrant, &cmp_pid); 1206e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!atoms) { 1207e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng thread_atoms_insert(migrant); 1208e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng register_pid(migrant->pid, migrant->comm); 1209e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atoms = thread_atoms_search(&atom_root, migrant, &cmp_pid); 1210e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!atoms) 1211e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng die("migration-event: Internal tree error"); 1212e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng add_sched_out_event(atoms, 'R', timestamp); 1213e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1214e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1215e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(list_empty(&atoms->work_list)); 1216e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1217e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom = list_entry(atoms->work_list.prev, struct work_atom, list); 1218e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng atom->sched_in_time = atom->sched_out_time = atom->wake_up_time = timestamp; 1219e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1220e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_timestamps++; 1221e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1222e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (atom->sched_out_time > timestamp) 1223e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_unordered_timestamps++; 1224e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1225e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1226e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct trace_sched_handler lat_ops = { 1227e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .wakeup_event = latency_wakeup_event, 1228e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .switch_event = latency_switch_event, 1229e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .runtime_event = latency_runtime_event, 1230e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .fork_event = latency_fork_event, 1231e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .migrate_task_event = latency_migrate_task_event, 1232e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1233e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1234e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void output_lat_thread(struct work_atoms *work_list) 1235e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1236e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int i; 1237e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int ret; 1238e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 avg; 1239e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1240e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!work_list->nb_atoms) 1241e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 1242e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 1243e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Ignore idle threads: 1244e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 1245e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcmp(work_list->thread->comm, "swapper")) 1246e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 1247e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1248e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng all_runtime += work_list->total_runtime; 1249e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng all_count += work_list->nb_atoms; 1250e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1251e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = printf(" %s:%d ", work_list->thread->comm, work_list->thread->pid); 1252e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1253e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < 24 - ret; i++) 1254e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" "); 1255e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1256e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng avg = work_list->total_lat / work_list->nb_atoms; 1257e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1258e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("|%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max at: %9.6f s\n", 1259e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (double)work_list->total_runtime / 1e6, 1260e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng work_list->nb_atoms, (double)avg / 1e6, 1261e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (double)work_list->max_lat / 1e6, 1262e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (double)work_list->max_lat_at / 1e9); 1263e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1264e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1265e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int pid_cmp(struct work_atoms *l, struct work_atoms *r) 1266e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1267e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (l->thread->pid < r->thread->pid) 1268e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 1269e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (l->thread->pid > r->thread->pid) 1270e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 1; 1271e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1272e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 1273e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1274e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1275e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct sort_dimension pid_sort_dimension = { 1276e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .name = "pid", 1277e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .cmp = pid_cmp, 1278e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1279e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1280e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int avg_cmp(struct work_atoms *l, struct work_atoms *r) 1281e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1282e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 avgl, avgr; 1283e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1284e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!l->nb_atoms) 1285e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 1286e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1287e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!r->nb_atoms) 1288e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 1; 1289e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1290e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng avgl = l->total_lat / l->nb_atoms; 1291e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng avgr = r->total_lat / r->nb_atoms; 1292e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1293e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (avgl < avgr) 1294e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 1295e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (avgl > avgr) 1296e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 1; 1297e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1298e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 1299e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1300e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1301e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct sort_dimension avg_sort_dimension = { 1302e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .name = "avg", 1303e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .cmp = avg_cmp, 1304e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1305e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1306e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int max_cmp(struct work_atoms *l, struct work_atoms *r) 1307e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1308e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (l->max_lat < r->max_lat) 1309e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 1310e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (l->max_lat > r->max_lat) 1311e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 1; 1312e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1313e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 1314e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1315e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1316e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct sort_dimension max_sort_dimension = { 1317e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .name = "max", 1318e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .cmp = max_cmp, 1319e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1320e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1321e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int switch_cmp(struct work_atoms *l, struct work_atoms *r) 1322e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1323e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (l->nb_atoms < r->nb_atoms) 1324e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 1325e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (l->nb_atoms > r->nb_atoms) 1326e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 1; 1327e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1328e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 1329e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1330e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1331e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct sort_dimension switch_sort_dimension = { 1332e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .name = "switch", 1333e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .cmp = switch_cmp, 1334e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1335e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1336e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int runtime_cmp(struct work_atoms *l, struct work_atoms *r) 1337e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1338e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (l->total_runtime < r->total_runtime) 1339e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 1340e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (l->total_runtime > r->total_runtime) 1341e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 1; 1342e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1343e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 1344e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1345e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1346e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct sort_dimension runtime_sort_dimension = { 1347e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .name = "runtime", 1348e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .cmp = runtime_cmp, 1349e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1350e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1351e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct sort_dimension *available_sorts[] = { 1352e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng &pid_sort_dimension, 1353e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng &avg_sort_dimension, 1354e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng &max_sort_dimension, 1355e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng &switch_sort_dimension, 1356e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng &runtime_sort_dimension, 1357e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1358e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1359e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define NB_AVAILABLE_SORTS (int)(sizeof(available_sorts) / sizeof(struct sort_dimension *)) 1360e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1361e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic LIST_HEAD(sort_list); 1362e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1363e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int sort_dimension__add(const char *tok, struct list_head *list) 1364e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1365e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int i; 1366e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1367e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < NB_AVAILABLE_SORTS; i++) { 1368e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcmp(available_sorts[i]->name, tok)) { 1369e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_add_tail(&available_sorts[i]->list, list); 1370e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1371e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 1372e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1373e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1374e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1375e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 1376e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1377e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1378e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void setup_sorting(void); 1379e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1380e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void sort_lat(void) 1381e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1382e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct rb_node *node; 1383e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1384e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (;;) { 1385e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atoms *data; 1386e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng node = rb_first(&atom_root); 1387e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!node) 1388e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 1389e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1390e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng rb_erase(node, &atom_root); 1391e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng data = rb_entry(node, struct work_atoms, node); 1392e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng __thread_latency_insert(&sorted_atom_root, data, &sort_list); 1393e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1394e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1395e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1396e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct trace_sched_handler *trace_handler; 1397e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1398e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1399e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengprocess_sched_wakeup_event(void *data, struct perf_session *session, 1400e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *event, 1401e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu __used, 1402e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp __used, 1403e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 1404e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1405e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct trace_wakeup_event wakeup_event; 1406e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1407e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_COMMON_FIELDS(wakeup_event, event, data); 1408e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1409e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_ARRAY(wakeup_event, comm, event, data); 1410e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(wakeup_event, pid, event, data); 1411e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(wakeup_event, prio, event, data); 1412e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(wakeup_event, success, event, data); 1413e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(wakeup_event, cpu, event, data); 1414e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1415e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (trace_handler->wakeup_event) 1416e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng trace_handler->wakeup_event(&wakeup_event, session, event, 1417e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cpu, timestamp, thread); 1418e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1419e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1420e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* 1421e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Track the current task - that way we can know whether there's any 1422e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * weird events, such as a task being switched away that is not current. 1423e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 1424e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int max_cpu; 1425e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1426e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic u32 curr_pid[MAX_CPUS] = { [0 ... MAX_CPUS-1] = -1 }; 1427e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1428e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct thread *curr_thread[MAX_CPUS]; 1429e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1430e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic char next_shortname1 = 'A'; 1431e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic char next_shortname2 = '0'; 1432e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1433e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1434e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengmap_switch_event(struct trace_switch_event *switch_event, 1435e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *session, 1436e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *event __used, 1437e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int this_cpu, 1438e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp, 1439e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 1440e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1441e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *sched_out __used, *sched_in; 1442e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int new_shortname; 1443e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp0; 1444e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng s64 delta; 1445e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu; 1446e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1447e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0); 1448e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1449e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (this_cpu > max_cpu) 1450e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng max_cpu = this_cpu; 1451e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1452e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng timestamp0 = cpu_last_switched[this_cpu]; 1453e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cpu_last_switched[this_cpu] = timestamp; 1454e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (timestamp0) 1455e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng delta = timestamp - timestamp0; 1456e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else 1457e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng delta = 0; 1458e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1459e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (delta < 0) 1460e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng die("hm, delta: %" PRIu64 " < 0 ?\n", delta); 1461e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1462e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1463e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sched_out = perf_session__findnew(session, switch_event->prev_pid); 1464e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sched_in = perf_session__findnew(session, switch_event->next_pid); 1465e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1466e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng curr_thread[this_cpu] = sched_in; 1467e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1468e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" "); 1469e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1470e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng new_shortname = 0; 1471e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!sched_in->shortname[0]) { 1472e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sched_in->shortname[0] = next_shortname1; 1473e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sched_in->shortname[1] = next_shortname2; 1474e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1475e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (next_shortname1 < 'Z') { 1476e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng next_shortname1++; 1477e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else { 1478e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng next_shortname1='A'; 1479e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (next_shortname2 < '9') { 1480e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng next_shortname2++; 1481e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else { 1482e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng next_shortname2='0'; 1483e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1484e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1485e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng new_shortname = 1; 1486e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1487e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1488e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (cpu = 0; cpu <= max_cpu; cpu++) { 1489e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (cpu != this_cpu) 1490e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" "); 1491e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else 1492e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("*"); 1493e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1494e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (curr_thread[cpu]) { 1495e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (curr_thread[cpu]->pid) 1496e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("%2s ", curr_thread[cpu]->shortname); 1497e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else 1498e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(". "); 1499e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else 1500e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" "); 1501e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1502e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1503e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" %12.6f secs ", (double)timestamp/1e9); 1504e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (new_shortname) { 1505e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("%s => %s:%d\n", 1506e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sched_in->shortname, sched_in->comm, sched_in->pid); 1507e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else { 1508e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("\n"); 1509e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1510e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1511e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1512e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1513e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1514e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengprocess_sched_switch_event(void *data, struct perf_session *session, 1515e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *event, 1516e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int this_cpu, 1517e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp __used, 1518e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 1519e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1520e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct trace_switch_event switch_event; 1521e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1522e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_COMMON_FIELDS(switch_event, event, data); 1523e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1524e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_ARRAY(switch_event, prev_comm, event, data); 1525e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(switch_event, prev_pid, event, data); 1526e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(switch_event, prev_prio, event, data); 1527e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(switch_event, prev_state, event, data); 1528e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_ARRAY(switch_event, next_comm, event, data); 1529e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(switch_event, next_pid, event, data); 1530e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(switch_event, next_prio, event, data); 1531e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1532e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (curr_pid[this_cpu] != (u32)-1) { 1533e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 1534e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Are we trying to switch away a PID that is 1535e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * not current? 1536e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 1537e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (curr_pid[this_cpu] != switch_event.prev_pid) 1538e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_context_switch_bugs++; 1539e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1540e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (trace_handler->switch_event) 1541e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng trace_handler->switch_event(&switch_event, session, event, 1542e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng this_cpu, timestamp, thread); 1543e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1544e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng curr_pid[this_cpu] = switch_event.next_pid; 1545e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1546e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1547e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1548e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengprocess_sched_runtime_event(void *data, struct perf_session *session, 1549e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *event, 1550e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu __used, 1551e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp __used, 1552e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 1553e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1554e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct trace_runtime_event runtime_event; 1555e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1556e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_ARRAY(runtime_event, comm, event, data); 1557e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(runtime_event, pid, event, data); 1558e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(runtime_event, runtime, event, data); 1559e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(runtime_event, vruntime, event, data); 1560e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1561e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (trace_handler->runtime_event) 1562e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng trace_handler->runtime_event(&runtime_event, session, event, cpu, timestamp, thread); 1563e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1564e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1565e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1566e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengprocess_sched_fork_event(void *data, 1567e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *event, 1568e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu __used, 1569e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp __used, 1570e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 1571e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1572e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct trace_fork_event fork_event; 1573e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1574e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_COMMON_FIELDS(fork_event, event, data); 1575e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1576e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_ARRAY(fork_event, parent_comm, event, data); 1577e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(fork_event, parent_pid, event, data); 1578e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_ARRAY(fork_event, child_comm, event, data); 1579e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(fork_event, child_pid, event, data); 1580e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1581e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (trace_handler->fork_event) 1582e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng trace_handler->fork_event(&fork_event, event, 1583e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cpu, timestamp, thread); 1584e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1585e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1586e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1587e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengprocess_sched_exit_event(struct event *event, 1588e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu __used, 1589e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp __used, 1590e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 1591e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1592e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (verbose) 1593e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("sched_exit event %p\n", event); 1594e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1595e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1596e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void 1597e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengprocess_sched_migrate_task_event(void *data, struct perf_session *session, 1598e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *event, 1599e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu __used, 1600e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp __used, 1601e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread __used) 1602e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1603e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct trace_migrate_task_event migrate_task_event; 1604e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1605e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_COMMON_FIELDS(migrate_task_event, event, data); 1606e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1607e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_ARRAY(migrate_task_event, comm, event, data); 1608e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(migrate_task_event, pid, event, data); 1609e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(migrate_task_event, prio, event, data); 1610e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng FILL_FIELD(migrate_task_event, cpu, event, data); 1611e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1612e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (trace_handler->migrate_task_event) 1613e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng trace_handler->migrate_task_event(&migrate_task_event, session, 1614e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event, cpu, timestamp, thread); 1615e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1616e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1617e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void process_raw_event(union perf_event *raw_event __used, 1618e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *session, void *data, int cpu, 1619e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 timestamp, struct thread *thread) 1620e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1621e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct event *event; 1622e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int type; 1623e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1624e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1625e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng type = trace_parse_common_type(data); 1626e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event = trace_find_event(type); 1627e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1628e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcmp(event->name, "sched_switch")) 1629e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng process_sched_switch_event(data, session, event, cpu, timestamp, thread); 1630e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcmp(event->name, "sched_stat_runtime")) 1631e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng process_sched_runtime_event(data, session, event, cpu, timestamp, thread); 1632e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcmp(event->name, "sched_wakeup")) 1633e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng process_sched_wakeup_event(data, session, event, cpu, timestamp, thread); 1634e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcmp(event->name, "sched_wakeup_new")) 1635e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng process_sched_wakeup_event(data, session, event, cpu, timestamp, thread); 1636e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcmp(event->name, "sched_process_fork")) 1637e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng process_sched_fork_event(data, event, cpu, timestamp, thread); 1638e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcmp(event->name, "sched_process_exit")) 1639e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng process_sched_exit_event(event, cpu, timestamp, thread); 1640e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcmp(event->name, "sched_migrate_task")) 1641e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng process_sched_migrate_task_event(data, session, event, cpu, timestamp, thread); 1642e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1643e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1644e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int process_sample_event(union perf_event *event, 1645e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_sample *sample, 1646e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evsel *evsel __used, 1647e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *session) 1648e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1649e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread *thread; 1650e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1651e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!(session->sample_type & PERF_SAMPLE_RAW)) 1652e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 1653e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1654e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng thread = perf_session__findnew(session, sample->pid); 1655e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (thread == NULL) { 1656e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pr_debug("problem processing %d event, skipping it.\n", 1657e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event->header.type); 1658e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 1659e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1660e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1661e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); 1662e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1663e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (profile_cpu != -1 && profile_cpu != (int)sample->cpu) 1664e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 1665e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1666e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng process_raw_event(event, session, sample->raw_data, sample->cpu, 1667e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sample->time, thread); 1668e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1669e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 1670e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1671e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1672e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct perf_event_ops event_ops = { 1673e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .sample = process_sample_event, 1674e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .comm = perf_event__process_comm, 1675e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .lost = perf_event__process_lost, 1676e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .fork = perf_event__process_task, 1677e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .ordered_samples = true, 1678e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1679e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1680e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int read_events(void) 1681e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1682e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int err = -EINVAL; 1683e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_session *session = perf_session__new(input_name, O_RDONLY, 1684e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 0, false, &event_ops); 1685e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (session == NULL) 1686e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -ENOMEM; 1687e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1688e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (perf_session__has_traces(session, "record -R")) { 1689e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng err = perf_session__process_events(session, &event_ops); 1690e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_events = session->hists.stats.nr_events[0]; 1691e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_lost_events = session->hists.stats.total_lost; 1692e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_lost_chunks = session->hists.stats.nr_events[PERF_RECORD_LOST]; 1693e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1694e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1695e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_session__delete(session); 1696e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return err; 1697e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1698e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1699e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void print_bad_events(void) 1700e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1701e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nr_unordered_timestamps && nr_timestamps) { 1702e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" INFO: %.3f%% unordered timestamps (%ld out of %ld)\n", 1703e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (double)nr_unordered_timestamps/(double)nr_timestamps*100.0, 1704e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_unordered_timestamps, nr_timestamps); 1705e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1706e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nr_lost_events && nr_events) { 1707e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" INFO: %.3f%% lost events (%ld out of %ld, in %ld chunks)\n", 1708e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (double)nr_lost_events/(double)nr_events*100.0, 1709e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_lost_events, nr_events, nr_lost_chunks); 1710e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1711e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nr_state_machine_bugs && nr_timestamps) { 1712e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" INFO: %.3f%% state machine bugs (%ld out of %ld)", 1713e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (double)nr_state_machine_bugs/(double)nr_timestamps*100.0, 1714e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_state_machine_bugs, nr_timestamps); 1715e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nr_lost_events) 1716e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" (due to lost events?)"); 1717e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("\n"); 1718e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1719e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nr_context_switch_bugs && nr_timestamps) { 1720e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" INFO: %.3f%% context switch bugs (%ld out of %ld)", 1721e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (double)nr_context_switch_bugs/(double)nr_timestamps*100.0, 1722e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_context_switch_bugs, nr_timestamps); 1723e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nr_lost_events) 1724e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" (due to lost events?)"); 1725e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("\n"); 1726e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1727e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1728e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1729e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void __cmd_lat(void) 1730e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1731e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct rb_node *next; 1732e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1733e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng setup_pager(); 1734e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng read_events(); 1735e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sort_lat(); 1736e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1737e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("\n ---------------------------------------------------------------------------------------------------------------\n"); 1738e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" Task | Runtime ms | Switches | Average delay ms | Maximum delay ms | Maximum delay at |\n"); 1739e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" ---------------------------------------------------------------------------------------------------------------\n"); 1740e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1741e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng next = rb_first(&sorted_atom_root); 1742e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1743e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng while (next) { 1744e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct work_atoms *work_list; 1745e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1746e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng work_list = rb_entry(next, struct work_atoms, node); 1747e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng output_lat_thread(work_list); 1748e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng next = rb_next(next); 1749e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1750e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1751e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" -----------------------------------------------------------------------------------------\n"); 1752e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" TOTAL: |%11.3f ms |%9" PRIu64 " |\n", 1753e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (double)all_runtime/1e6, all_count); 1754e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1755e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" ---------------------------------------------------\n"); 1756e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1757e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng print_bad_events(); 1758e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("\n"); 1759e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1760e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1761e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1762e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic struct trace_sched_handler map_ops = { 1763e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .wakeup_event = NULL, 1764e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .switch_event = map_switch_event, 1765e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .runtime_event = NULL, 1766e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .fork_event = NULL, 1767e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1768e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1769e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void __cmd_map(void) 1770e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1771e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng max_cpu = sysconf(_SC_NPROCESSORS_CONF); 1772e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1773e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng setup_pager(); 1774e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng read_events(); 1775e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng print_bad_events(); 1776e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1777e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1778e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void __cmd_replay(void) 1779e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1780e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned long i; 1781e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1782e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng calibrate_run_measurement_overhead(); 1783e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng calibrate_sleep_measurement_overhead(); 1784e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1785e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng test_calibrations(); 1786e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1787e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng read_events(); 1788e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1789e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("nr_run_events: %ld\n", nr_run_events); 1790e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("nr_sleep_events: %ld\n", nr_sleep_events); 1791e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("nr_wakeup_events: %ld\n", nr_wakeup_events); 1792e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1793e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (targetless_wakeups) 1794e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("target-less wakeups: %ld\n", targetless_wakeups); 1795e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (multitarget_wakeups) 1796e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("multi-target wakeups: %ld\n", multitarget_wakeups); 1797e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nr_run_events_optimized) 1798e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("run atoms optimized: %ld\n", 1799e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nr_run_events_optimized); 1800e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1801e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng print_task_traces(); 1802e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng add_cross_task_wakeups(); 1803e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1804e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng create_tasks(); 1805e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("------------------------------------------------------------\n"); 1806e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < replay_repeat; i++) 1807e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng run_one_test(); 1808e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1809e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1810e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1811e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const char * const sched_usage[] = { 1812e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "perf sched [<options>] {record|latency|map|replay|trace}", 1813e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng NULL 1814e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1815e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1816e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const struct option sched_options[] = { 1817e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_STRING('i', "input", &input_name, "file", 1818e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "input file name"), 1819e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_INCR('v', "verbose", &verbose, 1820e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "be more verbose (show symbol address, etc)"), 1821e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1822e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "dump raw trace in ASCII"), 1823e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_END() 1824e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1825e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1826e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const char * const latency_usage[] = { 1827e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "perf sched latency [<options>]", 1828e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng NULL 1829e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1830e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1831e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const struct option latency_options[] = { 1832e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_STRING('s', "sort", &sort_order, "key[,key2...]", 1833e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "sort by key(s): runtime, switch, avg, max"), 1834e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_INCR('v', "verbose", &verbose, 1835e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "be more verbose (show symbol address, etc)"), 1836e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_INTEGER('C', "CPU", &profile_cpu, 1837e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "CPU to profile on"), 1838e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1839e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "dump raw trace in ASCII"), 1840e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_END() 1841e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1842e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1843e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const char * const replay_usage[] = { 1844e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "perf sched replay [<options>]", 1845e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng NULL 1846e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1847e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1848e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const struct option replay_options[] = { 1849e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_UINTEGER('r', "repeat", &replay_repeat, 1850e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "repeat the workload replay N times (-1: infinite)"), 1851e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_INCR('v', "verbose", &verbose, 1852e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "be more verbose (show symbol address, etc)"), 1853e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1854e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "dump raw trace in ASCII"), 1855e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_END() 1856e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1857e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1858e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void setup_sorting(void) 1859e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1860e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char *tmp, *tok, *str = strdup(sort_order); 1861e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1862e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (tok = strtok_r(str, ", ", &tmp); 1863e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng tok; tok = strtok_r(NULL, ", ", &tmp)) { 1864e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (sort_dimension__add(tok, &sort_list) < 0) { 1865e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng error("Unknown --sort key: `%s'", tok); 1866e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng usage_with_options(latency_usage, latency_options); 1867e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1868e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1869e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1870e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng free(str); 1871e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1872e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sort_dimension__add("pid", &cmp_pid); 1873e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1874e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1875e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const char *record_args[] = { 1876e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "record", 1877e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-a", 1878e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-R", 1879e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-f", 1880e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-m", "1024", 1881e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-c", "1", 1882e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-e", "sched:sched_switch", 1883e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-e", "sched:sched_stat_wait", 1884e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-e", "sched:sched_stat_sleep", 1885e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-e", "sched:sched_stat_iowait", 1886e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-e", "sched:sched_stat_runtime", 1887e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-e", "sched:sched_process_exit", 1888e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-e", "sched:sched_process_fork", 1889e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-e", "sched:sched_wakeup", 1890e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "-e", "sched:sched_migrate_task", 1891e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 1892e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1893e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int __cmd_record(int argc, const char **argv) 1894e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1895e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int rec_argc, i, j; 1896e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char **rec_argv; 1897e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1898e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng rec_argc = ARRAY_SIZE(record_args) + argc - 1; 1899e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng rec_argv = calloc(rec_argc + 1, sizeof(char *)); 1900e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1901e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (rec_argv == NULL) 1902e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -ENOMEM; 1903e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1904e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < ARRAY_SIZE(record_args); i++) 1905e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng rec_argv[i] = strdup(record_args[i]); 1906e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1907e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (j = 1; j < (unsigned int)argc; j++, i++) 1908e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng rec_argv[i] = argv[j]; 1909e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1910e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng BUG_ON(i != rec_argc); 1911e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1912e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return cmd_record(i, rec_argv, NULL); 1913e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1914e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1915e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint cmd_sched(int argc, const char **argv, const char *prefix __used) 1916e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 1917e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng argc = parse_options(argc, argv, sched_options, sched_usage, 1918e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng PARSE_OPT_STOP_AT_NON_OPTION); 1919e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!argc) 1920e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng usage_with_options(sched_usage, sched_options); 1921e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1922e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 1923e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Aliased to 'perf script' for now: 1924e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 1925e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcmp(argv[0], "script")) 1926e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return cmd_script(argc, argv, prefix); 1927e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1928e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng symbol__init(); 1929e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strncmp(argv[0], "rec", 3)) { 1930e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return __cmd_record(argc, argv); 1931e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else if (!strncmp(argv[0], "lat", 3)) { 1932e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng trace_handler = &lat_ops; 1933e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (argc > 1) { 1934e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng argc = parse_options(argc, argv, latency_options, latency_usage, 0); 1935e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (argc) 1936e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng usage_with_options(latency_usage, latency_options); 1937e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1938e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng setup_sorting(); 1939e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng __cmd_lat(); 1940e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else if (!strcmp(argv[0], "map")) { 1941e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng trace_handler = &map_ops; 1942e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng setup_sorting(); 1943e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng __cmd_map(); 1944e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else if (!strncmp(argv[0], "rep", 3)) { 1945e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng trace_handler = &replay_ops; 1946e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (argc) { 1947e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng argc = parse_options(argc, argv, replay_options, replay_usage, 0); 1948e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (argc) 1949e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng usage_with_options(replay_usage, replay_options); 1950e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1951e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng __cmd_replay(); 1952e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else { 1953e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng usage_with_options(sched_usage, sched_options); 1954e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 1955e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 1956e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 1957e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 1958