1*58e6ee5fSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0
2*58e6ee5fSAndroid Build Coastguard Worker /*
3*58e6ee5fSAndroid Build Coastguard Worker * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <[email protected]>
4*58e6ee5fSAndroid Build Coastguard Worker *
5*58e6ee5fSAndroid Build Coastguard Worker */
6*58e6ee5fSAndroid Build Coastguard Worker #define _LARGEFILE64_SOURCE
7*58e6ee5fSAndroid Build Coastguard Worker #include <dirent.h>
8*58e6ee5fSAndroid Build Coastguard Worker #include <stdio.h>
9*58e6ee5fSAndroid Build Coastguard Worker #include <stdlib.h>
10*58e6ee5fSAndroid Build Coastguard Worker #include <string.h>
11*58e6ee5fSAndroid Build Coastguard Worker #include <getopt.h>
12*58e6ee5fSAndroid Build Coastguard Worker #include <stdarg.h>
13*58e6ee5fSAndroid Build Coastguard Worker #include <sys/types.h>
14*58e6ee5fSAndroid Build Coastguard Worker #include <sys/stat.h>
15*58e6ee5fSAndroid Build Coastguard Worker #include <sys/wait.h>
16*58e6ee5fSAndroid Build Coastguard Worker #include <sys/mman.h>
17*58e6ee5fSAndroid Build Coastguard Worker #include <fcntl.h>
18*58e6ee5fSAndroid Build Coastguard Worker #include <signal.h>
19*58e6ee5fSAndroid Build Coastguard Worker #include <unistd.h>
20*58e6ee5fSAndroid Build Coastguard Worker #include <ctype.h>
21*58e6ee5fSAndroid Build Coastguard Worker #include <errno.h>
22*58e6ee5fSAndroid Build Coastguard Worker
23*58e6ee5fSAndroid Build Coastguard Worker #include "trace-local.h"
24*58e6ee5fSAndroid Build Coastguard Worker #include "trace-hash.h"
25*58e6ee5fSAndroid Build Coastguard Worker #include "trace-hash-local.h"
26*58e6ee5fSAndroid Build Coastguard Worker #include "kbuffer.h"
27*58e6ee5fSAndroid Build Coastguard Worker #include "list.h"
28*58e6ee5fSAndroid Build Coastguard Worker
29*58e6ee5fSAndroid Build Coastguard Worker /*
30*58e6ee5fSAndroid Build Coastguard Worker * tep_func_repeat_format is defined as a weak variable in the
31*58e6ee5fSAndroid Build Coastguard Worker * libtraceevent library function plugin, to allow applications
32*58e6ee5fSAndroid Build Coastguard Worker * to override the format of the timestamp it prints for the
33*58e6ee5fSAndroid Build Coastguard Worker * last function that repeated.
34*58e6ee5fSAndroid Build Coastguard Worker */
35*58e6ee5fSAndroid Build Coastguard Worker const char *tep_func_repeat_format;
36*58e6ee5fSAndroid Build Coastguard Worker
37*58e6ee5fSAndroid Build Coastguard Worker static struct filter_str {
38*58e6ee5fSAndroid Build Coastguard Worker struct filter_str *next;
39*58e6ee5fSAndroid Build Coastguard Worker char *filter;
40*58e6ee5fSAndroid Build Coastguard Worker int neg;
41*58e6ee5fSAndroid Build Coastguard Worker } *filter_strings;
42*58e6ee5fSAndroid Build Coastguard Worker static struct filter_str **filter_next = &filter_strings;
43*58e6ee5fSAndroid Build Coastguard Worker
44*58e6ee5fSAndroid Build Coastguard Worker struct filter {
45*58e6ee5fSAndroid Build Coastguard Worker struct filter *next;
46*58e6ee5fSAndroid Build Coastguard Worker struct tep_event_filter *filter;
47*58e6ee5fSAndroid Build Coastguard Worker };
48*58e6ee5fSAndroid Build Coastguard Worker
49*58e6ee5fSAndroid Build Coastguard Worker struct event_str {
50*58e6ee5fSAndroid Build Coastguard Worker struct event_str *next;
51*58e6ee5fSAndroid Build Coastguard Worker const char *event;
52*58e6ee5fSAndroid Build Coastguard Worker };
53*58e6ee5fSAndroid Build Coastguard Worker
54*58e6ee5fSAndroid Build Coastguard Worker struct handle_list {
55*58e6ee5fSAndroid Build Coastguard Worker struct list_head list;
56*58e6ee5fSAndroid Build Coastguard Worker struct tracecmd_input *handle;
57*58e6ee5fSAndroid Build Coastguard Worker const char *file;
58*58e6ee5fSAndroid Build Coastguard Worker int cpus;
59*58e6ee5fSAndroid Build Coastguard Worker int done;
60*58e6ee5fSAndroid Build Coastguard Worker struct tep_record *record;
61*58e6ee5fSAndroid Build Coastguard Worker struct filter *event_filters;
62*58e6ee5fSAndroid Build Coastguard Worker struct filter *event_filter_out;
63*58e6ee5fSAndroid Build Coastguard Worker unsigned long long *last_timestamp;
64*58e6ee5fSAndroid Build Coastguard Worker };
65*58e6ee5fSAndroid Build Coastguard Worker static struct list_head handle_list;
66*58e6ee5fSAndroid Build Coastguard Worker
67*58e6ee5fSAndroid Build Coastguard Worker struct input_files {
68*58e6ee5fSAndroid Build Coastguard Worker struct list_head list;
69*58e6ee5fSAndroid Build Coastguard Worker const char *file;
70*58e6ee5fSAndroid Build Coastguard Worker long long tsoffset;
71*58e6ee5fSAndroid Build Coastguard Worker unsigned long long ts2secs;
72*58e6ee5fSAndroid Build Coastguard Worker };
73*58e6ee5fSAndroid Build Coastguard Worker static struct list_head input_files;
74*58e6ee5fSAndroid Build Coastguard Worker static struct input_files *last_input_file;
75*58e6ee5fSAndroid Build Coastguard Worker
76*58e6ee5fSAndroid Build Coastguard Worker struct pid_list {
77*58e6ee5fSAndroid Build Coastguard Worker struct pid_list *next;
78*58e6ee5fSAndroid Build Coastguard Worker char *pid;
79*58e6ee5fSAndroid Build Coastguard Worker int free;
80*58e6ee5fSAndroid Build Coastguard Worker } *pid_list;
81*58e6ee5fSAndroid Build Coastguard Worker
82*58e6ee5fSAndroid Build Coastguard Worker struct pid_list *comm_list;
83*58e6ee5fSAndroid Build Coastguard Worker
84*58e6ee5fSAndroid Build Coastguard Worker static unsigned int page_size;
85*58e6ee5fSAndroid Build Coastguard Worker static int input_fd;
86*58e6ee5fSAndroid Build Coastguard Worker static const char *default_input_file = DEFAULT_INPUT_FILE;
87*58e6ee5fSAndroid Build Coastguard Worker static const char *input_file;
88*58e6ee5fSAndroid Build Coastguard Worker static int multi_inputs;
89*58e6ee5fSAndroid Build Coastguard Worker static int max_file_size;
90*58e6ee5fSAndroid Build Coastguard Worker
91*58e6ee5fSAndroid Build Coastguard Worker static int instances;
92*58e6ee5fSAndroid Build Coastguard Worker
93*58e6ee5fSAndroid Build Coastguard Worker static int *filter_cpus;
94*58e6ee5fSAndroid Build Coastguard Worker static int nr_filter_cpus;
95*58e6ee5fSAndroid Build Coastguard Worker static int test_filters_mode;
96*58e6ee5fSAndroid Build Coastguard Worker
97*58e6ee5fSAndroid Build Coastguard Worker static int show_wakeup;
98*58e6ee5fSAndroid Build Coastguard Worker static int wakeup_id;
99*58e6ee5fSAndroid Build Coastguard Worker static int wakeup_new_id;
100*58e6ee5fSAndroid Build Coastguard Worker static int sched_id;
101*58e6ee5fSAndroid Build Coastguard Worker static int stacktrace_id;
102*58e6ee5fSAndroid Build Coastguard Worker
103*58e6ee5fSAndroid Build Coastguard Worker static int profile;
104*58e6ee5fSAndroid Build Coastguard Worker
105*58e6ee5fSAndroid Build Coastguard Worker static int buffer_breaks = 0;
106*58e6ee5fSAndroid Build Coastguard Worker
107*58e6ee5fSAndroid Build Coastguard Worker static int no_irqs;
108*58e6ee5fSAndroid Build Coastguard Worker static int no_softirqs;
109*58e6ee5fSAndroid Build Coastguard Worker
110*58e6ee5fSAndroid Build Coastguard Worker static int tsdiff;
111*58e6ee5fSAndroid Build Coastguard Worker static int tscheck;
112*58e6ee5fSAndroid Build Coastguard Worker
113*58e6ee5fSAndroid Build Coastguard Worker static int latency_format;
114*58e6ee5fSAndroid Build Coastguard Worker static bool raw_format;
115*58e6ee5fSAndroid Build Coastguard Worker static const char *format_type = TEP_PRINT_INFO;
116*58e6ee5fSAndroid Build Coastguard Worker
117*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *wakeup_task;
118*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *wakeup_success;
119*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *wakeup_new_task;
120*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *wakeup_new_success;
121*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *sched_task;
122*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *sched_prio;
123*58e6ee5fSAndroid Build Coastguard Worker
124*58e6ee5fSAndroid Build Coastguard Worker static unsigned long long total_wakeup_lat;
125*58e6ee5fSAndroid Build Coastguard Worker static unsigned long wakeup_lat_count;
126*58e6ee5fSAndroid Build Coastguard Worker
127*58e6ee5fSAndroid Build Coastguard Worker static unsigned long long total_wakeup_rt_lat;
128*58e6ee5fSAndroid Build Coastguard Worker static unsigned long wakeup_rt_lat_count;
129*58e6ee5fSAndroid Build Coastguard Worker
130*58e6ee5fSAndroid Build Coastguard Worker struct wakeup_info {
131*58e6ee5fSAndroid Build Coastguard Worker struct trace_hash_item hash;
132*58e6ee5fSAndroid Build Coastguard Worker unsigned long long start;
133*58e6ee5fSAndroid Build Coastguard Worker int pid;
134*58e6ee5fSAndroid Build Coastguard Worker };
135*58e6ee5fSAndroid Build Coastguard Worker
136*58e6ee5fSAndroid Build Coastguard Worker static struct hook_list *hooks;
137*58e6ee5fSAndroid Build Coastguard Worker static struct hook_list *last_hook;
138*58e6ee5fSAndroid Build Coastguard Worker
139*58e6ee5fSAndroid Build Coastguard Worker #define WAKEUP_HASH_SIZE 1024
140*58e6ee5fSAndroid Build Coastguard Worker static struct trace_hash wakeup_hash;
141*58e6ee5fSAndroid Build Coastguard Worker
print_event_name(struct trace_seq * s,struct tep_event * event)142*58e6ee5fSAndroid Build Coastguard Worker static void print_event_name(struct trace_seq *s, struct tep_event *event)
143*58e6ee5fSAndroid Build Coastguard Worker {
144*58e6ee5fSAndroid Build Coastguard Worker static const char *spaces = " "; /* 20 spaces */
145*58e6ee5fSAndroid Build Coastguard Worker const char *name;
146*58e6ee5fSAndroid Build Coastguard Worker int len;
147*58e6ee5fSAndroid Build Coastguard Worker
148*58e6ee5fSAndroid Build Coastguard Worker name = event ? event->name : "(NULL)";
149*58e6ee5fSAndroid Build Coastguard Worker
150*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(s, " %s: ", name);
151*58e6ee5fSAndroid Build Coastguard Worker
152*58e6ee5fSAndroid Build Coastguard Worker /* Space out the event names evenly. */
153*58e6ee5fSAndroid Build Coastguard Worker len = strlen(name);
154*58e6ee5fSAndroid Build Coastguard Worker if (len < 20)
155*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(s, "%.*s", 20 - len, spaces);
156*58e6ee5fSAndroid Build Coastguard Worker }
157*58e6ee5fSAndroid Build Coastguard Worker
158*58e6ee5fSAndroid Build Coastguard Worker enum time_fmt {
159*58e6ee5fSAndroid Build Coastguard Worker TIME_FMT_LAT = 1,
160*58e6ee5fSAndroid Build Coastguard Worker TIME_FMT_NORMAL = 2,
161*58e6ee5fSAndroid Build Coastguard Worker };
162*58e6ee5fSAndroid Build Coastguard Worker
time_format(struct tracecmd_input * handle,enum time_fmt tf)163*58e6ee5fSAndroid Build Coastguard Worker static const char *time_format(struct tracecmd_input *handle, enum time_fmt tf)
164*58e6ee5fSAndroid Build Coastguard Worker {
165*58e6ee5fSAndroid Build Coastguard Worker struct tep_handle *tep = tracecmd_get_tep(handle);
166*58e6ee5fSAndroid Build Coastguard Worker
167*58e6ee5fSAndroid Build Coastguard Worker switch (tf) {
168*58e6ee5fSAndroid Build Coastguard Worker case TIME_FMT_LAT:
169*58e6ee5fSAndroid Build Coastguard Worker if (latency_format)
170*58e6ee5fSAndroid Build Coastguard Worker return "%8.8s-%-5d %3d";
171*58e6ee5fSAndroid Build Coastguard Worker return "%16s-%-5d [%03d]";
172*58e6ee5fSAndroid Build Coastguard Worker default:
173*58e6ee5fSAndroid Build Coastguard Worker if (tracecmd_get_flags(handle) & TRACECMD_FL_IN_USECS) {
174*58e6ee5fSAndroid Build Coastguard Worker if (tep_test_flag(tep, TEP_NSEC_OUTPUT))
175*58e6ee5fSAndroid Build Coastguard Worker return " %9.1d:";
176*58e6ee5fSAndroid Build Coastguard Worker else
177*58e6ee5fSAndroid Build Coastguard Worker return " %6.1000d:";
178*58e6ee5fSAndroid Build Coastguard Worker } else
179*58e6ee5fSAndroid Build Coastguard Worker return "%12d:";
180*58e6ee5fSAndroid Build Coastguard Worker }
181*58e6ee5fSAndroid Build Coastguard Worker }
182*58e6ee5fSAndroid Build Coastguard Worker
print_event(struct trace_seq * s,struct tracecmd_input * handle,struct tep_record * record)183*58e6ee5fSAndroid Build Coastguard Worker static void print_event(struct trace_seq *s, struct tracecmd_input *handle,
184*58e6ee5fSAndroid Build Coastguard Worker struct tep_record *record)
185*58e6ee5fSAndroid Build Coastguard Worker {
186*58e6ee5fSAndroid Build Coastguard Worker struct tep_handle *tep = tracecmd_get_tep(handle);
187*58e6ee5fSAndroid Build Coastguard Worker struct tep_event *event;
188*58e6ee5fSAndroid Build Coastguard Worker const char *lfmt = time_format(handle, TIME_FMT_LAT);
189*58e6ee5fSAndroid Build Coastguard Worker const char *tfmt = time_format(handle, TIME_FMT_NORMAL);
190*58e6ee5fSAndroid Build Coastguard Worker
191*58e6ee5fSAndroid Build Coastguard Worker event = tep_find_event_by_record(tep, record);
192*58e6ee5fSAndroid Build Coastguard Worker tep_print_event(tep, s, record, lfmt, TEP_PRINT_COMM,
193*58e6ee5fSAndroid Build Coastguard Worker TEP_PRINT_PID, TEP_PRINT_CPU);
194*58e6ee5fSAndroid Build Coastguard Worker tep_print_event(tep, s, record, tfmt, TEP_PRINT_TIME);
195*58e6ee5fSAndroid Build Coastguard Worker print_event_name(s, event);
196*58e6ee5fSAndroid Build Coastguard Worker tep_print_event(tep, s, record, "%s", format_type);
197*58e6ee5fSAndroid Build Coastguard Worker }
198*58e6ee5fSAndroid Build Coastguard Worker
199*58e6ee5fSAndroid Build Coastguard Worker /* Debug variables for testing tracecmd_read_at */
200*58e6ee5fSAndroid Build Coastguard Worker #define TEST_READ_AT 0
201*58e6ee5fSAndroid Build Coastguard Worker #if TEST_READ_AT
202*58e6ee5fSAndroid Build Coastguard Worker #define DO_TEST
203*58e6ee5fSAndroid Build Coastguard Worker static off64_t test_read_at_offset;
204*58e6ee5fSAndroid Build Coastguard Worker static int test_read_at_copy = 100;
205*58e6ee5fSAndroid Build Coastguard Worker static int test_read_at_index;
show_test(struct tracecmd_input * handle)206*58e6ee5fSAndroid Build Coastguard Worker static void show_test(struct tracecmd_input *handle)
207*58e6ee5fSAndroid Build Coastguard Worker {
208*58e6ee5fSAndroid Build Coastguard Worker struct tep_record *record;
209*58e6ee5fSAndroid Build Coastguard Worker struct trace_seq s;
210*58e6ee5fSAndroid Build Coastguard Worker
211*58e6ee5fSAndroid Build Coastguard Worker if (!test_read_at_offset) {
212*58e6ee5fSAndroid Build Coastguard Worker printf("\nNO RECORD COPIED\n");
213*58e6ee5fSAndroid Build Coastguard Worker return;
214*58e6ee5fSAndroid Build Coastguard Worker }
215*58e6ee5fSAndroid Build Coastguard Worker
216*58e6ee5fSAndroid Build Coastguard Worker record = tracecmd_read_at(handle, test_read_at_offset, NULL);
217*58e6ee5fSAndroid Build Coastguard Worker printf("\nHERE'S THE COPY RECORD\n");
218*58e6ee5fSAndroid Build Coastguard Worker trace_seq_init(&s);
219*58e6ee5fSAndroid Build Coastguard Worker print_event(&s, handle, record);
220*58e6ee5fSAndroid Build Coastguard Worker trace_seq_do_printf(&s);
221*58e6ee5fSAndroid Build Coastguard Worker trace_seq_destroy(&s);
222*58e6ee5fSAndroid Build Coastguard Worker printf("\n");
223*58e6ee5fSAndroid Build Coastguard Worker
224*58e6ee5fSAndroid Build Coastguard Worker tracecmd_free_record(record);
225*58e6ee5fSAndroid Build Coastguard Worker }
226*58e6ee5fSAndroid Build Coastguard Worker
test_save(struct tep_record * record,int cpu)227*58e6ee5fSAndroid Build Coastguard Worker static void test_save(struct tep_record *record, int cpu)
228*58e6ee5fSAndroid Build Coastguard Worker {
229*58e6ee5fSAndroid Build Coastguard Worker if (test_read_at_index++ == test_read_at_copy) {
230*58e6ee5fSAndroid Build Coastguard Worker test_read_at_offset = record->offset;
231*58e6ee5fSAndroid Build Coastguard Worker printf("\nUSING THIS RECORD\n");
232*58e6ee5fSAndroid Build Coastguard Worker }
233*58e6ee5fSAndroid Build Coastguard Worker }
234*58e6ee5fSAndroid Build Coastguard Worker #endif /* TEST_READ_AT */
235*58e6ee5fSAndroid Build Coastguard Worker
236*58e6ee5fSAndroid Build Coastguard Worker /* Debug variables for testing tracecmd_set_cpu_at_timestamp */
237*58e6ee5fSAndroid Build Coastguard Worker #define TEST_AT_TIMESTAMP 0
238*58e6ee5fSAndroid Build Coastguard Worker #if TEST_AT_TIMESTAMP
239*58e6ee5fSAndroid Build Coastguard Worker #define DO_TEST
240*58e6ee5fSAndroid Build Coastguard Worker static unsigned long long test_at_timestamp_ts;
241*58e6ee5fSAndroid Build Coastguard Worker static int test_at_timestamp_copy = 100;
242*58e6ee5fSAndroid Build Coastguard Worker static int test_at_timestamp_cpu = -1;
243*58e6ee5fSAndroid Build Coastguard Worker static int test_at_timestamp_index;
show_test(struct tracecmd_input * handle)244*58e6ee5fSAndroid Build Coastguard Worker static void show_test(struct tracecmd_input *handle)
245*58e6ee5fSAndroid Build Coastguard Worker {
246*58e6ee5fSAndroid Build Coastguard Worker struct tep_record *record;
247*58e6ee5fSAndroid Build Coastguard Worker struct trace_seq s;
248*58e6ee5fSAndroid Build Coastguard Worker int cpu = test_at_timestamp_cpu;
249*58e6ee5fSAndroid Build Coastguard Worker
250*58e6ee5fSAndroid Build Coastguard Worker if (!test_at_timestamp_ts) {
251*58e6ee5fSAndroid Build Coastguard Worker printf("\nNO RECORD COPIED\n");
252*58e6ee5fSAndroid Build Coastguard Worker return;
253*58e6ee5fSAndroid Build Coastguard Worker }
254*58e6ee5fSAndroid Build Coastguard Worker
255*58e6ee5fSAndroid Build Coastguard Worker if (tracecmd_set_cpu_to_timestamp(handle, cpu, test_at_timestamp_ts))
256*58e6ee5fSAndroid Build Coastguard Worker return;
257*58e6ee5fSAndroid Build Coastguard Worker
258*58e6ee5fSAndroid Build Coastguard Worker record = tracecmd_read_data(handle, cpu);
259*58e6ee5fSAndroid Build Coastguard Worker printf("\nHERE'S THE COPY RECORD with page %p offset=%p\n",
260*58e6ee5fSAndroid Build Coastguard Worker (void *)(record->offset & ~(page_size - 1)),
261*58e6ee5fSAndroid Build Coastguard Worker (void *)record->offset);
262*58e6ee5fSAndroid Build Coastguard Worker trace_seq_init(&s);
263*58e6ee5fSAndroid Build Coastguard Worker print_event(&s, handle, record);
264*58e6ee5fSAndroid Build Coastguard Worker trace_seq_do_printf(&s);
265*58e6ee5fSAndroid Build Coastguard Worker trace_seq_destroy(&s);
266*58e6ee5fSAndroid Build Coastguard Worker printf("\n");
267*58e6ee5fSAndroid Build Coastguard Worker
268*58e6ee5fSAndroid Build Coastguard Worker tracecmd_free_record(record);
269*58e6ee5fSAndroid Build Coastguard Worker }
270*58e6ee5fSAndroid Build Coastguard Worker
test_save(struct tep_record * record,int cpu)271*58e6ee5fSAndroid Build Coastguard Worker static void test_save(struct tep_record *record, int cpu)
272*58e6ee5fSAndroid Build Coastguard Worker {
273*58e6ee5fSAndroid Build Coastguard Worker if (test_at_timestamp_index++ == test_at_timestamp_copy) {
274*58e6ee5fSAndroid Build Coastguard Worker test_at_timestamp_ts = record->ts;
275*58e6ee5fSAndroid Build Coastguard Worker test_at_timestamp_cpu = cpu;
276*58e6ee5fSAndroid Build Coastguard Worker printf("\nUSING THIS RECORD page=%p offset=%p\n",
277*58e6ee5fSAndroid Build Coastguard Worker (void *)(record->offset & ~(page_size - 1)),
278*58e6ee5fSAndroid Build Coastguard Worker (void *)record->offset);
279*58e6ee5fSAndroid Build Coastguard Worker }
280*58e6ee5fSAndroid Build Coastguard Worker }
281*58e6ee5fSAndroid Build Coastguard Worker #endif /* TEST_AT_TIMESTAMP */
282*58e6ee5fSAndroid Build Coastguard Worker
283*58e6ee5fSAndroid Build Coastguard Worker #define TEST_FIRST_LAST 0
284*58e6ee5fSAndroid Build Coastguard Worker #if TEST_FIRST_LAST
285*58e6ee5fSAndroid Build Coastguard Worker #define DO_TEST
show_test(struct tracecmd_input * handle)286*58e6ee5fSAndroid Build Coastguard Worker static void show_test(struct tracecmd_input *handle)
287*58e6ee5fSAndroid Build Coastguard Worker {
288*58e6ee5fSAndroid Build Coastguard Worker struct tep_record *record;
289*58e6ee5fSAndroid Build Coastguard Worker struct trace_seq s;
290*58e6ee5fSAndroid Build Coastguard Worker int cpu = 0;
291*58e6ee5fSAndroid Build Coastguard Worker
292*58e6ee5fSAndroid Build Coastguard Worker record = tracecmd_read_cpu_first(handle, cpu);
293*58e6ee5fSAndroid Build Coastguard Worker if (!record) {
294*58e6ee5fSAndroid Build Coastguard Worker printf("No first record?\n");
295*58e6ee5fSAndroid Build Coastguard Worker return;
296*58e6ee5fSAndroid Build Coastguard Worker }
297*58e6ee5fSAndroid Build Coastguard Worker
298*58e6ee5fSAndroid Build Coastguard Worker printf("\nHERE'S THE FIRST RECORD with offset %p\n",
299*58e6ee5fSAndroid Build Coastguard Worker (void *)record->offset);
300*58e6ee5fSAndroid Build Coastguard Worker trace_seq_init(&s);
301*58e6ee5fSAndroid Build Coastguard Worker print_event(&s, handle, record);
302*58e6ee5fSAndroid Build Coastguard Worker trace_seq_do_printf(&s);
303*58e6ee5fSAndroid Build Coastguard Worker trace_seq_destroy(&s);
304*58e6ee5fSAndroid Build Coastguard Worker printf("\n");
305*58e6ee5fSAndroid Build Coastguard Worker
306*58e6ee5fSAndroid Build Coastguard Worker tracecmd_free_record(record);
307*58e6ee5fSAndroid Build Coastguard Worker
308*58e6ee5fSAndroid Build Coastguard Worker record = tracecmd_read_cpu_last(handle, cpu);
309*58e6ee5fSAndroid Build Coastguard Worker if (!record) {
310*58e6ee5fSAndroid Build Coastguard Worker printf("No last record?\n");
311*58e6ee5fSAndroid Build Coastguard Worker return;
312*58e6ee5fSAndroid Build Coastguard Worker }
313*58e6ee5fSAndroid Build Coastguard Worker
314*58e6ee5fSAndroid Build Coastguard Worker printf("\nHERE'S THE LAST RECORD with offset %p\n",
315*58e6ee5fSAndroid Build Coastguard Worker (void *)record->offset);
316*58e6ee5fSAndroid Build Coastguard Worker trace_seq_init(&s);
317*58e6ee5fSAndroid Build Coastguard Worker print_event(&s, handle, record);
318*58e6ee5fSAndroid Build Coastguard Worker trace_seq_do_printf(&s);
319*58e6ee5fSAndroid Build Coastguard Worker trace_seq_destroy(&s);
320*58e6ee5fSAndroid Build Coastguard Worker printf("\n");
321*58e6ee5fSAndroid Build Coastguard Worker
322*58e6ee5fSAndroid Build Coastguard Worker tracecmd_free_record(record);
323*58e6ee5fSAndroid Build Coastguard Worker }
test_save(struct tep_record * record,int cpu)324*58e6ee5fSAndroid Build Coastguard Worker static void test_save(struct tep_record *record, int cpu)
325*58e6ee5fSAndroid Build Coastguard Worker {
326*58e6ee5fSAndroid Build Coastguard Worker }
327*58e6ee5fSAndroid Build Coastguard Worker #endif /* TEST_FIRST_LAST */
328*58e6ee5fSAndroid Build Coastguard Worker
329*58e6ee5fSAndroid Build Coastguard Worker #ifndef DO_TEST
show_test(struct tracecmd_input * handle)330*58e6ee5fSAndroid Build Coastguard Worker static void show_test(struct tracecmd_input *handle)
331*58e6ee5fSAndroid Build Coastguard Worker {
332*58e6ee5fSAndroid Build Coastguard Worker /* quiet the compiler */
333*58e6ee5fSAndroid Build Coastguard Worker if (0)
334*58e6ee5fSAndroid Build Coastguard Worker print_event(NULL, NULL, NULL);
335*58e6ee5fSAndroid Build Coastguard Worker }
test_save(struct tep_record * record,int cpu)336*58e6ee5fSAndroid Build Coastguard Worker static void test_save(struct tep_record *record, int cpu)
337*58e6ee5fSAndroid Build Coastguard Worker {
338*58e6ee5fSAndroid Build Coastguard Worker }
339*58e6ee5fSAndroid Build Coastguard Worker #endif
340*58e6ee5fSAndroid Build Coastguard Worker
add_input(const char * file)341*58e6ee5fSAndroid Build Coastguard Worker static void add_input(const char *file)
342*58e6ee5fSAndroid Build Coastguard Worker {
343*58e6ee5fSAndroid Build Coastguard Worker struct input_files *item;
344*58e6ee5fSAndroid Build Coastguard Worker
345*58e6ee5fSAndroid Build Coastguard Worker item = malloc(sizeof(*item));
346*58e6ee5fSAndroid Build Coastguard Worker if (!item)
347*58e6ee5fSAndroid Build Coastguard Worker die("Failed to allocate for %s", file);
348*58e6ee5fSAndroid Build Coastguard Worker memset(item, 0, sizeof(*item));
349*58e6ee5fSAndroid Build Coastguard Worker item->file = file;
350*58e6ee5fSAndroid Build Coastguard Worker list_add_tail(&item->list, &input_files);
351*58e6ee5fSAndroid Build Coastguard Worker last_input_file = item;
352*58e6ee5fSAndroid Build Coastguard Worker }
353*58e6ee5fSAndroid Build Coastguard Worker
add_handle(struct tracecmd_input * handle,const char * file)354*58e6ee5fSAndroid Build Coastguard Worker static void add_handle(struct tracecmd_input *handle, const char *file)
355*58e6ee5fSAndroid Build Coastguard Worker {
356*58e6ee5fSAndroid Build Coastguard Worker struct handle_list *item;
357*58e6ee5fSAndroid Build Coastguard Worker
358*58e6ee5fSAndroid Build Coastguard Worker item = malloc(sizeof(*item));
359*58e6ee5fSAndroid Build Coastguard Worker if (!item)
360*58e6ee5fSAndroid Build Coastguard Worker die("Failed ot allocate for %s", file);
361*58e6ee5fSAndroid Build Coastguard Worker memset(item, 0, sizeof(*item));
362*58e6ee5fSAndroid Build Coastguard Worker item->handle = handle;
363*58e6ee5fSAndroid Build Coastguard Worker if (file) {
364*58e6ee5fSAndroid Build Coastguard Worker item->file = file + strlen(file);
365*58e6ee5fSAndroid Build Coastguard Worker /* we want just the base name */
366*58e6ee5fSAndroid Build Coastguard Worker while (item->file >= file && *item->file != '/')
367*58e6ee5fSAndroid Build Coastguard Worker item->file--;
368*58e6ee5fSAndroid Build Coastguard Worker item->file++;
369*58e6ee5fSAndroid Build Coastguard Worker if (strlen(item->file) > max_file_size)
370*58e6ee5fSAndroid Build Coastguard Worker max_file_size = strlen(item->file);
371*58e6ee5fSAndroid Build Coastguard Worker }
372*58e6ee5fSAndroid Build Coastguard Worker list_add_tail(&item->list, &handle_list);
373*58e6ee5fSAndroid Build Coastguard Worker }
374*58e6ee5fSAndroid Build Coastguard Worker
free_inputs(void)375*58e6ee5fSAndroid Build Coastguard Worker static void free_inputs(void)
376*58e6ee5fSAndroid Build Coastguard Worker {
377*58e6ee5fSAndroid Build Coastguard Worker struct input_files *item;
378*58e6ee5fSAndroid Build Coastguard Worker
379*58e6ee5fSAndroid Build Coastguard Worker while (!list_empty(&input_files)) {
380*58e6ee5fSAndroid Build Coastguard Worker item = container_of(input_files.next, struct input_files, list);
381*58e6ee5fSAndroid Build Coastguard Worker list_del(&item->list);
382*58e6ee5fSAndroid Build Coastguard Worker free(item);
383*58e6ee5fSAndroid Build Coastguard Worker }
384*58e6ee5fSAndroid Build Coastguard Worker }
385*58e6ee5fSAndroid Build Coastguard Worker
free_handles(void)386*58e6ee5fSAndroid Build Coastguard Worker static void free_handles(void)
387*58e6ee5fSAndroid Build Coastguard Worker {
388*58e6ee5fSAndroid Build Coastguard Worker struct handle_list *item;
389*58e6ee5fSAndroid Build Coastguard Worker
390*58e6ee5fSAndroid Build Coastguard Worker while (!list_empty(&handle_list)) {
391*58e6ee5fSAndroid Build Coastguard Worker item = container_of(handle_list.next, struct handle_list, list);
392*58e6ee5fSAndroid Build Coastguard Worker list_del(&item->list);
393*58e6ee5fSAndroid Build Coastguard Worker free(item);
394*58e6ee5fSAndroid Build Coastguard Worker }
395*58e6ee5fSAndroid Build Coastguard Worker }
396*58e6ee5fSAndroid Build Coastguard Worker
add_filter(const char * filter,int neg)397*58e6ee5fSAndroid Build Coastguard Worker static void add_filter(const char *filter, int neg)
398*58e6ee5fSAndroid Build Coastguard Worker {
399*58e6ee5fSAndroid Build Coastguard Worker struct filter_str *ftr;
400*58e6ee5fSAndroid Build Coastguard Worker
401*58e6ee5fSAndroid Build Coastguard Worker ftr = malloc(sizeof(*ftr));
402*58e6ee5fSAndroid Build Coastguard Worker if (!ftr)
403*58e6ee5fSAndroid Build Coastguard Worker die("Failed to allocate for filter %s", filter);
404*58e6ee5fSAndroid Build Coastguard Worker ftr->filter = strdup(filter);
405*58e6ee5fSAndroid Build Coastguard Worker if (!ftr->filter)
406*58e6ee5fSAndroid Build Coastguard Worker die("malloc");
407*58e6ee5fSAndroid Build Coastguard Worker ftr->next = NULL;
408*58e6ee5fSAndroid Build Coastguard Worker ftr->neg = neg;
409*58e6ee5fSAndroid Build Coastguard Worker
410*58e6ee5fSAndroid Build Coastguard Worker /* must maintain order of command line */
411*58e6ee5fSAndroid Build Coastguard Worker *filter_next = ftr;
412*58e6ee5fSAndroid Build Coastguard Worker filter_next = &ftr->next;
413*58e6ee5fSAndroid Build Coastguard Worker }
414*58e6ee5fSAndroid Build Coastguard Worker
__add_filter(struct pid_list ** head,const char * arg)415*58e6ee5fSAndroid Build Coastguard Worker static void __add_filter(struct pid_list **head, const char *arg)
416*58e6ee5fSAndroid Build Coastguard Worker {
417*58e6ee5fSAndroid Build Coastguard Worker struct pid_list *list;
418*58e6ee5fSAndroid Build Coastguard Worker char *pids = strdup(arg);
419*58e6ee5fSAndroid Build Coastguard Worker char *pid;
420*58e6ee5fSAndroid Build Coastguard Worker char *sav;
421*58e6ee5fSAndroid Build Coastguard Worker int free = 1;
422*58e6ee5fSAndroid Build Coastguard Worker
423*58e6ee5fSAndroid Build Coastguard Worker if (!pids)
424*58e6ee5fSAndroid Build Coastguard Worker die("malloc");
425*58e6ee5fSAndroid Build Coastguard Worker
426*58e6ee5fSAndroid Build Coastguard Worker pid = strtok_r(pids, ",", &sav);
427*58e6ee5fSAndroid Build Coastguard Worker while (pid) {
428*58e6ee5fSAndroid Build Coastguard Worker list = malloc(sizeof(*list));
429*58e6ee5fSAndroid Build Coastguard Worker if (!list)
430*58e6ee5fSAndroid Build Coastguard Worker die("Failed to allocate for arg %s", arg);
431*58e6ee5fSAndroid Build Coastguard Worker list->pid = pid;
432*58e6ee5fSAndroid Build Coastguard Worker list->free = free;
433*58e6ee5fSAndroid Build Coastguard Worker list->next = *head;
434*58e6ee5fSAndroid Build Coastguard Worker *head = list;
435*58e6ee5fSAndroid Build Coastguard Worker /* The first pid needs to be freed */
436*58e6ee5fSAndroid Build Coastguard Worker free = 0;
437*58e6ee5fSAndroid Build Coastguard Worker pid = strtok_r(NULL, ",", &sav);
438*58e6ee5fSAndroid Build Coastguard Worker }
439*58e6ee5fSAndroid Build Coastguard Worker }
440*58e6ee5fSAndroid Build Coastguard Worker
add_comm_filter(const char * arg)441*58e6ee5fSAndroid Build Coastguard Worker static void add_comm_filter(const char *arg)
442*58e6ee5fSAndroid Build Coastguard Worker {
443*58e6ee5fSAndroid Build Coastguard Worker __add_filter(&comm_list, arg);
444*58e6ee5fSAndroid Build Coastguard Worker }
445*58e6ee5fSAndroid Build Coastguard Worker
add_pid_filter(const char * arg)446*58e6ee5fSAndroid Build Coastguard Worker static void add_pid_filter(const char *arg)
447*58e6ee5fSAndroid Build Coastguard Worker {
448*58e6ee5fSAndroid Build Coastguard Worker __add_filter(&pid_list, arg);
449*58e6ee5fSAndroid Build Coastguard Worker }
450*58e6ee5fSAndroid Build Coastguard Worker
append_pid_filter(char * curr_filter,char * pid)451*58e6ee5fSAndroid Build Coastguard Worker static char *append_pid_filter(char *curr_filter, char *pid)
452*58e6ee5fSAndroid Build Coastguard Worker {
453*58e6ee5fSAndroid Build Coastguard Worker char *filter;
454*58e6ee5fSAndroid Build Coastguard Worker int len, curr_len;
455*58e6ee5fSAndroid Build Coastguard Worker
456*58e6ee5fSAndroid Build Coastguard Worker #define FILTER_FMT "(common_pid==" __STR ")||(pid==" __STR ")||(next_pid==" __STR ")"
457*58e6ee5fSAndroid Build Coastguard Worker
458*58e6ee5fSAndroid Build Coastguard Worker #undef __STR
459*58e6ee5fSAndroid Build Coastguard Worker #define __STR ""
460*58e6ee5fSAndroid Build Coastguard Worker
461*58e6ee5fSAndroid Build Coastguard Worker /* strlen(".*:") > strlen("||") */
462*58e6ee5fSAndroid Build Coastguard Worker len = strlen(".*:" FILTER_FMT) + strlen(pid) * 3 + 1;
463*58e6ee5fSAndroid Build Coastguard Worker
464*58e6ee5fSAndroid Build Coastguard Worker #undef __STR
465*58e6ee5fSAndroid Build Coastguard Worker #define __STR "%s"
466*58e6ee5fSAndroid Build Coastguard Worker
467*58e6ee5fSAndroid Build Coastguard Worker if (!curr_filter) {
468*58e6ee5fSAndroid Build Coastguard Worker filter = malloc(len);
469*58e6ee5fSAndroid Build Coastguard Worker if (!filter)
470*58e6ee5fSAndroid Build Coastguard Worker die("Failed to allocate for filter %s", curr_filter);
471*58e6ee5fSAndroid Build Coastguard Worker sprintf(filter, ".*:" FILTER_FMT, pid, pid, pid);
472*58e6ee5fSAndroid Build Coastguard Worker } else {
473*58e6ee5fSAndroid Build Coastguard Worker curr_len = strlen(curr_filter);
474*58e6ee5fSAndroid Build Coastguard Worker len += curr_len;
475*58e6ee5fSAndroid Build Coastguard Worker
476*58e6ee5fSAndroid Build Coastguard Worker filter = realloc(curr_filter, len);
477*58e6ee5fSAndroid Build Coastguard Worker if (!filter)
478*58e6ee5fSAndroid Build Coastguard Worker die("realloc");
479*58e6ee5fSAndroid Build Coastguard Worker sprintf(filter + curr_len, "||" FILTER_FMT, pid, pid, pid);
480*58e6ee5fSAndroid Build Coastguard Worker }
481*58e6ee5fSAndroid Build Coastguard Worker
482*58e6ee5fSAndroid Build Coastguard Worker return filter;
483*58e6ee5fSAndroid Build Coastguard Worker }
484*58e6ee5fSAndroid Build Coastguard Worker
convert_comm_filter(struct tracecmd_input * handle)485*58e6ee5fSAndroid Build Coastguard Worker static void convert_comm_filter(struct tracecmd_input *handle)
486*58e6ee5fSAndroid Build Coastguard Worker {
487*58e6ee5fSAndroid Build Coastguard Worker struct tep_cmdline *cmdline;
488*58e6ee5fSAndroid Build Coastguard Worker struct tep_handle *pevent;
489*58e6ee5fSAndroid Build Coastguard Worker struct pid_list *list;
490*58e6ee5fSAndroid Build Coastguard Worker
491*58e6ee5fSAndroid Build Coastguard Worker char pidstr[100];
492*58e6ee5fSAndroid Build Coastguard Worker
493*58e6ee5fSAndroid Build Coastguard Worker if (!comm_list)
494*58e6ee5fSAndroid Build Coastguard Worker return;
495*58e6ee5fSAndroid Build Coastguard Worker
496*58e6ee5fSAndroid Build Coastguard Worker pevent = tracecmd_get_tep(handle);
497*58e6ee5fSAndroid Build Coastguard Worker
498*58e6ee5fSAndroid Build Coastguard Worker /* Seach for comm names and get their pids */
499*58e6ee5fSAndroid Build Coastguard Worker for (list = comm_list; list; list = list->next) {
500*58e6ee5fSAndroid Build Coastguard Worker cmdline = tep_data_pid_from_comm(pevent, list->pid, NULL);
501*58e6ee5fSAndroid Build Coastguard Worker if (!cmdline) {
502*58e6ee5fSAndroid Build Coastguard Worker warning("comm: %s not in cmdline list", list->pid);
503*58e6ee5fSAndroid Build Coastguard Worker continue;
504*58e6ee5fSAndroid Build Coastguard Worker }
505*58e6ee5fSAndroid Build Coastguard Worker do {
506*58e6ee5fSAndroid Build Coastguard Worker sprintf(pidstr, "%d", tep_cmdline_pid(pevent, cmdline));
507*58e6ee5fSAndroid Build Coastguard Worker add_pid_filter(pidstr);
508*58e6ee5fSAndroid Build Coastguard Worker cmdline = tep_data_pid_from_comm(pevent, list->pid,
509*58e6ee5fSAndroid Build Coastguard Worker cmdline);
510*58e6ee5fSAndroid Build Coastguard Worker } while (cmdline);
511*58e6ee5fSAndroid Build Coastguard Worker }
512*58e6ee5fSAndroid Build Coastguard Worker
513*58e6ee5fSAndroid Build Coastguard Worker while (comm_list) {
514*58e6ee5fSAndroid Build Coastguard Worker list = comm_list;
515*58e6ee5fSAndroid Build Coastguard Worker comm_list = comm_list->next;
516*58e6ee5fSAndroid Build Coastguard Worker if (list->free)
517*58e6ee5fSAndroid Build Coastguard Worker free(list->pid);
518*58e6ee5fSAndroid Build Coastguard Worker free(list);
519*58e6ee5fSAndroid Build Coastguard Worker }
520*58e6ee5fSAndroid Build Coastguard Worker }
521*58e6ee5fSAndroid Build Coastguard Worker
make_pid_filter(struct tracecmd_input * handle)522*58e6ee5fSAndroid Build Coastguard Worker static void make_pid_filter(struct tracecmd_input *handle)
523*58e6ee5fSAndroid Build Coastguard Worker {
524*58e6ee5fSAndroid Build Coastguard Worker struct pid_list *list;
525*58e6ee5fSAndroid Build Coastguard Worker char *str = NULL;
526*58e6ee5fSAndroid Build Coastguard Worker
527*58e6ee5fSAndroid Build Coastguard Worker convert_comm_filter(handle);
528*58e6ee5fSAndroid Build Coastguard Worker
529*58e6ee5fSAndroid Build Coastguard Worker if (!pid_list)
530*58e6ee5fSAndroid Build Coastguard Worker return;
531*58e6ee5fSAndroid Build Coastguard Worker
532*58e6ee5fSAndroid Build Coastguard Worker /* First do all common pids */
533*58e6ee5fSAndroid Build Coastguard Worker for (list = pid_list; list; list = list->next) {
534*58e6ee5fSAndroid Build Coastguard Worker str = append_pid_filter(str, list->pid);
535*58e6ee5fSAndroid Build Coastguard Worker }
536*58e6ee5fSAndroid Build Coastguard Worker
537*58e6ee5fSAndroid Build Coastguard Worker add_filter(str, 0);
538*58e6ee5fSAndroid Build Coastguard Worker free(str);
539*58e6ee5fSAndroid Build Coastguard Worker
540*58e6ee5fSAndroid Build Coastguard Worker while (pid_list) {
541*58e6ee5fSAndroid Build Coastguard Worker list = pid_list;
542*58e6ee5fSAndroid Build Coastguard Worker pid_list = pid_list->next;
543*58e6ee5fSAndroid Build Coastguard Worker if (list->free)
544*58e6ee5fSAndroid Build Coastguard Worker free(list->pid);
545*58e6ee5fSAndroid Build Coastguard Worker free(list);
546*58e6ee5fSAndroid Build Coastguard Worker }
547*58e6ee5fSAndroid Build Coastguard Worker }
548*58e6ee5fSAndroid Build Coastguard Worker
process_filters(struct handle_list * handles)549*58e6ee5fSAndroid Build Coastguard Worker static void process_filters(struct handle_list *handles)
550*58e6ee5fSAndroid Build Coastguard Worker {
551*58e6ee5fSAndroid Build Coastguard Worker struct filter **filter_next = &handles->event_filters;
552*58e6ee5fSAndroid Build Coastguard Worker struct filter **filter_out_next = &handles->event_filter_out;
553*58e6ee5fSAndroid Build Coastguard Worker struct filter *event_filter;
554*58e6ee5fSAndroid Build Coastguard Worker struct filter_str *filter;
555*58e6ee5fSAndroid Build Coastguard Worker struct tep_handle *pevent;
556*58e6ee5fSAndroid Build Coastguard Worker char errstr[200];
557*58e6ee5fSAndroid Build Coastguard Worker int filters = 0;
558*58e6ee5fSAndroid Build Coastguard Worker int ret;
559*58e6ee5fSAndroid Build Coastguard Worker
560*58e6ee5fSAndroid Build Coastguard Worker pevent = tracecmd_get_tep(handles->handle);
561*58e6ee5fSAndroid Build Coastguard Worker
562*58e6ee5fSAndroid Build Coastguard Worker make_pid_filter(handles->handle);
563*58e6ee5fSAndroid Build Coastguard Worker
564*58e6ee5fSAndroid Build Coastguard Worker while (filter_strings) {
565*58e6ee5fSAndroid Build Coastguard Worker filter = filter_strings;
566*58e6ee5fSAndroid Build Coastguard Worker filter_strings = filter->next;
567*58e6ee5fSAndroid Build Coastguard Worker
568*58e6ee5fSAndroid Build Coastguard Worker event_filter = malloc(sizeof(*event_filter));
569*58e6ee5fSAndroid Build Coastguard Worker if (!event_filter)
570*58e6ee5fSAndroid Build Coastguard Worker die("Failed to allocate for event filter");
571*58e6ee5fSAndroid Build Coastguard Worker event_filter->next = NULL;
572*58e6ee5fSAndroid Build Coastguard Worker event_filter->filter = tep_filter_alloc(pevent);
573*58e6ee5fSAndroid Build Coastguard Worker if (!event_filter->filter)
574*58e6ee5fSAndroid Build Coastguard Worker die("malloc");
575*58e6ee5fSAndroid Build Coastguard Worker
576*58e6ee5fSAndroid Build Coastguard Worker ret = tep_filter_add_filter_str(event_filter->filter,
577*58e6ee5fSAndroid Build Coastguard Worker filter->filter);
578*58e6ee5fSAndroid Build Coastguard Worker if (ret < 0) {
579*58e6ee5fSAndroid Build Coastguard Worker tep_strerror(pevent, ret, errstr, sizeof(errstr));
580*58e6ee5fSAndroid Build Coastguard Worker die("Error filtering: %s\n%s",
581*58e6ee5fSAndroid Build Coastguard Worker filter->filter, errstr);
582*58e6ee5fSAndroid Build Coastguard Worker }
583*58e6ee5fSAndroid Build Coastguard Worker
584*58e6ee5fSAndroid Build Coastguard Worker if (filter->neg) {
585*58e6ee5fSAndroid Build Coastguard Worker *filter_out_next = event_filter;
586*58e6ee5fSAndroid Build Coastguard Worker filter_out_next = &event_filter->next;
587*58e6ee5fSAndroid Build Coastguard Worker } else {
588*58e6ee5fSAndroid Build Coastguard Worker *filter_next = event_filter;
589*58e6ee5fSAndroid Build Coastguard Worker filter_next = &event_filter->next;
590*58e6ee5fSAndroid Build Coastguard Worker }
591*58e6ee5fSAndroid Build Coastguard Worker filters++;
592*58e6ee5fSAndroid Build Coastguard Worker free(filter->filter);
593*58e6ee5fSAndroid Build Coastguard Worker free(filter);
594*58e6ee5fSAndroid Build Coastguard Worker }
595*58e6ee5fSAndroid Build Coastguard Worker if (filters && test_filters_mode)
596*58e6ee5fSAndroid Build Coastguard Worker exit(0);
597*58e6ee5fSAndroid Build Coastguard Worker }
598*58e6ee5fSAndroid Build Coastguard Worker
init_wakeup(struct tracecmd_input * handle)599*58e6ee5fSAndroid Build Coastguard Worker static void init_wakeup(struct tracecmd_input *handle)
600*58e6ee5fSAndroid Build Coastguard Worker {
601*58e6ee5fSAndroid Build Coastguard Worker struct tep_handle *pevent;
602*58e6ee5fSAndroid Build Coastguard Worker struct tep_event *event;
603*58e6ee5fSAndroid Build Coastguard Worker
604*58e6ee5fSAndroid Build Coastguard Worker if (!show_wakeup)
605*58e6ee5fSAndroid Build Coastguard Worker return;
606*58e6ee5fSAndroid Build Coastguard Worker
607*58e6ee5fSAndroid Build Coastguard Worker pevent = tracecmd_get_tep(handle);
608*58e6ee5fSAndroid Build Coastguard Worker
609*58e6ee5fSAndroid Build Coastguard Worker trace_hash_init(&wakeup_hash, WAKEUP_HASH_SIZE);
610*58e6ee5fSAndroid Build Coastguard Worker
611*58e6ee5fSAndroid Build Coastguard Worker event = tep_find_event_by_name(pevent, "sched", "sched_wakeup");
612*58e6ee5fSAndroid Build Coastguard Worker if (!event)
613*58e6ee5fSAndroid Build Coastguard Worker goto fail;
614*58e6ee5fSAndroid Build Coastguard Worker wakeup_id = event->id;
615*58e6ee5fSAndroid Build Coastguard Worker wakeup_task = tep_find_field(event, "pid");
616*58e6ee5fSAndroid Build Coastguard Worker if (!wakeup_task)
617*58e6ee5fSAndroid Build Coastguard Worker goto fail;
618*58e6ee5fSAndroid Build Coastguard Worker wakeup_success = tep_find_field(event, "success");
619*58e6ee5fSAndroid Build Coastguard Worker
620*58e6ee5fSAndroid Build Coastguard Worker event = tep_find_event_by_name(pevent, "sched", "sched_switch");
621*58e6ee5fSAndroid Build Coastguard Worker if (!event)
622*58e6ee5fSAndroid Build Coastguard Worker goto fail;
623*58e6ee5fSAndroid Build Coastguard Worker sched_id = event->id;
624*58e6ee5fSAndroid Build Coastguard Worker sched_task = tep_find_field(event, "next_pid");
625*58e6ee5fSAndroid Build Coastguard Worker if (!sched_task)
626*58e6ee5fSAndroid Build Coastguard Worker goto fail;
627*58e6ee5fSAndroid Build Coastguard Worker
628*58e6ee5fSAndroid Build Coastguard Worker sched_prio = tep_find_field(event, "next_prio");
629*58e6ee5fSAndroid Build Coastguard Worker if (!sched_prio)
630*58e6ee5fSAndroid Build Coastguard Worker goto fail;
631*58e6ee5fSAndroid Build Coastguard Worker
632*58e6ee5fSAndroid Build Coastguard Worker
633*58e6ee5fSAndroid Build Coastguard Worker wakeup_new_id = -1;
634*58e6ee5fSAndroid Build Coastguard Worker
635*58e6ee5fSAndroid Build Coastguard Worker event = tep_find_event_by_name(pevent, "sched", "sched_wakeup_new");
636*58e6ee5fSAndroid Build Coastguard Worker if (!event)
637*58e6ee5fSAndroid Build Coastguard Worker goto skip;
638*58e6ee5fSAndroid Build Coastguard Worker wakeup_new_id = event->id;
639*58e6ee5fSAndroid Build Coastguard Worker wakeup_new_task = tep_find_field(event, "pid");
640*58e6ee5fSAndroid Build Coastguard Worker if (!wakeup_new_task)
641*58e6ee5fSAndroid Build Coastguard Worker goto fail;
642*58e6ee5fSAndroid Build Coastguard Worker wakeup_new_success = tep_find_field(event, "success");
643*58e6ee5fSAndroid Build Coastguard Worker
644*58e6ee5fSAndroid Build Coastguard Worker skip:
645*58e6ee5fSAndroid Build Coastguard Worker return;
646*58e6ee5fSAndroid Build Coastguard Worker
647*58e6ee5fSAndroid Build Coastguard Worker fail:
648*58e6ee5fSAndroid Build Coastguard Worker show_wakeup = 0;
649*58e6ee5fSAndroid Build Coastguard Worker }
650*58e6ee5fSAndroid Build Coastguard Worker
add_wakeup(unsigned int val,unsigned long long start)651*58e6ee5fSAndroid Build Coastguard Worker static void add_wakeup(unsigned int val, unsigned long long start)
652*58e6ee5fSAndroid Build Coastguard Worker {
653*58e6ee5fSAndroid Build Coastguard Worker unsigned int key = trace_hash(val);
654*58e6ee5fSAndroid Build Coastguard Worker struct wakeup_info *info;
655*58e6ee5fSAndroid Build Coastguard Worker struct trace_hash_item *item;
656*58e6ee5fSAndroid Build Coastguard Worker
657*58e6ee5fSAndroid Build Coastguard Worker item = trace_hash_find(&wakeup_hash, key, NULL, NULL);
658*58e6ee5fSAndroid Build Coastguard Worker if (item) {
659*58e6ee5fSAndroid Build Coastguard Worker info = container_of(item, struct wakeup_info, hash);
660*58e6ee5fSAndroid Build Coastguard Worker /* Hmm, double wakeup? */
661*58e6ee5fSAndroid Build Coastguard Worker info->start = start;
662*58e6ee5fSAndroid Build Coastguard Worker return;
663*58e6ee5fSAndroid Build Coastguard Worker }
664*58e6ee5fSAndroid Build Coastguard Worker
665*58e6ee5fSAndroid Build Coastguard Worker info = malloc(sizeof(*info));
666*58e6ee5fSAndroid Build Coastguard Worker if (!info)
667*58e6ee5fSAndroid Build Coastguard Worker die("Failed to allocate wakeup info");
668*58e6ee5fSAndroid Build Coastguard Worker info->hash.key = key;
669*58e6ee5fSAndroid Build Coastguard Worker info->start = start;
670*58e6ee5fSAndroid Build Coastguard Worker trace_hash_add(&wakeup_hash, &info->hash);
671*58e6ee5fSAndroid Build Coastguard Worker }
672*58e6ee5fSAndroid Build Coastguard Worker
673*58e6ee5fSAndroid Build Coastguard Worker static unsigned long long max_lat = 0;
674*58e6ee5fSAndroid Build Coastguard Worker static unsigned long long max_time;
675*58e6ee5fSAndroid Build Coastguard Worker static unsigned long long min_lat = -1;
676*58e6ee5fSAndroid Build Coastguard Worker static unsigned long long min_time;
677*58e6ee5fSAndroid Build Coastguard Worker
678*58e6ee5fSAndroid Build Coastguard Worker static unsigned long long max_rt_lat = 0;
679*58e6ee5fSAndroid Build Coastguard Worker static unsigned long long max_rt_time;
680*58e6ee5fSAndroid Build Coastguard Worker static unsigned long long min_rt_lat = -1;
681*58e6ee5fSAndroid Build Coastguard Worker static unsigned long long min_rt_time;
682*58e6ee5fSAndroid Build Coastguard Worker
add_sched(unsigned int val,unsigned long long end,int rt)683*58e6ee5fSAndroid Build Coastguard Worker static void add_sched(unsigned int val, unsigned long long end, int rt)
684*58e6ee5fSAndroid Build Coastguard Worker {
685*58e6ee5fSAndroid Build Coastguard Worker struct trace_hash_item *item;
686*58e6ee5fSAndroid Build Coastguard Worker unsigned int key = trace_hash(val);
687*58e6ee5fSAndroid Build Coastguard Worker struct wakeup_info *info;
688*58e6ee5fSAndroid Build Coastguard Worker unsigned long long cal;
689*58e6ee5fSAndroid Build Coastguard Worker
690*58e6ee5fSAndroid Build Coastguard Worker item = trace_hash_find(&wakeup_hash, key, NULL, NULL);
691*58e6ee5fSAndroid Build Coastguard Worker if (!item)
692*58e6ee5fSAndroid Build Coastguard Worker return;
693*58e6ee5fSAndroid Build Coastguard Worker
694*58e6ee5fSAndroid Build Coastguard Worker info = container_of(item, struct wakeup_info, hash);
695*58e6ee5fSAndroid Build Coastguard Worker
696*58e6ee5fSAndroid Build Coastguard Worker cal = end - info->start;
697*58e6ee5fSAndroid Build Coastguard Worker
698*58e6ee5fSAndroid Build Coastguard Worker if (cal > max_lat) {
699*58e6ee5fSAndroid Build Coastguard Worker max_lat = cal;
700*58e6ee5fSAndroid Build Coastguard Worker max_time = end;
701*58e6ee5fSAndroid Build Coastguard Worker }
702*58e6ee5fSAndroid Build Coastguard Worker if (cal < min_lat) {
703*58e6ee5fSAndroid Build Coastguard Worker min_lat = cal;
704*58e6ee5fSAndroid Build Coastguard Worker min_time = end;
705*58e6ee5fSAndroid Build Coastguard Worker }
706*58e6ee5fSAndroid Build Coastguard Worker
707*58e6ee5fSAndroid Build Coastguard Worker if (rt) {
708*58e6ee5fSAndroid Build Coastguard Worker if (cal > max_rt_lat) {
709*58e6ee5fSAndroid Build Coastguard Worker max_rt_lat = cal;
710*58e6ee5fSAndroid Build Coastguard Worker max_rt_time = end;
711*58e6ee5fSAndroid Build Coastguard Worker }
712*58e6ee5fSAndroid Build Coastguard Worker if (cal < min_rt_lat) {
713*58e6ee5fSAndroid Build Coastguard Worker min_rt_lat = cal;
714*58e6ee5fSAndroid Build Coastguard Worker min_rt_time = end;
715*58e6ee5fSAndroid Build Coastguard Worker }
716*58e6ee5fSAndroid Build Coastguard Worker }
717*58e6ee5fSAndroid Build Coastguard Worker
718*58e6ee5fSAndroid Build Coastguard Worker printf(" Latency: %llu.%03llu usecs", cal / 1000, cal % 1000);
719*58e6ee5fSAndroid Build Coastguard Worker
720*58e6ee5fSAndroid Build Coastguard Worker total_wakeup_lat += cal;
721*58e6ee5fSAndroid Build Coastguard Worker wakeup_lat_count++;
722*58e6ee5fSAndroid Build Coastguard Worker
723*58e6ee5fSAndroid Build Coastguard Worker if (rt) {
724*58e6ee5fSAndroid Build Coastguard Worker total_wakeup_rt_lat += cal;
725*58e6ee5fSAndroid Build Coastguard Worker wakeup_rt_lat_count++;
726*58e6ee5fSAndroid Build Coastguard Worker }
727*58e6ee5fSAndroid Build Coastguard Worker
728*58e6ee5fSAndroid Build Coastguard Worker trace_hash_del(item);
729*58e6ee5fSAndroid Build Coastguard Worker free(info);
730*58e6ee5fSAndroid Build Coastguard Worker }
731*58e6ee5fSAndroid Build Coastguard Worker
process_wakeup(struct tep_handle * pevent,struct tep_record * record)732*58e6ee5fSAndroid Build Coastguard Worker static void process_wakeup(struct tep_handle *pevent, struct tep_record *record)
733*58e6ee5fSAndroid Build Coastguard Worker {
734*58e6ee5fSAndroid Build Coastguard Worker unsigned long long val;
735*58e6ee5fSAndroid Build Coastguard Worker int id;
736*58e6ee5fSAndroid Build Coastguard Worker
737*58e6ee5fSAndroid Build Coastguard Worker if (!show_wakeup)
738*58e6ee5fSAndroid Build Coastguard Worker return;
739*58e6ee5fSAndroid Build Coastguard Worker
740*58e6ee5fSAndroid Build Coastguard Worker id = tep_data_type(pevent, record);
741*58e6ee5fSAndroid Build Coastguard Worker if (id == wakeup_id) {
742*58e6ee5fSAndroid Build Coastguard Worker if (tep_read_number_field(wakeup_success, record->data, &val) == 0) {
743*58e6ee5fSAndroid Build Coastguard Worker if (!val)
744*58e6ee5fSAndroid Build Coastguard Worker return;
745*58e6ee5fSAndroid Build Coastguard Worker }
746*58e6ee5fSAndroid Build Coastguard Worker if (tep_read_number_field(wakeup_task, record->data, &val))
747*58e6ee5fSAndroid Build Coastguard Worker return;
748*58e6ee5fSAndroid Build Coastguard Worker add_wakeup(val, record->ts);
749*58e6ee5fSAndroid Build Coastguard Worker } else if (id == wakeup_new_id) {
750*58e6ee5fSAndroid Build Coastguard Worker if (tep_read_number_field(wakeup_new_success, record->data, &val) == 0) {
751*58e6ee5fSAndroid Build Coastguard Worker if (!val)
752*58e6ee5fSAndroid Build Coastguard Worker return;
753*58e6ee5fSAndroid Build Coastguard Worker }
754*58e6ee5fSAndroid Build Coastguard Worker if (tep_read_number_field(wakeup_new_task, record->data, &val))
755*58e6ee5fSAndroid Build Coastguard Worker return;
756*58e6ee5fSAndroid Build Coastguard Worker add_wakeup(val, record->ts);
757*58e6ee5fSAndroid Build Coastguard Worker } else if (id == sched_id) {
758*58e6ee5fSAndroid Build Coastguard Worker int rt = 1;
759*58e6ee5fSAndroid Build Coastguard Worker if (tep_read_number_field(sched_prio, record->data, &val))
760*58e6ee5fSAndroid Build Coastguard Worker return;
761*58e6ee5fSAndroid Build Coastguard Worker if (val > 99)
762*58e6ee5fSAndroid Build Coastguard Worker rt = 0;
763*58e6ee5fSAndroid Build Coastguard Worker if (tep_read_number_field(sched_task, record->data, &val))
764*58e6ee5fSAndroid Build Coastguard Worker return;
765*58e6ee5fSAndroid Build Coastguard Worker add_sched(val, record->ts, rt);
766*58e6ee5fSAndroid Build Coastguard Worker }
767*58e6ee5fSAndroid Build Coastguard Worker }
768*58e6ee5fSAndroid Build Coastguard Worker
769*58e6ee5fSAndroid Build Coastguard Worker static void
show_wakeup_timings(unsigned long long total,unsigned long count,unsigned long long lat_max,unsigned long long time_max,unsigned long long lat_min,unsigned long long time_min)770*58e6ee5fSAndroid Build Coastguard Worker show_wakeup_timings(unsigned long long total, unsigned long count,
771*58e6ee5fSAndroid Build Coastguard Worker unsigned long long lat_max, unsigned long long time_max,
772*58e6ee5fSAndroid Build Coastguard Worker unsigned long long lat_min, unsigned long long time_min)
773*58e6ee5fSAndroid Build Coastguard Worker {
774*58e6ee5fSAndroid Build Coastguard Worker
775*58e6ee5fSAndroid Build Coastguard Worker total /= count;
776*58e6ee5fSAndroid Build Coastguard Worker
777*58e6ee5fSAndroid Build Coastguard Worker printf("\nAverage wakeup latency: %llu.%03llu usecs\n",
778*58e6ee5fSAndroid Build Coastguard Worker total / 1000,
779*58e6ee5fSAndroid Build Coastguard Worker total % 1000);
780*58e6ee5fSAndroid Build Coastguard Worker printf("Maximum Latency: %llu.%03llu usecs at ", lat_max / 1000, lat_max % 1000);
781*58e6ee5fSAndroid Build Coastguard Worker printf("timestamp: %llu.%06llu\n",
782*58e6ee5fSAndroid Build Coastguard Worker time_max / 1000000000, ((time_max + 500) % 1000000000) / 1000);
783*58e6ee5fSAndroid Build Coastguard Worker printf("Minimum Latency: %llu.%03llu usecs at ", lat_min / 1000, lat_min % 1000);
784*58e6ee5fSAndroid Build Coastguard Worker printf("timestamp: %llu.%06llu\n\n", time_min / 1000000000,
785*58e6ee5fSAndroid Build Coastguard Worker ((time_min + 500) % 1000000000) / 1000);
786*58e6ee5fSAndroid Build Coastguard Worker }
787*58e6ee5fSAndroid Build Coastguard Worker
finish_wakeup(void)788*58e6ee5fSAndroid Build Coastguard Worker static void finish_wakeup(void)
789*58e6ee5fSAndroid Build Coastguard Worker {
790*58e6ee5fSAndroid Build Coastguard Worker struct wakeup_info *info;
791*58e6ee5fSAndroid Build Coastguard Worker struct trace_hash_item **bucket;
792*58e6ee5fSAndroid Build Coastguard Worker struct trace_hash_item *item;
793*58e6ee5fSAndroid Build Coastguard Worker
794*58e6ee5fSAndroid Build Coastguard Worker if (!show_wakeup || !wakeup_lat_count)
795*58e6ee5fSAndroid Build Coastguard Worker return;
796*58e6ee5fSAndroid Build Coastguard Worker
797*58e6ee5fSAndroid Build Coastguard Worker show_wakeup_timings(total_wakeup_lat, wakeup_lat_count,
798*58e6ee5fSAndroid Build Coastguard Worker max_lat, max_time,
799*58e6ee5fSAndroid Build Coastguard Worker min_lat, min_time);
800*58e6ee5fSAndroid Build Coastguard Worker
801*58e6ee5fSAndroid Build Coastguard Worker
802*58e6ee5fSAndroid Build Coastguard Worker if (wakeup_rt_lat_count) {
803*58e6ee5fSAndroid Build Coastguard Worker printf("RT task timings:\n");
804*58e6ee5fSAndroid Build Coastguard Worker show_wakeup_timings(total_wakeup_rt_lat, wakeup_rt_lat_count,
805*58e6ee5fSAndroid Build Coastguard Worker max_rt_lat, max_rt_time,
806*58e6ee5fSAndroid Build Coastguard Worker min_rt_lat, min_rt_time);
807*58e6ee5fSAndroid Build Coastguard Worker }
808*58e6ee5fSAndroid Build Coastguard Worker
809*58e6ee5fSAndroid Build Coastguard Worker trace_hash_for_each_bucket(bucket, &wakeup_hash) {
810*58e6ee5fSAndroid Build Coastguard Worker trace_hash_while_item(item, bucket) {
811*58e6ee5fSAndroid Build Coastguard Worker trace_hash_del(item);
812*58e6ee5fSAndroid Build Coastguard Worker info = container_of(item, struct wakeup_info, hash);
813*58e6ee5fSAndroid Build Coastguard Worker free(info);
814*58e6ee5fSAndroid Build Coastguard Worker }
815*58e6ee5fSAndroid Build Coastguard Worker }
816*58e6ee5fSAndroid Build Coastguard Worker
817*58e6ee5fSAndroid Build Coastguard Worker trace_hash_free(&wakeup_hash);
818*58e6ee5fSAndroid Build Coastguard Worker }
819*58e6ee5fSAndroid Build Coastguard Worker
trace_show_data(struct tracecmd_input * handle,struct tep_record * record)820*58e6ee5fSAndroid Build Coastguard Worker void trace_show_data(struct tracecmd_input *handle, struct tep_record *record)
821*58e6ee5fSAndroid Build Coastguard Worker {
822*58e6ee5fSAndroid Build Coastguard Worker tracecmd_show_data_func func = tracecmd_get_show_data_func(handle);
823*58e6ee5fSAndroid Build Coastguard Worker const char *tfmt = time_format(handle, TIME_FMT_NORMAL);
824*58e6ee5fSAndroid Build Coastguard Worker const char *cfmt = latency_format ? "%8.8s-%-5d %3d" : "%16s-%-5d [%03d]";
825*58e6ee5fSAndroid Build Coastguard Worker struct tep_handle *pevent;
826*58e6ee5fSAndroid Build Coastguard Worker struct tep_event *event;
827*58e6ee5fSAndroid Build Coastguard Worker struct trace_seq s;
828*58e6ee5fSAndroid Build Coastguard Worker int cpu = record->cpu;
829*58e6ee5fSAndroid Build Coastguard Worker bool use_trace_clock;
830*58e6ee5fSAndroid Build Coastguard Worker static unsigned long long last_ts;
831*58e6ee5fSAndroid Build Coastguard Worker unsigned long long diff_ts;
832*58e6ee5fSAndroid Build Coastguard Worker unsigned long page_size;
833*58e6ee5fSAndroid Build Coastguard Worker char buf[50];
834*58e6ee5fSAndroid Build Coastguard Worker
835*58e6ee5fSAndroid Build Coastguard Worker page_size = tracecmd_page_size(handle);
836*58e6ee5fSAndroid Build Coastguard Worker
837*58e6ee5fSAndroid Build Coastguard Worker test_save(record, cpu);
838*58e6ee5fSAndroid Build Coastguard Worker
839*58e6ee5fSAndroid Build Coastguard Worker if (func) {
840*58e6ee5fSAndroid Build Coastguard Worker func(handle, record);
841*58e6ee5fSAndroid Build Coastguard Worker return;
842*58e6ee5fSAndroid Build Coastguard Worker }
843*58e6ee5fSAndroid Build Coastguard Worker
844*58e6ee5fSAndroid Build Coastguard Worker pevent = tracecmd_get_tep(handle);
845*58e6ee5fSAndroid Build Coastguard Worker event = tep_find_event_by_record(pevent, record);
846*58e6ee5fSAndroid Build Coastguard Worker use_trace_clock = tracecmd_get_use_trace_clock(handle);
847*58e6ee5fSAndroid Build Coastguard Worker
848*58e6ee5fSAndroid Build Coastguard Worker trace_seq_init(&s);
849*58e6ee5fSAndroid Build Coastguard Worker if (record->missed_events > 0)
850*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(&s, "CPU:%d [%lld EVENTS DROPPED]\n",
851*58e6ee5fSAndroid Build Coastguard Worker cpu, record->missed_events);
852*58e6ee5fSAndroid Build Coastguard Worker else if (record->missed_events < 0)
853*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(&s, "CPU:%d [EVENTS DROPPED]\n", cpu);
854*58e6ee5fSAndroid Build Coastguard Worker if (buffer_breaks || tracecmd_get_debug()) {
855*58e6ee5fSAndroid Build Coastguard Worker if (tracecmd_record_at_buffer_start(handle, record)) {
856*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(&s, "CPU:%d [SUBBUFFER START]", cpu);
857*58e6ee5fSAndroid Build Coastguard Worker if (tracecmd_get_debug())
858*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(&s, " [%lld:0x%llx]",
859*58e6ee5fSAndroid Build Coastguard Worker tracecmd_page_ts(handle, record),
860*58e6ee5fSAndroid Build Coastguard Worker record->offset & ~(page_size - 1));
861*58e6ee5fSAndroid Build Coastguard Worker trace_seq_putc(&s, '\n');
862*58e6ee5fSAndroid Build Coastguard Worker }
863*58e6ee5fSAndroid Build Coastguard Worker }
864*58e6ee5fSAndroid Build Coastguard Worker
865*58e6ee5fSAndroid Build Coastguard Worker tep_print_event(pevent, &s, record, cfmt,
866*58e6ee5fSAndroid Build Coastguard Worker TEP_PRINT_COMM,
867*58e6ee5fSAndroid Build Coastguard Worker TEP_PRINT_PID,
868*58e6ee5fSAndroid Build Coastguard Worker TEP_PRINT_CPU);
869*58e6ee5fSAndroid Build Coastguard Worker
870*58e6ee5fSAndroid Build Coastguard Worker if (latency_format) {
871*58e6ee5fSAndroid Build Coastguard Worker if (raw_format)
872*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(&s, "-0x%x",
873*58e6ee5fSAndroid Build Coastguard Worker tep_data_flags(pevent, record));
874*58e6ee5fSAndroid Build Coastguard Worker else
875*58e6ee5fSAndroid Build Coastguard Worker tep_print_event(pevent, &s, record, "%s",
876*58e6ee5fSAndroid Build Coastguard Worker TEP_PRINT_LATENCY);
877*58e6ee5fSAndroid Build Coastguard Worker }
878*58e6ee5fSAndroid Build Coastguard Worker
879*58e6ee5fSAndroid Build Coastguard Worker tep_print_event(pevent, &s, record, tfmt, TEP_PRINT_TIME);
880*58e6ee5fSAndroid Build Coastguard Worker
881*58e6ee5fSAndroid Build Coastguard Worker if (tsdiff) {
882*58e6ee5fSAndroid Build Coastguard Worker unsigned long long rec_ts = record->ts;
883*58e6ee5fSAndroid Build Coastguard Worker
884*58e6ee5fSAndroid Build Coastguard Worker buf[0] = 0;
885*58e6ee5fSAndroid Build Coastguard Worker if (use_trace_clock && !tep_test_flag(pevent, TEP_NSEC_OUTPUT))
886*58e6ee5fSAndroid Build Coastguard Worker rec_ts = (rec_ts + 500) / 1000;
887*58e6ee5fSAndroid Build Coastguard Worker if (last_ts) {
888*58e6ee5fSAndroid Build Coastguard Worker diff_ts = rec_ts - last_ts;
889*58e6ee5fSAndroid Build Coastguard Worker snprintf(buf, 50, "(+%lld)", diff_ts);
890*58e6ee5fSAndroid Build Coastguard Worker buf[49] = 0;
891*58e6ee5fSAndroid Build Coastguard Worker }
892*58e6ee5fSAndroid Build Coastguard Worker last_ts = rec_ts;
893*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(&s, " %-8s", buf);
894*58e6ee5fSAndroid Build Coastguard Worker }
895*58e6ee5fSAndroid Build Coastguard Worker
896*58e6ee5fSAndroid Build Coastguard Worker print_event_name(&s, event);
897*58e6ee5fSAndroid Build Coastguard Worker tep_print_event(pevent, &s, record, "%s", format_type);
898*58e6ee5fSAndroid Build Coastguard Worker
899*58e6ee5fSAndroid Build Coastguard Worker if (s.len && *(s.buffer + s.len - 1) == '\n')
900*58e6ee5fSAndroid Build Coastguard Worker s.len--;
901*58e6ee5fSAndroid Build Coastguard Worker if (tracecmd_get_debug()) {
902*58e6ee5fSAndroid Build Coastguard Worker struct kbuffer *kbuf;
903*58e6ee5fSAndroid Build Coastguard Worker struct kbuffer_raw_info info;
904*58e6ee5fSAndroid Build Coastguard Worker void *page;
905*58e6ee5fSAndroid Build Coastguard Worker void *offset;
906*58e6ee5fSAndroid Build Coastguard Worker
907*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(&s, " [%d:0x%llx:%d]",
908*58e6ee5fSAndroid Build Coastguard Worker tracecmd_record_ts_delta(handle, record),
909*58e6ee5fSAndroid Build Coastguard Worker record->offset & (page_size - 1), record->size);
910*58e6ee5fSAndroid Build Coastguard Worker kbuf = tracecmd_record_kbuf(handle, record);
911*58e6ee5fSAndroid Build Coastguard Worker page = tracecmd_record_page(handle, record);
912*58e6ee5fSAndroid Build Coastguard Worker offset = tracecmd_record_offset(handle, record);
913*58e6ee5fSAndroid Build Coastguard Worker
914*58e6ee5fSAndroid Build Coastguard Worker if (kbuf && page && offset) {
915*58e6ee5fSAndroid Build Coastguard Worker struct kbuffer_raw_info *pi = &info;
916*58e6ee5fSAndroid Build Coastguard Worker
917*58e6ee5fSAndroid Build Coastguard Worker /* We need to get the record raw data to get next */
918*58e6ee5fSAndroid Build Coastguard Worker pi->next = offset;
919*58e6ee5fSAndroid Build Coastguard Worker pi = kbuffer_raw_get(kbuf, page, pi);
920*58e6ee5fSAndroid Build Coastguard Worker while ((pi = kbuffer_raw_get(kbuf, page, pi))) {
921*58e6ee5fSAndroid Build Coastguard Worker if (pi->type < KBUFFER_TYPE_PADDING)
922*58e6ee5fSAndroid Build Coastguard Worker break;
923*58e6ee5fSAndroid Build Coastguard Worker switch (pi->type) {
924*58e6ee5fSAndroid Build Coastguard Worker case KBUFFER_TYPE_PADDING:
925*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(&s, "\n PADDING: ");
926*58e6ee5fSAndroid Build Coastguard Worker break;
927*58e6ee5fSAndroid Build Coastguard Worker case KBUFFER_TYPE_TIME_EXTEND:
928*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(&s, "\n TIME EXTEND: ");
929*58e6ee5fSAndroid Build Coastguard Worker break;
930*58e6ee5fSAndroid Build Coastguard Worker case KBUFFER_TYPE_TIME_STAMP:
931*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(&s, "\n TIME STAMP: ");
932*58e6ee5fSAndroid Build Coastguard Worker break;
933*58e6ee5fSAndroid Build Coastguard Worker }
934*58e6ee5fSAndroid Build Coastguard Worker if (pi->type == KBUFFER_TYPE_TIME_STAMP)
935*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(&s, "timestamp:%lld length:%d",
936*58e6ee5fSAndroid Build Coastguard Worker pi->delta,
937*58e6ee5fSAndroid Build Coastguard Worker pi->length);
938*58e6ee5fSAndroid Build Coastguard Worker else
939*58e6ee5fSAndroid Build Coastguard Worker trace_seq_printf(&s, "delta:%lld length:%d",
940*58e6ee5fSAndroid Build Coastguard Worker pi->delta,
941*58e6ee5fSAndroid Build Coastguard Worker pi->length);
942*58e6ee5fSAndroid Build Coastguard Worker }
943*58e6ee5fSAndroid Build Coastguard Worker }
944*58e6ee5fSAndroid Build Coastguard Worker }
945*58e6ee5fSAndroid Build Coastguard Worker
946*58e6ee5fSAndroid Build Coastguard Worker trace_seq_do_printf(&s);
947*58e6ee5fSAndroid Build Coastguard Worker trace_seq_destroy(&s);
948*58e6ee5fSAndroid Build Coastguard Worker
949*58e6ee5fSAndroid Build Coastguard Worker process_wakeup(pevent, record);
950*58e6ee5fSAndroid Build Coastguard Worker
951*58e6ee5fSAndroid Build Coastguard Worker printf("\n");
952*58e6ee5fSAndroid Build Coastguard Worker }
953*58e6ee5fSAndroid Build Coastguard Worker
read_latency(struct tracecmd_input * handle)954*58e6ee5fSAndroid Build Coastguard Worker static void read_latency(struct tracecmd_input *handle)
955*58e6ee5fSAndroid Build Coastguard Worker {
956*58e6ee5fSAndroid Build Coastguard Worker char *buf = NULL;
957*58e6ee5fSAndroid Build Coastguard Worker size_t size = 0;
958*58e6ee5fSAndroid Build Coastguard Worker int r;
959*58e6ee5fSAndroid Build Coastguard Worker
960*58e6ee5fSAndroid Build Coastguard Worker do {
961*58e6ee5fSAndroid Build Coastguard Worker r = tracecmd_latency_data_read(handle, &buf, &size);
962*58e6ee5fSAndroid Build Coastguard Worker if (r > 0)
963*58e6ee5fSAndroid Build Coastguard Worker printf("%.*s", r, buf);
964*58e6ee5fSAndroid Build Coastguard Worker } while (r > 0);
965*58e6ee5fSAndroid Build Coastguard Worker
966*58e6ee5fSAndroid Build Coastguard Worker printf("\n");
967*58e6ee5fSAndroid Build Coastguard Worker free(buf);
968*58e6ee5fSAndroid Build Coastguard Worker }
969*58e6ee5fSAndroid Build Coastguard Worker
970*58e6ee5fSAndroid Build Coastguard Worker static int
test_filters(struct tep_handle * pevent,struct filter * event_filters,struct tep_record * record,int neg)971*58e6ee5fSAndroid Build Coastguard Worker test_filters(struct tep_handle *pevent, struct filter *event_filters,
972*58e6ee5fSAndroid Build Coastguard Worker struct tep_record *record, int neg)
973*58e6ee5fSAndroid Build Coastguard Worker {
974*58e6ee5fSAndroid Build Coastguard Worker int found = 0;
975*58e6ee5fSAndroid Build Coastguard Worker int ret = FILTER_NONE;
976*58e6ee5fSAndroid Build Coastguard Worker int flags;
977*58e6ee5fSAndroid Build Coastguard Worker
978*58e6ee5fSAndroid Build Coastguard Worker if (no_irqs || no_softirqs) {
979*58e6ee5fSAndroid Build Coastguard Worker flags = tep_data_flags(pevent, record);
980*58e6ee5fSAndroid Build Coastguard Worker if (no_irqs && (flags & TRACE_FLAG_HARDIRQ))
981*58e6ee5fSAndroid Build Coastguard Worker return FILTER_MISS;
982*58e6ee5fSAndroid Build Coastguard Worker if (no_softirqs && (flags & TRACE_FLAG_SOFTIRQ))
983*58e6ee5fSAndroid Build Coastguard Worker return FILTER_MISS;
984*58e6ee5fSAndroid Build Coastguard Worker }
985*58e6ee5fSAndroid Build Coastguard Worker
986*58e6ee5fSAndroid Build Coastguard Worker while (event_filters) {
987*58e6ee5fSAndroid Build Coastguard Worker ret = tep_filter_match(event_filters->filter, record);
988*58e6ee5fSAndroid Build Coastguard Worker switch (ret) {
989*58e6ee5fSAndroid Build Coastguard Worker case FILTER_NONE:
990*58e6ee5fSAndroid Build Coastguard Worker case FILTER_MATCH:
991*58e6ee5fSAndroid Build Coastguard Worker found = 1;
992*58e6ee5fSAndroid Build Coastguard Worker }
993*58e6ee5fSAndroid Build Coastguard Worker /* We need to test all negative filters */
994*58e6ee5fSAndroid Build Coastguard Worker if (!neg && found)
995*58e6ee5fSAndroid Build Coastguard Worker break;
996*58e6ee5fSAndroid Build Coastguard Worker event_filters = event_filters->next;
997*58e6ee5fSAndroid Build Coastguard Worker }
998*58e6ee5fSAndroid Build Coastguard Worker
999*58e6ee5fSAndroid Build Coastguard Worker return ret;
1000*58e6ee5fSAndroid Build Coastguard Worker }
1001*58e6ee5fSAndroid Build Coastguard Worker
1002*58e6ee5fSAndroid Build Coastguard Worker struct stack_info_cpu {
1003*58e6ee5fSAndroid Build Coastguard Worker int cpu;
1004*58e6ee5fSAndroid Build Coastguard Worker int last_printed;
1005*58e6ee5fSAndroid Build Coastguard Worker };
1006*58e6ee5fSAndroid Build Coastguard Worker
1007*58e6ee5fSAndroid Build Coastguard Worker struct stack_info {
1008*58e6ee5fSAndroid Build Coastguard Worker struct stack_info *next;
1009*58e6ee5fSAndroid Build Coastguard Worker struct handle_list *handles;
1010*58e6ee5fSAndroid Build Coastguard Worker struct stack_info_cpu *cpus;
1011*58e6ee5fSAndroid Build Coastguard Worker int stacktrace_id;
1012*58e6ee5fSAndroid Build Coastguard Worker int nr_cpus;
1013*58e6ee5fSAndroid Build Coastguard Worker };
1014*58e6ee5fSAndroid Build Coastguard Worker
1015*58e6ee5fSAndroid Build Coastguard Worker static int
test_stacktrace(struct handle_list * handles,struct tep_record * record,int last_printed)1016*58e6ee5fSAndroid Build Coastguard Worker test_stacktrace(struct handle_list *handles, struct tep_record *record,
1017*58e6ee5fSAndroid Build Coastguard Worker int last_printed)
1018*58e6ee5fSAndroid Build Coastguard Worker {
1019*58e6ee5fSAndroid Build Coastguard Worker static struct stack_info *infos;
1020*58e6ee5fSAndroid Build Coastguard Worker struct stack_info *info;
1021*58e6ee5fSAndroid Build Coastguard Worker struct stack_info_cpu *cpu_info;
1022*58e6ee5fSAndroid Build Coastguard Worker struct handle_list *h;
1023*58e6ee5fSAndroid Build Coastguard Worker struct tracecmd_input *handle;
1024*58e6ee5fSAndroid Build Coastguard Worker struct tep_handle *pevent;
1025*58e6ee5fSAndroid Build Coastguard Worker struct tep_event *event;
1026*58e6ee5fSAndroid Build Coastguard Worker static int init;
1027*58e6ee5fSAndroid Build Coastguard Worker int ret;
1028*58e6ee5fSAndroid Build Coastguard Worker int id;
1029*58e6ee5fSAndroid Build Coastguard Worker
1030*58e6ee5fSAndroid Build Coastguard Worker if (!init) {
1031*58e6ee5fSAndroid Build Coastguard Worker init = 1;
1032*58e6ee5fSAndroid Build Coastguard Worker
1033*58e6ee5fSAndroid Build Coastguard Worker list_for_each_entry(h, &handle_list, list) {
1034*58e6ee5fSAndroid Build Coastguard Worker info = malloc(sizeof(*info));
1035*58e6ee5fSAndroid Build Coastguard Worker if (!info)
1036*58e6ee5fSAndroid Build Coastguard Worker die("Failed to allocate handle");
1037*58e6ee5fSAndroid Build Coastguard Worker info->handles = h;
1038*58e6ee5fSAndroid Build Coastguard Worker info->nr_cpus = tracecmd_cpus(h->handle);
1039*58e6ee5fSAndroid Build Coastguard Worker
1040*58e6ee5fSAndroid Build Coastguard Worker info->cpus = malloc(sizeof(*info->cpus) * info->nr_cpus);
1041*58e6ee5fSAndroid Build Coastguard Worker if (!info->cpus)
1042*58e6ee5fSAndroid Build Coastguard Worker die("Failed to allocate for %d cpus", info->nr_cpus);
1043*58e6ee5fSAndroid Build Coastguard Worker memset(info->cpus, 0, sizeof(*info->cpus));
1044*58e6ee5fSAndroid Build Coastguard Worker
1045*58e6ee5fSAndroid Build Coastguard Worker pevent = tracecmd_get_tep(h->handle);
1046*58e6ee5fSAndroid Build Coastguard Worker event = tep_find_event_by_name(pevent, "ftrace",
1047*58e6ee5fSAndroid Build Coastguard Worker "kernel_stack");
1048*58e6ee5fSAndroid Build Coastguard Worker if (event)
1049*58e6ee5fSAndroid Build Coastguard Worker info->stacktrace_id = event->id;
1050*58e6ee5fSAndroid Build Coastguard Worker else
1051*58e6ee5fSAndroid Build Coastguard Worker info->stacktrace_id = 0;
1052*58e6ee5fSAndroid Build Coastguard Worker
1053*58e6ee5fSAndroid Build Coastguard Worker info->next = infos;
1054*58e6ee5fSAndroid Build Coastguard Worker infos = info;
1055*58e6ee5fSAndroid Build Coastguard Worker }
1056*58e6ee5fSAndroid Build Coastguard Worker
1057*58e6ee5fSAndroid Build Coastguard Worker
1058*58e6ee5fSAndroid Build Coastguard Worker }
1059*58e6ee5fSAndroid Build Coastguard Worker
1060*58e6ee5fSAndroid Build Coastguard Worker handle = handles->handle;
1061*58e6ee5fSAndroid Build Coastguard Worker pevent = tracecmd_get_tep(handle);
1062*58e6ee5fSAndroid Build Coastguard Worker
1063*58e6ee5fSAndroid Build Coastguard Worker for (info = infos; info; info = info->next)
1064*58e6ee5fSAndroid Build Coastguard Worker if (info->handles == handles)
1065*58e6ee5fSAndroid Build Coastguard Worker break;
1066*58e6ee5fSAndroid Build Coastguard Worker
1067*58e6ee5fSAndroid Build Coastguard Worker if (!info->stacktrace_id)
1068*58e6ee5fSAndroid Build Coastguard Worker return 0;
1069*58e6ee5fSAndroid Build Coastguard Worker
1070*58e6ee5fSAndroid Build Coastguard Worker cpu_info = &info->cpus[record->cpu];
1071*58e6ee5fSAndroid Build Coastguard Worker
1072*58e6ee5fSAndroid Build Coastguard Worker id = tep_data_type(pevent, record);
1073*58e6ee5fSAndroid Build Coastguard Worker
1074*58e6ee5fSAndroid Build Coastguard Worker /*
1075*58e6ee5fSAndroid Build Coastguard Worker * Print the stack trace if the previous event was printed.
1076*58e6ee5fSAndroid Build Coastguard Worker * But do not print the stack trace if it is explicitly
1077*58e6ee5fSAndroid Build Coastguard Worker * being filtered out.
1078*58e6ee5fSAndroid Build Coastguard Worker */
1079*58e6ee5fSAndroid Build Coastguard Worker if (id == info->stacktrace_id) {
1080*58e6ee5fSAndroid Build Coastguard Worker ret = test_filters(pevent, handles->event_filter_out, record, 1);
1081*58e6ee5fSAndroid Build Coastguard Worker if (ret != FILTER_MATCH)
1082*58e6ee5fSAndroid Build Coastguard Worker return cpu_info->last_printed;
1083*58e6ee5fSAndroid Build Coastguard Worker return 0;
1084*58e6ee5fSAndroid Build Coastguard Worker }
1085*58e6ee5fSAndroid Build Coastguard Worker
1086*58e6ee5fSAndroid Build Coastguard Worker cpu_info->last_printed = last_printed;
1087*58e6ee5fSAndroid Build Coastguard Worker return 0;
1088*58e6ee5fSAndroid Build Coastguard Worker }
1089*58e6ee5fSAndroid Build Coastguard Worker
get_next_record(struct handle_list * handles)1090*58e6ee5fSAndroid Build Coastguard Worker static struct tep_record *get_next_record(struct handle_list *handles)
1091*58e6ee5fSAndroid Build Coastguard Worker {
1092*58e6ee5fSAndroid Build Coastguard Worker struct tep_record *record;
1093*58e6ee5fSAndroid Build Coastguard Worker struct tep_handle *pevent;
1094*58e6ee5fSAndroid Build Coastguard Worker int found = 0;
1095*58e6ee5fSAndroid Build Coastguard Worker int cpu;
1096*58e6ee5fSAndroid Build Coastguard Worker int ret;
1097*58e6ee5fSAndroid Build Coastguard Worker
1098*58e6ee5fSAndroid Build Coastguard Worker if (handles->record)
1099*58e6ee5fSAndroid Build Coastguard Worker return handles->record;
1100*58e6ee5fSAndroid Build Coastguard Worker
1101*58e6ee5fSAndroid Build Coastguard Worker if (handles->done)
1102*58e6ee5fSAndroid Build Coastguard Worker return NULL;
1103*58e6ee5fSAndroid Build Coastguard Worker
1104*58e6ee5fSAndroid Build Coastguard Worker pevent = tracecmd_get_tep(handles->handle);
1105*58e6ee5fSAndroid Build Coastguard Worker
1106*58e6ee5fSAndroid Build Coastguard Worker do {
1107*58e6ee5fSAndroid Build Coastguard Worker if (filter_cpus) {
1108*58e6ee5fSAndroid Build Coastguard Worker long long last_stamp = -1;
1109*58e6ee5fSAndroid Build Coastguard Worker struct tep_record *precord;
1110*58e6ee5fSAndroid Build Coastguard Worker int first_record = 1;
1111*58e6ee5fSAndroid Build Coastguard Worker int next_cpu = -1;
1112*58e6ee5fSAndroid Build Coastguard Worker int i;
1113*58e6ee5fSAndroid Build Coastguard Worker
1114*58e6ee5fSAndroid Build Coastguard Worker for (i = 0; (cpu = filter_cpus[i]) >= 0; i++) {
1115*58e6ee5fSAndroid Build Coastguard Worker precord = tracecmd_peek_data(handles->handle, cpu);
1116*58e6ee5fSAndroid Build Coastguard Worker if (precord &&
1117*58e6ee5fSAndroid Build Coastguard Worker (first_record || precord->ts < last_stamp)) {
1118*58e6ee5fSAndroid Build Coastguard Worker next_cpu = cpu;
1119*58e6ee5fSAndroid Build Coastguard Worker last_stamp = precord->ts;
1120*58e6ee5fSAndroid Build Coastguard Worker first_record = 0;
1121*58e6ee5fSAndroid Build Coastguard Worker }
1122*58e6ee5fSAndroid Build Coastguard Worker }
1123*58e6ee5fSAndroid Build Coastguard Worker if (!first_record)
1124*58e6ee5fSAndroid Build Coastguard Worker record = tracecmd_read_data(handles->handle, next_cpu);
1125*58e6ee5fSAndroid Build Coastguard Worker else
1126*58e6ee5fSAndroid Build Coastguard Worker record = NULL;
1127*58e6ee5fSAndroid Build Coastguard Worker } else
1128*58e6ee5fSAndroid Build Coastguard Worker record = tracecmd_read_next_data(handles->handle, &cpu);
1129*58e6ee5fSAndroid Build Coastguard Worker
1130*58e6ee5fSAndroid Build Coastguard Worker if (record) {
1131*58e6ee5fSAndroid Build Coastguard Worker ret = test_filters(pevent, handles->event_filters, record, 0);
1132*58e6ee5fSAndroid Build Coastguard Worker switch (ret) {
1133*58e6ee5fSAndroid Build Coastguard Worker case FILTER_NOEXIST:
1134*58e6ee5fSAndroid Build Coastguard Worker /* Stack traces may still filter this */
1135*58e6ee5fSAndroid Build Coastguard Worker if (stacktrace_id &&
1136*58e6ee5fSAndroid Build Coastguard Worker test_stacktrace(handles, record, 0))
1137*58e6ee5fSAndroid Build Coastguard Worker found = 1;
1138*58e6ee5fSAndroid Build Coastguard Worker else
1139*58e6ee5fSAndroid Build Coastguard Worker tracecmd_free_record(record);
1140*58e6ee5fSAndroid Build Coastguard Worker break;
1141*58e6ee5fSAndroid Build Coastguard Worker case FILTER_NONE:
1142*58e6ee5fSAndroid Build Coastguard Worker case FILTER_MATCH:
1143*58e6ee5fSAndroid Build Coastguard Worker /* Test the negative filters (-v) */
1144*58e6ee5fSAndroid Build Coastguard Worker ret = test_filters(pevent, handles->event_filter_out,
1145*58e6ee5fSAndroid Build Coastguard Worker record, 1);
1146*58e6ee5fSAndroid Build Coastguard Worker if (ret != FILTER_MATCH) {
1147*58e6ee5fSAndroid Build Coastguard Worker found = 1;
1148*58e6ee5fSAndroid Build Coastguard Worker break;
1149*58e6ee5fSAndroid Build Coastguard Worker }
1150*58e6ee5fSAndroid Build Coastguard Worker /* fall through */
1151*58e6ee5fSAndroid Build Coastguard Worker default:
1152*58e6ee5fSAndroid Build Coastguard Worker tracecmd_free_record(record);
1153*58e6ee5fSAndroid Build Coastguard Worker }
1154*58e6ee5fSAndroid Build Coastguard Worker }
1155*58e6ee5fSAndroid Build Coastguard Worker } while (record && !found);
1156*58e6ee5fSAndroid Build Coastguard Worker
1157*58e6ee5fSAndroid Build Coastguard Worker if (record && stacktrace_id)
1158*58e6ee5fSAndroid Build Coastguard Worker test_stacktrace(handles, record, 1);
1159*58e6ee5fSAndroid Build Coastguard Worker
1160*58e6ee5fSAndroid Build Coastguard Worker handles->record = record;
1161*58e6ee5fSAndroid Build Coastguard Worker if (!record)
1162*58e6ee5fSAndroid Build Coastguard Worker handles->done = 1;
1163*58e6ee5fSAndroid Build Coastguard Worker
1164*58e6ee5fSAndroid Build Coastguard Worker return record;
1165*58e6ee5fSAndroid Build Coastguard Worker }
1166*58e6ee5fSAndroid Build Coastguard Worker
free_handle_record(struct handle_list * handles)1167*58e6ee5fSAndroid Build Coastguard Worker static void free_handle_record(struct handle_list *handles)
1168*58e6ee5fSAndroid Build Coastguard Worker {
1169*58e6ee5fSAndroid Build Coastguard Worker if (!handles->record)
1170*58e6ee5fSAndroid Build Coastguard Worker return;
1171*58e6ee5fSAndroid Build Coastguard Worker
1172*58e6ee5fSAndroid Build Coastguard Worker tracecmd_free_record(handles->record);
1173*58e6ee5fSAndroid Build Coastguard Worker handles->record = NULL;
1174*58e6ee5fSAndroid Build Coastguard Worker }
1175*58e6ee5fSAndroid Build Coastguard Worker
print_handle_file(struct handle_list * handles)1176*58e6ee5fSAndroid Build Coastguard Worker static void print_handle_file(struct handle_list *handles)
1177*58e6ee5fSAndroid Build Coastguard Worker {
1178*58e6ee5fSAndroid Build Coastguard Worker /* Only print file names if more than one file is read */
1179*58e6ee5fSAndroid Build Coastguard Worker if (!multi_inputs && !instances)
1180*58e6ee5fSAndroid Build Coastguard Worker return;
1181*58e6ee5fSAndroid Build Coastguard Worker if (handles->file && *handles->file != '\0')
1182*58e6ee5fSAndroid Build Coastguard Worker printf("%*s: ", max_file_size, handles->file);
1183*58e6ee5fSAndroid Build Coastguard Worker else
1184*58e6ee5fSAndroid Build Coastguard Worker printf("%*s ", max_file_size, "");
1185*58e6ee5fSAndroid Build Coastguard Worker }
1186*58e6ee5fSAndroid Build Coastguard Worker
free_filters(struct filter * event_filter)1187*58e6ee5fSAndroid Build Coastguard Worker static void free_filters(struct filter *event_filter)
1188*58e6ee5fSAndroid Build Coastguard Worker {
1189*58e6ee5fSAndroid Build Coastguard Worker struct filter *filter;
1190*58e6ee5fSAndroid Build Coastguard Worker
1191*58e6ee5fSAndroid Build Coastguard Worker while (event_filter) {
1192*58e6ee5fSAndroid Build Coastguard Worker filter = event_filter;
1193*58e6ee5fSAndroid Build Coastguard Worker event_filter = filter->next;
1194*58e6ee5fSAndroid Build Coastguard Worker
1195*58e6ee5fSAndroid Build Coastguard Worker tep_filter_free(filter->filter);
1196*58e6ee5fSAndroid Build Coastguard Worker free(filter);
1197*58e6ee5fSAndroid Build Coastguard Worker }
1198*58e6ee5fSAndroid Build Coastguard Worker }
1199*58e6ee5fSAndroid Build Coastguard Worker
1200*58e6ee5fSAndroid Build Coastguard Worker enum output_type {
1201*58e6ee5fSAndroid Build Coastguard Worker OUTPUT_NORMAL,
1202*58e6ee5fSAndroid Build Coastguard Worker OUTPUT_STAT_ONLY,
1203*58e6ee5fSAndroid Build Coastguard Worker OUTPUT_UNAME_ONLY,
1204*58e6ee5fSAndroid Build Coastguard Worker OUTPUT_VERSION_ONLY,
1205*58e6ee5fSAndroid Build Coastguard Worker };
1206*58e6ee5fSAndroid Build Coastguard Worker
read_data_info(struct list_head * handle_list,enum output_type otype,int global,int align_ts)1207*58e6ee5fSAndroid Build Coastguard Worker static void read_data_info(struct list_head *handle_list, enum output_type otype,
1208*58e6ee5fSAndroid Build Coastguard Worker int global, int align_ts)
1209*58e6ee5fSAndroid Build Coastguard Worker {
1210*58e6ee5fSAndroid Build Coastguard Worker unsigned long long ts, first_ts;
1211*58e6ee5fSAndroid Build Coastguard Worker struct handle_list *handles;
1212*58e6ee5fSAndroid Build Coastguard Worker struct handle_list *last_handle;
1213*58e6ee5fSAndroid Build Coastguard Worker struct tep_record *record;
1214*58e6ee5fSAndroid Build Coastguard Worker struct tep_record *last_record;
1215*58e6ee5fSAndroid Build Coastguard Worker struct tep_handle *pevent;
1216*58e6ee5fSAndroid Build Coastguard Worker struct tep_event *event;
1217*58e6ee5fSAndroid Build Coastguard Worker int first = 1;
1218*58e6ee5fSAndroid Build Coastguard Worker int ret;
1219*58e6ee5fSAndroid Build Coastguard Worker
1220*58e6ee5fSAndroid Build Coastguard Worker list_for_each_entry(handles, handle_list, list) {
1221*58e6ee5fSAndroid Build Coastguard Worker int cpus;
1222*58e6ee5fSAndroid Build Coastguard Worker
1223*58e6ee5fSAndroid Build Coastguard Worker if (!tracecmd_is_buffer_instance(handles->handle)) {
1224*58e6ee5fSAndroid Build Coastguard Worker ret = tracecmd_init_data(handles->handle);
1225*58e6ee5fSAndroid Build Coastguard Worker if (ret < 0)
1226*58e6ee5fSAndroid Build Coastguard Worker die("failed to init data");
1227*58e6ee5fSAndroid Build Coastguard Worker }
1228*58e6ee5fSAndroid Build Coastguard Worker cpus = tracecmd_cpus(handles->handle);
1229*58e6ee5fSAndroid Build Coastguard Worker handles->cpus = cpus;
1230*58e6ee5fSAndroid Build Coastguard Worker handles->last_timestamp = calloc(cpus, sizeof(*handles->last_timestamp));
1231*58e6ee5fSAndroid Build Coastguard Worker if (!handles->last_timestamp)
1232*58e6ee5fSAndroid Build Coastguard Worker die("allocating timestamps");
1233*58e6ee5fSAndroid Build Coastguard Worker
1234*58e6ee5fSAndroid Build Coastguard Worker /* Don't process instances that we added here */
1235*58e6ee5fSAndroid Build Coastguard Worker if (tracecmd_is_buffer_instance(handles->handle))
1236*58e6ee5fSAndroid Build Coastguard Worker continue;
1237*58e6ee5fSAndroid Build Coastguard Worker
1238*58e6ee5fSAndroid Build Coastguard Worker if (align_ts) {
1239*58e6ee5fSAndroid Build Coastguard Worker ts = tracecmd_get_first_ts(handles->handle);
1240*58e6ee5fSAndroid Build Coastguard Worker if (first || first_ts > ts)
1241*58e6ee5fSAndroid Build Coastguard Worker first_ts = ts;
1242*58e6ee5fSAndroid Build Coastguard Worker first = 0;
1243*58e6ee5fSAndroid Build Coastguard Worker }
1244*58e6ee5fSAndroid Build Coastguard Worker print_handle_file(handles);
1245*58e6ee5fSAndroid Build Coastguard Worker printf("cpus=%d\n", cpus);
1246*58e6ee5fSAndroid Build Coastguard Worker
1247*58e6ee5fSAndroid Build Coastguard Worker /* Latency trace is just all ASCII */
1248*58e6ee5fSAndroid Build Coastguard Worker if (ret > 0) {
1249*58e6ee5fSAndroid Build Coastguard Worker if (multi_inputs)
1250*58e6ee5fSAndroid Build Coastguard Worker die("latency traces do not work with multiple inputs");
1251*58e6ee5fSAndroid Build Coastguard Worker read_latency(handles->handle);
1252*58e6ee5fSAndroid Build Coastguard Worker return;
1253*58e6ee5fSAndroid Build Coastguard Worker }
1254*58e6ee5fSAndroid Build Coastguard Worker
1255*58e6ee5fSAndroid Build Coastguard Worker switch (otype) {
1256*58e6ee5fSAndroid Build Coastguard Worker case OUTPUT_NORMAL:
1257*58e6ee5fSAndroid Build Coastguard Worker break;
1258*58e6ee5fSAndroid Build Coastguard Worker case OUTPUT_STAT_ONLY:
1259*58e6ee5fSAndroid Build Coastguard Worker printf("\nKernel buffer statistics:\n"
1260*58e6ee5fSAndroid Build Coastguard Worker " Note: \"entries\" are the entries left in the kernel ring buffer and are not\n"
1261*58e6ee5fSAndroid Build Coastguard Worker " recorded in the trace data. They should all be zero.\n\n");
1262*58e6ee5fSAndroid Build Coastguard Worker tracecmd_print_stats(handles->handle);
1263*58e6ee5fSAndroid Build Coastguard Worker continue;
1264*58e6ee5fSAndroid Build Coastguard Worker case OUTPUT_UNAME_ONLY:
1265*58e6ee5fSAndroid Build Coastguard Worker tracecmd_print_uname(handles->handle);
1266*58e6ee5fSAndroid Build Coastguard Worker case OUTPUT_VERSION_ONLY:
1267*58e6ee5fSAndroid Build Coastguard Worker tracecmd_print_version(handles->handle);
1268*58e6ee5fSAndroid Build Coastguard Worker continue;
1269*58e6ee5fSAndroid Build Coastguard Worker }
1270*58e6ee5fSAndroid Build Coastguard Worker
1271*58e6ee5fSAndroid Build Coastguard Worker /* Find the kernel_stacktrace if available */
1272*58e6ee5fSAndroid Build Coastguard Worker pevent = tracecmd_get_tep(handles->handle);
1273*58e6ee5fSAndroid Build Coastguard Worker event = tep_find_event_by_name(pevent, "ftrace", "kernel_stack");
1274*58e6ee5fSAndroid Build Coastguard Worker if (event)
1275*58e6ee5fSAndroid Build Coastguard Worker stacktrace_id = event->id;
1276*58e6ee5fSAndroid Build Coastguard Worker
1277*58e6ee5fSAndroid Build Coastguard Worker init_wakeup(handles->handle);
1278*58e6ee5fSAndroid Build Coastguard Worker if (last_hook)
1279*58e6ee5fSAndroid Build Coastguard Worker last_hook->next = tracecmd_hooks(handles->handle);
1280*58e6ee5fSAndroid Build Coastguard Worker else
1281*58e6ee5fSAndroid Build Coastguard Worker hooks = tracecmd_hooks(handles->handle);
1282*58e6ee5fSAndroid Build Coastguard Worker if (profile)
1283*58e6ee5fSAndroid Build Coastguard Worker trace_init_profile(handles->handle, hooks, global);
1284*58e6ee5fSAndroid Build Coastguard Worker
1285*58e6ee5fSAndroid Build Coastguard Worker process_filters(handles);
1286*58e6ee5fSAndroid Build Coastguard Worker
1287*58e6ee5fSAndroid Build Coastguard Worker /* If this file has buffer instances, get the handles for them */
1288*58e6ee5fSAndroid Build Coastguard Worker instances = tracecmd_buffer_instances(handles->handle);
1289*58e6ee5fSAndroid Build Coastguard Worker if (instances) {
1290*58e6ee5fSAndroid Build Coastguard Worker struct tracecmd_input *new_handle;
1291*58e6ee5fSAndroid Build Coastguard Worker const char *name;
1292*58e6ee5fSAndroid Build Coastguard Worker int i;
1293*58e6ee5fSAndroid Build Coastguard Worker
1294*58e6ee5fSAndroid Build Coastguard Worker for (i = 0; i < instances; i++) {
1295*58e6ee5fSAndroid Build Coastguard Worker name = tracecmd_buffer_instance_name(handles->handle, i);
1296*58e6ee5fSAndroid Build Coastguard Worker if (!name)
1297*58e6ee5fSAndroid Build Coastguard Worker die("error in reading buffer instance");
1298*58e6ee5fSAndroid Build Coastguard Worker new_handle = tracecmd_buffer_instance_handle(handles->handle, i);
1299*58e6ee5fSAndroid Build Coastguard Worker if (!new_handle) {
1300*58e6ee5fSAndroid Build Coastguard Worker warning("could not retrieve handle %s", name);
1301*58e6ee5fSAndroid Build Coastguard Worker continue;
1302*58e6ee5fSAndroid Build Coastguard Worker }
1303*58e6ee5fSAndroid Build Coastguard Worker add_handle(new_handle, name);
1304*58e6ee5fSAndroid Build Coastguard Worker }
1305*58e6ee5fSAndroid Build Coastguard Worker }
1306*58e6ee5fSAndroid Build Coastguard Worker }
1307*58e6ee5fSAndroid Build Coastguard Worker
1308*58e6ee5fSAndroid Build Coastguard Worker if (otype != OUTPUT_NORMAL)
1309*58e6ee5fSAndroid Build Coastguard Worker return;
1310*58e6ee5fSAndroid Build Coastguard Worker
1311*58e6ee5fSAndroid Build Coastguard Worker if (align_ts) {
1312*58e6ee5fSAndroid Build Coastguard Worker list_for_each_entry(handles, handle_list, list) {
1313*58e6ee5fSAndroid Build Coastguard Worker tracecmd_add_ts_offset(handles->handle, -first_ts);
1314*58e6ee5fSAndroid Build Coastguard Worker }
1315*58e6ee5fSAndroid Build Coastguard Worker }
1316*58e6ee5fSAndroid Build Coastguard Worker
1317*58e6ee5fSAndroid Build Coastguard Worker do {
1318*58e6ee5fSAndroid Build Coastguard Worker last_handle = NULL;
1319*58e6ee5fSAndroid Build Coastguard Worker last_record = NULL;
1320*58e6ee5fSAndroid Build Coastguard Worker
1321*58e6ee5fSAndroid Build Coastguard Worker list_for_each_entry(handles, handle_list, list) {
1322*58e6ee5fSAndroid Build Coastguard Worker record = get_next_record(handles);
1323*58e6ee5fSAndroid Build Coastguard Worker if (!record)
1324*58e6ee5fSAndroid Build Coastguard Worker continue;
1325*58e6ee5fSAndroid Build Coastguard Worker if (!last_record ||
1326*58e6ee5fSAndroid Build Coastguard Worker (record && record->ts < last_record->ts)) {
1327*58e6ee5fSAndroid Build Coastguard Worker last_record = record;
1328*58e6ee5fSAndroid Build Coastguard Worker last_handle = handles;
1329*58e6ee5fSAndroid Build Coastguard Worker }
1330*58e6ee5fSAndroid Build Coastguard Worker }
1331*58e6ee5fSAndroid Build Coastguard Worker if (last_record) {
1332*58e6ee5fSAndroid Build Coastguard Worker int cpu = last_record->cpu;
1333*58e6ee5fSAndroid Build Coastguard Worker if (cpu >= last_handle->cpus)
1334*58e6ee5fSAndroid Build Coastguard Worker die("cpu %d greater than %d\n", cpu, last_handle->cpus);
1335*58e6ee5fSAndroid Build Coastguard Worker if (tscheck &&
1336*58e6ee5fSAndroid Build Coastguard Worker last_handle->last_timestamp[cpu] > last_record->ts) {
1337*58e6ee5fSAndroid Build Coastguard Worker errno = 0;
1338*58e6ee5fSAndroid Build Coastguard Worker warning("WARNING: Record on cpu %d went backwards: %lld to %lld delta: -%lld\n",
1339*58e6ee5fSAndroid Build Coastguard Worker cpu, last_handle->last_timestamp[cpu],
1340*58e6ee5fSAndroid Build Coastguard Worker last_record->ts,
1341*58e6ee5fSAndroid Build Coastguard Worker last_handle->last_timestamp[cpu] - last_record->ts);
1342*58e6ee5fSAndroid Build Coastguard Worker }
1343*58e6ee5fSAndroid Build Coastguard Worker last_handle->last_timestamp[cpu] = last_record->ts;
1344*58e6ee5fSAndroid Build Coastguard Worker print_handle_file(last_handle);
1345*58e6ee5fSAndroid Build Coastguard Worker trace_show_data(last_handle->handle, last_record);
1346*58e6ee5fSAndroid Build Coastguard Worker free_handle_record(last_handle);
1347*58e6ee5fSAndroid Build Coastguard Worker }
1348*58e6ee5fSAndroid Build Coastguard Worker } while (last_record);
1349*58e6ee5fSAndroid Build Coastguard Worker
1350*58e6ee5fSAndroid Build Coastguard Worker if (profile)
1351*58e6ee5fSAndroid Build Coastguard Worker do_trace_profile();
1352*58e6ee5fSAndroid Build Coastguard Worker
1353*58e6ee5fSAndroid Build Coastguard Worker list_for_each_entry(handles, handle_list, list) {
1354*58e6ee5fSAndroid Build Coastguard Worker free_filters(handles->event_filters);
1355*58e6ee5fSAndroid Build Coastguard Worker free_filters(handles->event_filter_out);
1356*58e6ee5fSAndroid Build Coastguard Worker free(handles->last_timestamp);
1357*58e6ee5fSAndroid Build Coastguard Worker
1358*58e6ee5fSAndroid Build Coastguard Worker show_test(handles->handle);
1359*58e6ee5fSAndroid Build Coastguard Worker }
1360*58e6ee5fSAndroid Build Coastguard Worker }
1361*58e6ee5fSAndroid Build Coastguard Worker
read_trace_header(const char * file,int flags)1362*58e6ee5fSAndroid Build Coastguard Worker struct tracecmd_input *read_trace_header(const char *file, int flags)
1363*58e6ee5fSAndroid Build Coastguard Worker {
1364*58e6ee5fSAndroid Build Coastguard Worker input_fd = open(file, O_RDONLY);
1365*58e6ee5fSAndroid Build Coastguard Worker if (input_fd < 0)
1366*58e6ee5fSAndroid Build Coastguard Worker die("opening '%s'\n", file);
1367*58e6ee5fSAndroid Build Coastguard Worker
1368*58e6ee5fSAndroid Build Coastguard Worker return tracecmd_alloc_fd(input_fd, flags);
1369*58e6ee5fSAndroid Build Coastguard Worker }
1370*58e6ee5fSAndroid Build Coastguard Worker
sig_end(int sig)1371*58e6ee5fSAndroid Build Coastguard Worker static void sig_end(int sig)
1372*58e6ee5fSAndroid Build Coastguard Worker {
1373*58e6ee5fSAndroid Build Coastguard Worker struct handle_list *handles;
1374*58e6ee5fSAndroid Build Coastguard Worker
1375*58e6ee5fSAndroid Build Coastguard Worker fprintf(stderr, "trace-cmd: Received SIGINT\n");
1376*58e6ee5fSAndroid Build Coastguard Worker
1377*58e6ee5fSAndroid Build Coastguard Worker list_for_each_entry(handles, &handle_list, list) {
1378*58e6ee5fSAndroid Build Coastguard Worker tracecmd_close(handles->handle);
1379*58e6ee5fSAndroid Build Coastguard Worker }
1380*58e6ee5fSAndroid Build Coastguard Worker
1381*58e6ee5fSAndroid Build Coastguard Worker exit(0);
1382*58e6ee5fSAndroid Build Coastguard Worker }
1383*58e6ee5fSAndroid Build Coastguard Worker
skip_space_and_test_digit(const char * p,const char * cpu_str)1384*58e6ee5fSAndroid Build Coastguard Worker static const char *skip_space_and_test_digit(const char *p, const char *cpu_str)
1385*58e6ee5fSAndroid Build Coastguard Worker {
1386*58e6ee5fSAndroid Build Coastguard Worker while (isspace(*p))
1387*58e6ee5fSAndroid Build Coastguard Worker p++;
1388*58e6ee5fSAndroid Build Coastguard Worker if (!isdigit(*p))
1389*58e6ee5fSAndroid Build Coastguard Worker die("invalid character '%c' in cpu string '%s'",
1390*58e6ee5fSAndroid Build Coastguard Worker *p, cpu_str);
1391*58e6ee5fSAndroid Build Coastguard Worker return p;
1392*58e6ee5fSAndroid Build Coastguard Worker }
1393*58e6ee5fSAndroid Build Coastguard Worker
__add_cpu(int cpu)1394*58e6ee5fSAndroid Build Coastguard Worker static void __add_cpu(int cpu)
1395*58e6ee5fSAndroid Build Coastguard Worker {
1396*58e6ee5fSAndroid Build Coastguard Worker filter_cpus = tracecmd_add_id(filter_cpus, cpu, nr_filter_cpus++);
1397*58e6ee5fSAndroid Build Coastguard Worker }
1398*58e6ee5fSAndroid Build Coastguard Worker
parse_cpulist(const char * cpu_str)1399*58e6ee5fSAndroid Build Coastguard Worker static void parse_cpulist(const char *cpu_str)
1400*58e6ee5fSAndroid Build Coastguard Worker {
1401*58e6ee5fSAndroid Build Coastguard Worker unsigned a, b;
1402*58e6ee5fSAndroid Build Coastguard Worker const char *s = cpu_str;
1403*58e6ee5fSAndroid Build Coastguard Worker
1404*58e6ee5fSAndroid Build Coastguard Worker do {
1405*58e6ee5fSAndroid Build Coastguard Worker s = skip_space_and_test_digit(s, cpu_str);
1406*58e6ee5fSAndroid Build Coastguard Worker b = a = strtoul(s, (char **)&s, 10);
1407*58e6ee5fSAndroid Build Coastguard Worker if (*s == '-') {
1408*58e6ee5fSAndroid Build Coastguard Worker s = skip_space_and_test_digit(s + 1, cpu_str);
1409*58e6ee5fSAndroid Build Coastguard Worker b = strtoul(s, (char **)&s, 10);
1410*58e6ee5fSAndroid Build Coastguard Worker }
1411*58e6ee5fSAndroid Build Coastguard Worker if (!(a <= b))
1412*58e6ee5fSAndroid Build Coastguard Worker die("range of cpu numbers must be lower to greater");
1413*58e6ee5fSAndroid Build Coastguard Worker while (a <= b) {
1414*58e6ee5fSAndroid Build Coastguard Worker __add_cpu(a);
1415*58e6ee5fSAndroid Build Coastguard Worker a++;
1416*58e6ee5fSAndroid Build Coastguard Worker }
1417*58e6ee5fSAndroid Build Coastguard Worker if (*s == ',' || *s == ':')
1418*58e6ee5fSAndroid Build Coastguard Worker s++;
1419*58e6ee5fSAndroid Build Coastguard Worker } while (*s != '\0');
1420*58e6ee5fSAndroid Build Coastguard Worker }
1421*58e6ee5fSAndroid Build Coastguard Worker
read_file_fd(int fd,char * dst,int len)1422*58e6ee5fSAndroid Build Coastguard Worker static void read_file_fd(int fd, char *dst, int len)
1423*58e6ee5fSAndroid Build Coastguard Worker {
1424*58e6ee5fSAndroid Build Coastguard Worker size_t size = 0;
1425*58e6ee5fSAndroid Build Coastguard Worker int r;
1426*58e6ee5fSAndroid Build Coastguard Worker
1427*58e6ee5fSAndroid Build Coastguard Worker do {
1428*58e6ee5fSAndroid Build Coastguard Worker r = read(fd, dst+size, len);
1429*58e6ee5fSAndroid Build Coastguard Worker if (r > 0) {
1430*58e6ee5fSAndroid Build Coastguard Worker size += r;
1431*58e6ee5fSAndroid Build Coastguard Worker len -= r;
1432*58e6ee5fSAndroid Build Coastguard Worker }
1433*58e6ee5fSAndroid Build Coastguard Worker } while (r > 0);
1434*58e6ee5fSAndroid Build Coastguard Worker }
1435*58e6ee5fSAndroid Build Coastguard Worker
add_functions(struct tep_handle * pevent,const char * file)1436*58e6ee5fSAndroid Build Coastguard Worker static void add_functions(struct tep_handle *pevent, const char *file)
1437*58e6ee5fSAndroid Build Coastguard Worker {
1438*58e6ee5fSAndroid Build Coastguard Worker struct stat st;
1439*58e6ee5fSAndroid Build Coastguard Worker char *buf;
1440*58e6ee5fSAndroid Build Coastguard Worker int ret;
1441*58e6ee5fSAndroid Build Coastguard Worker int fd;
1442*58e6ee5fSAndroid Build Coastguard Worker
1443*58e6ee5fSAndroid Build Coastguard Worker fd = open(file, O_RDONLY);
1444*58e6ee5fSAndroid Build Coastguard Worker if (fd < 0)
1445*58e6ee5fSAndroid Build Coastguard Worker die("Can't read file %s", file);
1446*58e6ee5fSAndroid Build Coastguard Worker
1447*58e6ee5fSAndroid Build Coastguard Worker ret = fstat(fd, &st);
1448*58e6ee5fSAndroid Build Coastguard Worker if (ret < 0)
1449*58e6ee5fSAndroid Build Coastguard Worker die("Can't stat file %s", file);
1450*58e6ee5fSAndroid Build Coastguard Worker
1451*58e6ee5fSAndroid Build Coastguard Worker buf = malloc(st.st_size + 1);
1452*58e6ee5fSAndroid Build Coastguard Worker if (!buf)
1453*58e6ee5fSAndroid Build Coastguard Worker die("Failed to allocate for function buffer");
1454*58e6ee5fSAndroid Build Coastguard Worker read_file_fd(fd, buf, st.st_size);
1455*58e6ee5fSAndroid Build Coastguard Worker buf[st.st_size] = '\0';
1456*58e6ee5fSAndroid Build Coastguard Worker close(fd);
1457*58e6ee5fSAndroid Build Coastguard Worker tep_parse_kallsyms(pevent, buf);
1458*58e6ee5fSAndroid Build Coastguard Worker free(buf);
1459*58e6ee5fSAndroid Build Coastguard Worker }
1460*58e6ee5fSAndroid Build Coastguard Worker
process_plugin_option(char * option)1461*58e6ee5fSAndroid Build Coastguard Worker static void process_plugin_option(char *option)
1462*58e6ee5fSAndroid Build Coastguard Worker {
1463*58e6ee5fSAndroid Build Coastguard Worker char *name = option;
1464*58e6ee5fSAndroid Build Coastguard Worker char *val = NULL;
1465*58e6ee5fSAndroid Build Coastguard Worker char *p;
1466*58e6ee5fSAndroid Build Coastguard Worker
1467*58e6ee5fSAndroid Build Coastguard Worker if ((p = strstr(name, "="))) {
1468*58e6ee5fSAndroid Build Coastguard Worker *p = '\0';
1469*58e6ee5fSAndroid Build Coastguard Worker val = p+1;
1470*58e6ee5fSAndroid Build Coastguard Worker }
1471*58e6ee5fSAndroid Build Coastguard Worker tep_plugin_add_option(name, val);
1472*58e6ee5fSAndroid Build Coastguard Worker }
1473*58e6ee5fSAndroid Build Coastguard Worker
set_event_flags(struct tep_handle * pevent,struct event_str * list,unsigned int flag)1474*58e6ee5fSAndroid Build Coastguard Worker static void set_event_flags(struct tep_handle *pevent, struct event_str *list,
1475*58e6ee5fSAndroid Build Coastguard Worker unsigned int flag)
1476*58e6ee5fSAndroid Build Coastguard Worker {
1477*58e6ee5fSAndroid Build Coastguard Worker struct tep_event **events;
1478*58e6ee5fSAndroid Build Coastguard Worker struct tep_event *event;
1479*58e6ee5fSAndroid Build Coastguard Worker struct event_str *str;
1480*58e6ee5fSAndroid Build Coastguard Worker regex_t regex;
1481*58e6ee5fSAndroid Build Coastguard Worker int ret;
1482*58e6ee5fSAndroid Build Coastguard Worker int i;
1483*58e6ee5fSAndroid Build Coastguard Worker
1484*58e6ee5fSAndroid Build Coastguard Worker if (!list)
1485*58e6ee5fSAndroid Build Coastguard Worker return;
1486*58e6ee5fSAndroid Build Coastguard Worker
1487*58e6ee5fSAndroid Build Coastguard Worker events = tep_list_events(pevent, 0);
1488*58e6ee5fSAndroid Build Coastguard Worker
1489*58e6ee5fSAndroid Build Coastguard Worker for (str = list; str; str = str->next) {
1490*58e6ee5fSAndroid Build Coastguard Worker char *match;
1491*58e6ee5fSAndroid Build Coastguard Worker
1492*58e6ee5fSAndroid Build Coastguard Worker match = malloc(strlen(str->event) + 3);
1493*58e6ee5fSAndroid Build Coastguard Worker if (!match)
1494*58e6ee5fSAndroid Build Coastguard Worker die("Failed to allocate for match string '%s'", str->event);
1495*58e6ee5fSAndroid Build Coastguard Worker sprintf(match, "^%s$", str->event);
1496*58e6ee5fSAndroid Build Coastguard Worker
1497*58e6ee5fSAndroid Build Coastguard Worker ret = regcomp(®ex, match, REG_ICASE|REG_NOSUB);
1498*58e6ee5fSAndroid Build Coastguard Worker if (ret < 0)
1499*58e6ee5fSAndroid Build Coastguard Worker die("Can't parse '%s'", str->event);
1500*58e6ee5fSAndroid Build Coastguard Worker free(match);
1501*58e6ee5fSAndroid Build Coastguard Worker for (i = 0; events[i]; i++) {
1502*58e6ee5fSAndroid Build Coastguard Worker event = events[i];
1503*58e6ee5fSAndroid Build Coastguard Worker if (!regexec(®ex, event->name, 0, NULL, 0) ||
1504*58e6ee5fSAndroid Build Coastguard Worker !regexec(®ex, event->system, 0, NULL, 0))
1505*58e6ee5fSAndroid Build Coastguard Worker event->flags |= flag;
1506*58e6ee5fSAndroid Build Coastguard Worker }
1507*58e6ee5fSAndroid Build Coastguard Worker }
1508*58e6ee5fSAndroid Build Coastguard Worker }
1509*58e6ee5fSAndroid Build Coastguard Worker
add_hook(const char * arg)1510*58e6ee5fSAndroid Build Coastguard Worker static void add_hook(const char *arg)
1511*58e6ee5fSAndroid Build Coastguard Worker {
1512*58e6ee5fSAndroid Build Coastguard Worker struct hook_list *hook;
1513*58e6ee5fSAndroid Build Coastguard Worker
1514*58e6ee5fSAndroid Build Coastguard Worker hook = tracecmd_create_event_hook(arg);
1515*58e6ee5fSAndroid Build Coastguard Worker
1516*58e6ee5fSAndroid Build Coastguard Worker hook->next = hooks;
1517*58e6ee5fSAndroid Build Coastguard Worker hooks = hook;
1518*58e6ee5fSAndroid Build Coastguard Worker if (!last_hook)
1519*58e6ee5fSAndroid Build Coastguard Worker last_hook = hook;
1520*58e6ee5fSAndroid Build Coastguard Worker }
1521*58e6ee5fSAndroid Build Coastguard Worker
1522*58e6ee5fSAndroid Build Coastguard Worker enum {
1523*58e6ee5fSAndroid Build Coastguard Worker OPT_verbose = 234,
1524*58e6ee5fSAndroid Build Coastguard Worker OPT_align_ts = 235,
1525*58e6ee5fSAndroid Build Coastguard Worker OPT_raw_ts = 236,
1526*58e6ee5fSAndroid Build Coastguard Worker OPT_version = 237,
1527*58e6ee5fSAndroid Build Coastguard Worker OPT_tscheck = 238,
1528*58e6ee5fSAndroid Build Coastguard Worker OPT_tsdiff = 239,
1529*58e6ee5fSAndroid Build Coastguard Worker OPT_ts2secs = 240,
1530*58e6ee5fSAndroid Build Coastguard Worker OPT_tsoffset = 241,
1531*58e6ee5fSAndroid Build Coastguard Worker OPT_bycomm = 242,
1532*58e6ee5fSAndroid Build Coastguard Worker OPT_debug = 243,
1533*58e6ee5fSAndroid Build Coastguard Worker OPT_uname = 244,
1534*58e6ee5fSAndroid Build Coastguard Worker OPT_profile = 245,
1535*58e6ee5fSAndroid Build Coastguard Worker OPT_event = 246,
1536*58e6ee5fSAndroid Build Coastguard Worker OPT_comm = 247,
1537*58e6ee5fSAndroid Build Coastguard Worker OPT_boundary = 248,
1538*58e6ee5fSAndroid Build Coastguard Worker OPT_stat = 249,
1539*58e6ee5fSAndroid Build Coastguard Worker OPT_pid = 250,
1540*58e6ee5fSAndroid Build Coastguard Worker OPT_nodate = 251,
1541*58e6ee5fSAndroid Build Coastguard Worker OPT_check_event_parsing = 252,
1542*58e6ee5fSAndroid Build Coastguard Worker OPT_kallsyms = 253,
1543*58e6ee5fSAndroid Build Coastguard Worker OPT_events = 254,
1544*58e6ee5fSAndroid Build Coastguard Worker OPT_cpu = 255,
1545*58e6ee5fSAndroid Build Coastguard Worker OPT_cpus = 256,
1546*58e6ee5fSAndroid Build Coastguard Worker };
1547*58e6ee5fSAndroid Build Coastguard Worker
trace_report(int argc,char ** argv)1548*58e6ee5fSAndroid Build Coastguard Worker void trace_report (int argc, char **argv)
1549*58e6ee5fSAndroid Build Coastguard Worker {
1550*58e6ee5fSAndroid Build Coastguard Worker struct tracecmd_input *handle;
1551*58e6ee5fSAndroid Build Coastguard Worker struct tep_handle *pevent;
1552*58e6ee5fSAndroid Build Coastguard Worker struct event_str *raw_events = NULL;
1553*58e6ee5fSAndroid Build Coastguard Worker struct event_str *nohandler_events = NULL;
1554*58e6ee5fSAndroid Build Coastguard Worker struct event_str **raw_ptr = &raw_events;
1555*58e6ee5fSAndroid Build Coastguard Worker struct event_str **nohandler_ptr = &nohandler_events;
1556*58e6ee5fSAndroid Build Coastguard Worker const char *functions = NULL;
1557*58e6ee5fSAndroid Build Coastguard Worker const char *print_event = NULL;
1558*58e6ee5fSAndroid Build Coastguard Worker struct input_files *inputs;
1559*58e6ee5fSAndroid Build Coastguard Worker struct handle_list *handles;
1560*58e6ee5fSAndroid Build Coastguard Worker enum output_type otype;
1561*58e6ee5fSAndroid Build Coastguard Worker long long tsoffset = 0;
1562*58e6ee5fSAndroid Build Coastguard Worker unsigned long long ts2secs = 0;
1563*58e6ee5fSAndroid Build Coastguard Worker unsigned long long ts2sc;
1564*58e6ee5fSAndroid Build Coastguard Worker int open_flags = 0;
1565*58e6ee5fSAndroid Build Coastguard Worker int show_stat = 0;
1566*58e6ee5fSAndroid Build Coastguard Worker int show_funcs = 0;
1567*58e6ee5fSAndroid Build Coastguard Worker int show_endian = 0;
1568*58e6ee5fSAndroid Build Coastguard Worker int show_page_size = 0;
1569*58e6ee5fSAndroid Build Coastguard Worker int show_printk = 0;
1570*58e6ee5fSAndroid Build Coastguard Worker int show_uname = 0;
1571*58e6ee5fSAndroid Build Coastguard Worker int show_version = 0;
1572*58e6ee5fSAndroid Build Coastguard Worker int show_events = 0;
1573*58e6ee5fSAndroid Build Coastguard Worker int show_cpus = 0;
1574*58e6ee5fSAndroid Build Coastguard Worker int print_events = 0;
1575*58e6ee5fSAndroid Build Coastguard Worker int nanosec = 0;
1576*58e6ee5fSAndroid Build Coastguard Worker int no_date = 0;
1577*58e6ee5fSAndroid Build Coastguard Worker int raw_ts = 0;
1578*58e6ee5fSAndroid Build Coastguard Worker int align_ts = 0;
1579*58e6ee5fSAndroid Build Coastguard Worker int global = 0;
1580*58e6ee5fSAndroid Build Coastguard Worker int neg = 0;
1581*58e6ee5fSAndroid Build Coastguard Worker int ret = 0;
1582*58e6ee5fSAndroid Build Coastguard Worker int check_event_parsing = 0;
1583*58e6ee5fSAndroid Build Coastguard Worker int c;
1584*58e6ee5fSAndroid Build Coastguard Worker
1585*58e6ee5fSAndroid Build Coastguard Worker list_head_init(&handle_list);
1586*58e6ee5fSAndroid Build Coastguard Worker list_head_init(&input_files);
1587*58e6ee5fSAndroid Build Coastguard Worker
1588*58e6ee5fSAndroid Build Coastguard Worker if (argc < 2)
1589*58e6ee5fSAndroid Build Coastguard Worker usage(argv);
1590*58e6ee5fSAndroid Build Coastguard Worker
1591*58e6ee5fSAndroid Build Coastguard Worker if (strcmp(argv[1], "report") != 0)
1592*58e6ee5fSAndroid Build Coastguard Worker usage(argv);
1593*58e6ee5fSAndroid Build Coastguard Worker
1594*58e6ee5fSAndroid Build Coastguard Worker signal(SIGINT, sig_end);
1595*58e6ee5fSAndroid Build Coastguard Worker
1596*58e6ee5fSAndroid Build Coastguard Worker for (;;) {
1597*58e6ee5fSAndroid Build Coastguard Worker int option_index = 0;
1598*58e6ee5fSAndroid Build Coastguard Worker static struct option long_options[] = {
1599*58e6ee5fSAndroid Build Coastguard Worker {"cpu", required_argument, NULL, OPT_cpu},
1600*58e6ee5fSAndroid Build Coastguard Worker {"cpus", no_argument, NULL, OPT_cpus},
1601*58e6ee5fSAndroid Build Coastguard Worker {"events", no_argument, NULL, OPT_events},
1602*58e6ee5fSAndroid Build Coastguard Worker {"event", required_argument, NULL, OPT_event},
1603*58e6ee5fSAndroid Build Coastguard Worker {"filter-test", no_argument, NULL, 'T'},
1604*58e6ee5fSAndroid Build Coastguard Worker {"kallsyms", required_argument, NULL, OPT_kallsyms},
1605*58e6ee5fSAndroid Build Coastguard Worker {"pid", required_argument, NULL, OPT_pid},
1606*58e6ee5fSAndroid Build Coastguard Worker {"comm", required_argument, NULL, OPT_comm},
1607*58e6ee5fSAndroid Build Coastguard Worker {"check-events", no_argument, NULL,
1608*58e6ee5fSAndroid Build Coastguard Worker OPT_check_event_parsing},
1609*58e6ee5fSAndroid Build Coastguard Worker {"nodate", no_argument, NULL, OPT_nodate},
1610*58e6ee5fSAndroid Build Coastguard Worker {"stat", no_argument, NULL, OPT_stat},
1611*58e6ee5fSAndroid Build Coastguard Worker {"boundary", no_argument, NULL, OPT_boundary},
1612*58e6ee5fSAndroid Build Coastguard Worker {"debug", no_argument, NULL, OPT_debug},
1613*58e6ee5fSAndroid Build Coastguard Worker {"profile", no_argument, NULL, OPT_profile},
1614*58e6ee5fSAndroid Build Coastguard Worker {"uname", no_argument, NULL, OPT_uname},
1615*58e6ee5fSAndroid Build Coastguard Worker {"version", no_argument, NULL, OPT_version},
1616*58e6ee5fSAndroid Build Coastguard Worker {"by-comm", no_argument, NULL, OPT_bycomm},
1617*58e6ee5fSAndroid Build Coastguard Worker {"ts-offset", required_argument, NULL, OPT_tsoffset},
1618*58e6ee5fSAndroid Build Coastguard Worker {"ts2secs", required_argument, NULL, OPT_ts2secs},
1619*58e6ee5fSAndroid Build Coastguard Worker {"ts-diff", no_argument, NULL, OPT_tsdiff},
1620*58e6ee5fSAndroid Build Coastguard Worker {"ts-check", no_argument, NULL, OPT_tscheck},
1621*58e6ee5fSAndroid Build Coastguard Worker {"raw-ts", no_argument, NULL, OPT_raw_ts},
1622*58e6ee5fSAndroid Build Coastguard Worker {"align-ts", no_argument, NULL, OPT_align_ts},
1623*58e6ee5fSAndroid Build Coastguard Worker {"verbose", optional_argument, NULL, OPT_verbose},
1624*58e6ee5fSAndroid Build Coastguard Worker {"help", no_argument, NULL, '?'},
1625*58e6ee5fSAndroid Build Coastguard Worker {NULL, 0, NULL, 0}
1626*58e6ee5fSAndroid Build Coastguard Worker };
1627*58e6ee5fSAndroid Build Coastguard Worker
1628*58e6ee5fSAndroid Build Coastguard Worker c = getopt_long (argc-1, argv+1, "+hSIi:H:feGpRr:tPNn:LlEwF:V::vTqO:",
1629*58e6ee5fSAndroid Build Coastguard Worker long_options, &option_index);
1630*58e6ee5fSAndroid Build Coastguard Worker if (c == -1)
1631*58e6ee5fSAndroid Build Coastguard Worker break;
1632*58e6ee5fSAndroid Build Coastguard Worker switch (c) {
1633*58e6ee5fSAndroid Build Coastguard Worker case 'h':
1634*58e6ee5fSAndroid Build Coastguard Worker usage(argv);
1635*58e6ee5fSAndroid Build Coastguard Worker break;
1636*58e6ee5fSAndroid Build Coastguard Worker case 'i':
1637*58e6ee5fSAndroid Build Coastguard Worker if (input_file) {
1638*58e6ee5fSAndroid Build Coastguard Worker if (!multi_inputs) {
1639*58e6ee5fSAndroid Build Coastguard Worker add_input(input_file);
1640*58e6ee5fSAndroid Build Coastguard Worker if (tsoffset)
1641*58e6ee5fSAndroid Build Coastguard Worker last_input_file->tsoffset = tsoffset;
1642*58e6ee5fSAndroid Build Coastguard Worker }
1643*58e6ee5fSAndroid Build Coastguard Worker multi_inputs++;
1644*58e6ee5fSAndroid Build Coastguard Worker add_input(optarg);
1645*58e6ee5fSAndroid Build Coastguard Worker } else
1646*58e6ee5fSAndroid Build Coastguard Worker input_file = optarg;
1647*58e6ee5fSAndroid Build Coastguard Worker break;
1648*58e6ee5fSAndroid Build Coastguard Worker case 'F':
1649*58e6ee5fSAndroid Build Coastguard Worker add_filter(optarg, neg);
1650*58e6ee5fSAndroid Build Coastguard Worker break;
1651*58e6ee5fSAndroid Build Coastguard Worker case 'H':
1652*58e6ee5fSAndroid Build Coastguard Worker add_hook(optarg);
1653*58e6ee5fSAndroid Build Coastguard Worker break;
1654*58e6ee5fSAndroid Build Coastguard Worker case 'T':
1655*58e6ee5fSAndroid Build Coastguard Worker test_filters_mode = 1;
1656*58e6ee5fSAndroid Build Coastguard Worker break;
1657*58e6ee5fSAndroid Build Coastguard Worker case 'f':
1658*58e6ee5fSAndroid Build Coastguard Worker show_funcs = 1;
1659*58e6ee5fSAndroid Build Coastguard Worker break;
1660*58e6ee5fSAndroid Build Coastguard Worker case 'I':
1661*58e6ee5fSAndroid Build Coastguard Worker no_irqs = 1;
1662*58e6ee5fSAndroid Build Coastguard Worker break;
1663*58e6ee5fSAndroid Build Coastguard Worker case 'S':
1664*58e6ee5fSAndroid Build Coastguard Worker no_softirqs = 1;
1665*58e6ee5fSAndroid Build Coastguard Worker break;
1666*58e6ee5fSAndroid Build Coastguard Worker case 'P':
1667*58e6ee5fSAndroid Build Coastguard Worker show_printk = 1;
1668*58e6ee5fSAndroid Build Coastguard Worker break;
1669*58e6ee5fSAndroid Build Coastguard Worker case 'L':
1670*58e6ee5fSAndroid Build Coastguard Worker open_flags |= TRACECMD_FL_LOAD_NO_SYSTEM_PLUGINS;
1671*58e6ee5fSAndroid Build Coastguard Worker break;
1672*58e6ee5fSAndroid Build Coastguard Worker case 'N':
1673*58e6ee5fSAndroid Build Coastguard Worker open_flags |= TRACECMD_FL_LOAD_NO_PLUGINS;
1674*58e6ee5fSAndroid Build Coastguard Worker break;
1675*58e6ee5fSAndroid Build Coastguard Worker case 'n':
1676*58e6ee5fSAndroid Build Coastguard Worker *nohandler_ptr = malloc(sizeof(struct event_str));
1677*58e6ee5fSAndroid Build Coastguard Worker if (!*nohandler_ptr)
1678*58e6ee5fSAndroid Build Coastguard Worker die("Failed to allocate for '-n %s'", optarg);
1679*58e6ee5fSAndroid Build Coastguard Worker (*nohandler_ptr)->event = optarg;
1680*58e6ee5fSAndroid Build Coastguard Worker (*nohandler_ptr)->next = NULL;
1681*58e6ee5fSAndroid Build Coastguard Worker nohandler_ptr = &(*nohandler_ptr)->next;
1682*58e6ee5fSAndroid Build Coastguard Worker break;
1683*58e6ee5fSAndroid Build Coastguard Worker case 'e':
1684*58e6ee5fSAndroid Build Coastguard Worker show_endian = 1;
1685*58e6ee5fSAndroid Build Coastguard Worker break;
1686*58e6ee5fSAndroid Build Coastguard Worker case 'p':
1687*58e6ee5fSAndroid Build Coastguard Worker show_page_size = 1;
1688*58e6ee5fSAndroid Build Coastguard Worker break;
1689*58e6ee5fSAndroid Build Coastguard Worker case 'E':
1690*58e6ee5fSAndroid Build Coastguard Worker show_events = 1;
1691*58e6ee5fSAndroid Build Coastguard Worker break;
1692*58e6ee5fSAndroid Build Coastguard Worker case 'G':
1693*58e6ee5fSAndroid Build Coastguard Worker global = 1;
1694*58e6ee5fSAndroid Build Coastguard Worker break;
1695*58e6ee5fSAndroid Build Coastguard Worker case 'R':
1696*58e6ee5fSAndroid Build Coastguard Worker raw_format = true;
1697*58e6ee5fSAndroid Build Coastguard Worker break;
1698*58e6ee5fSAndroid Build Coastguard Worker case 'r':
1699*58e6ee5fSAndroid Build Coastguard Worker *raw_ptr = malloc(sizeof(struct event_str));
1700*58e6ee5fSAndroid Build Coastguard Worker if (!*raw_ptr)
1701*58e6ee5fSAndroid Build Coastguard Worker die("Failed to allocate '-r %s'", optarg);
1702*58e6ee5fSAndroid Build Coastguard Worker (*raw_ptr)->event = optarg;
1703*58e6ee5fSAndroid Build Coastguard Worker (*raw_ptr)->next = NULL;
1704*58e6ee5fSAndroid Build Coastguard Worker raw_ptr = &(*raw_ptr)->next;
1705*58e6ee5fSAndroid Build Coastguard Worker break;
1706*58e6ee5fSAndroid Build Coastguard Worker case 't':
1707*58e6ee5fSAndroid Build Coastguard Worker nanosec = 1;
1708*58e6ee5fSAndroid Build Coastguard Worker break;
1709*58e6ee5fSAndroid Build Coastguard Worker case 'w':
1710*58e6ee5fSAndroid Build Coastguard Worker show_wakeup = 1;
1711*58e6ee5fSAndroid Build Coastguard Worker break;
1712*58e6ee5fSAndroid Build Coastguard Worker case 'l':
1713*58e6ee5fSAndroid Build Coastguard Worker latency_format = 1;
1714*58e6ee5fSAndroid Build Coastguard Worker break;
1715*58e6ee5fSAndroid Build Coastguard Worker case 'O':
1716*58e6ee5fSAndroid Build Coastguard Worker process_plugin_option(optarg);
1717*58e6ee5fSAndroid Build Coastguard Worker break;
1718*58e6ee5fSAndroid Build Coastguard Worker case 'v':
1719*58e6ee5fSAndroid Build Coastguard Worker if (neg)
1720*58e6ee5fSAndroid Build Coastguard Worker die("Only 1 -v can be used");
1721*58e6ee5fSAndroid Build Coastguard Worker neg = 1;
1722*58e6ee5fSAndroid Build Coastguard Worker break;
1723*58e6ee5fSAndroid Build Coastguard Worker case 'q':
1724*58e6ee5fSAndroid Build Coastguard Worker silence_warnings = 1;
1725*58e6ee5fSAndroid Build Coastguard Worker tracecmd_set_loglevel(TEP_LOG_NONE);
1726*58e6ee5fSAndroid Build Coastguard Worker break;
1727*58e6ee5fSAndroid Build Coastguard Worker case OPT_cpu:
1728*58e6ee5fSAndroid Build Coastguard Worker parse_cpulist(optarg);
1729*58e6ee5fSAndroid Build Coastguard Worker break;
1730*58e6ee5fSAndroid Build Coastguard Worker case OPT_cpus:
1731*58e6ee5fSAndroid Build Coastguard Worker show_cpus = 1;
1732*58e6ee5fSAndroid Build Coastguard Worker break;
1733*58e6ee5fSAndroid Build Coastguard Worker case OPT_events:
1734*58e6ee5fSAndroid Build Coastguard Worker print_events = 1;
1735*58e6ee5fSAndroid Build Coastguard Worker break;
1736*58e6ee5fSAndroid Build Coastguard Worker case OPT_event:
1737*58e6ee5fSAndroid Build Coastguard Worker print_event = optarg;
1738*58e6ee5fSAndroid Build Coastguard Worker break;
1739*58e6ee5fSAndroid Build Coastguard Worker case OPT_kallsyms:
1740*58e6ee5fSAndroid Build Coastguard Worker functions = optarg;
1741*58e6ee5fSAndroid Build Coastguard Worker break;
1742*58e6ee5fSAndroid Build Coastguard Worker case OPT_pid:
1743*58e6ee5fSAndroid Build Coastguard Worker add_pid_filter(optarg);
1744*58e6ee5fSAndroid Build Coastguard Worker break;
1745*58e6ee5fSAndroid Build Coastguard Worker case OPT_comm:
1746*58e6ee5fSAndroid Build Coastguard Worker add_comm_filter(optarg);
1747*58e6ee5fSAndroid Build Coastguard Worker break;
1748*58e6ee5fSAndroid Build Coastguard Worker case OPT_check_event_parsing:
1749*58e6ee5fSAndroid Build Coastguard Worker check_event_parsing = 1;
1750*58e6ee5fSAndroid Build Coastguard Worker break;
1751*58e6ee5fSAndroid Build Coastguard Worker case OPT_nodate:
1752*58e6ee5fSAndroid Build Coastguard Worker no_date = 1;
1753*58e6ee5fSAndroid Build Coastguard Worker break;
1754*58e6ee5fSAndroid Build Coastguard Worker case OPT_stat:
1755*58e6ee5fSAndroid Build Coastguard Worker show_stat = 1;
1756*58e6ee5fSAndroid Build Coastguard Worker break;
1757*58e6ee5fSAndroid Build Coastguard Worker case OPT_boundary:
1758*58e6ee5fSAndroid Build Coastguard Worker /* Debug to look at buffer breaks */
1759*58e6ee5fSAndroid Build Coastguard Worker buffer_breaks = 1;
1760*58e6ee5fSAndroid Build Coastguard Worker break;
1761*58e6ee5fSAndroid Build Coastguard Worker case OPT_debug:
1762*58e6ee5fSAndroid Build Coastguard Worker buffer_breaks = 1;
1763*58e6ee5fSAndroid Build Coastguard Worker tracecmd_set_debug(true);
1764*58e6ee5fSAndroid Build Coastguard Worker break;
1765*58e6ee5fSAndroid Build Coastguard Worker case OPT_profile:
1766*58e6ee5fSAndroid Build Coastguard Worker profile = 1;
1767*58e6ee5fSAndroid Build Coastguard Worker break;
1768*58e6ee5fSAndroid Build Coastguard Worker case OPT_uname:
1769*58e6ee5fSAndroid Build Coastguard Worker show_uname = 1;
1770*58e6ee5fSAndroid Build Coastguard Worker break;
1771*58e6ee5fSAndroid Build Coastguard Worker case OPT_version:
1772*58e6ee5fSAndroid Build Coastguard Worker show_version = 1;
1773*58e6ee5fSAndroid Build Coastguard Worker break;
1774*58e6ee5fSAndroid Build Coastguard Worker case OPT_bycomm:
1775*58e6ee5fSAndroid Build Coastguard Worker trace_profile_set_merge_like_comms();
1776*58e6ee5fSAndroid Build Coastguard Worker break;
1777*58e6ee5fSAndroid Build Coastguard Worker case OPT_ts2secs:
1778*58e6ee5fSAndroid Build Coastguard Worker ts2sc = atoll(optarg);
1779*58e6ee5fSAndroid Build Coastguard Worker if (multi_inputs)
1780*58e6ee5fSAndroid Build Coastguard Worker last_input_file->ts2secs = ts2sc;
1781*58e6ee5fSAndroid Build Coastguard Worker else
1782*58e6ee5fSAndroid Build Coastguard Worker ts2secs = ts2sc;
1783*58e6ee5fSAndroid Build Coastguard Worker break;
1784*58e6ee5fSAndroid Build Coastguard Worker case OPT_tsoffset:
1785*58e6ee5fSAndroid Build Coastguard Worker tsoffset = atoll(optarg);
1786*58e6ee5fSAndroid Build Coastguard Worker if (multi_inputs)
1787*58e6ee5fSAndroid Build Coastguard Worker last_input_file->tsoffset = tsoffset;
1788*58e6ee5fSAndroid Build Coastguard Worker if (!input_file)
1789*58e6ee5fSAndroid Build Coastguard Worker die("--ts-offset must come after -i");
1790*58e6ee5fSAndroid Build Coastguard Worker break;
1791*58e6ee5fSAndroid Build Coastguard Worker case OPT_tsdiff:
1792*58e6ee5fSAndroid Build Coastguard Worker tsdiff = 1;
1793*58e6ee5fSAndroid Build Coastguard Worker break;
1794*58e6ee5fSAndroid Build Coastguard Worker case OPT_tscheck:
1795*58e6ee5fSAndroid Build Coastguard Worker tscheck = 1;
1796*58e6ee5fSAndroid Build Coastguard Worker break;
1797*58e6ee5fSAndroid Build Coastguard Worker case OPT_raw_ts:
1798*58e6ee5fSAndroid Build Coastguard Worker raw_ts = 1;
1799*58e6ee5fSAndroid Build Coastguard Worker break;
1800*58e6ee5fSAndroid Build Coastguard Worker case OPT_align_ts:
1801*58e6ee5fSAndroid Build Coastguard Worker align_ts = 1;
1802*58e6ee5fSAndroid Build Coastguard Worker break;
1803*58e6ee5fSAndroid Build Coastguard Worker case 'V':
1804*58e6ee5fSAndroid Build Coastguard Worker case OPT_verbose:
1805*58e6ee5fSAndroid Build Coastguard Worker show_status = 1;
1806*58e6ee5fSAndroid Build Coastguard Worker if (trace_set_verbose(optarg) < 0)
1807*58e6ee5fSAndroid Build Coastguard Worker die("invalid verbose level %s", optarg);
1808*58e6ee5fSAndroid Build Coastguard Worker break;
1809*58e6ee5fSAndroid Build Coastguard Worker default:
1810*58e6ee5fSAndroid Build Coastguard Worker usage(argv);
1811*58e6ee5fSAndroid Build Coastguard Worker }
1812*58e6ee5fSAndroid Build Coastguard Worker }
1813*58e6ee5fSAndroid Build Coastguard Worker
1814*58e6ee5fSAndroid Build Coastguard Worker if ((argc - optind) >= 2) {
1815*58e6ee5fSAndroid Build Coastguard Worker if (input_file)
1816*58e6ee5fSAndroid Build Coastguard Worker usage(argv);
1817*58e6ee5fSAndroid Build Coastguard Worker input_file = argv[optind + 1];
1818*58e6ee5fSAndroid Build Coastguard Worker }
1819*58e6ee5fSAndroid Build Coastguard Worker
1820*58e6ee5fSAndroid Build Coastguard Worker if (!input_file)
1821*58e6ee5fSAndroid Build Coastguard Worker input_file = default_input_file;
1822*58e6ee5fSAndroid Build Coastguard Worker
1823*58e6ee5fSAndroid Build Coastguard Worker if (!multi_inputs) {
1824*58e6ee5fSAndroid Build Coastguard Worker add_input(input_file);
1825*58e6ee5fSAndroid Build Coastguard Worker if (tsoffset)
1826*58e6ee5fSAndroid Build Coastguard Worker last_input_file->tsoffset = tsoffset;
1827*58e6ee5fSAndroid Build Coastguard Worker } else if (show_wakeup)
1828*58e6ee5fSAndroid Build Coastguard Worker die("Wakeup tracing can only be done on a single input file");
1829*58e6ee5fSAndroid Build Coastguard Worker
1830*58e6ee5fSAndroid Build Coastguard Worker list_for_each_entry(inputs, &input_files, list) {
1831*58e6ee5fSAndroid Build Coastguard Worker handle = read_trace_header(inputs->file, open_flags);
1832*58e6ee5fSAndroid Build Coastguard Worker if (!handle)
1833*58e6ee5fSAndroid Build Coastguard Worker die("error reading header for %s", inputs->file);
1834*58e6ee5fSAndroid Build Coastguard Worker
1835*58e6ee5fSAndroid Build Coastguard Worker /* If used with instances, top instance will have no tag */
1836*58e6ee5fSAndroid Build Coastguard Worker add_handle(handle, multi_inputs ? inputs->file : NULL);
1837*58e6ee5fSAndroid Build Coastguard Worker
1838*58e6ee5fSAndroid Build Coastguard Worker if (no_date)
1839*58e6ee5fSAndroid Build Coastguard Worker tracecmd_set_flag(handle, TRACECMD_FL_IGNORE_DATE);
1840*58e6ee5fSAndroid Build Coastguard Worker if (raw_ts)
1841*58e6ee5fSAndroid Build Coastguard Worker tracecmd_set_flag(handle, TRACECMD_FL_RAW_TS);
1842*58e6ee5fSAndroid Build Coastguard Worker page_size = tracecmd_page_size(handle);
1843*58e6ee5fSAndroid Build Coastguard Worker
1844*58e6ee5fSAndroid Build Coastguard Worker if (show_page_size) {
1845*58e6ee5fSAndroid Build Coastguard Worker printf("file page size is %d, and host page size is %d\n",
1846*58e6ee5fSAndroid Build Coastguard Worker page_size,
1847*58e6ee5fSAndroid Build Coastguard Worker getpagesize());
1848*58e6ee5fSAndroid Build Coastguard Worker return;
1849*58e6ee5fSAndroid Build Coastguard Worker }
1850*58e6ee5fSAndroid Build Coastguard Worker
1851*58e6ee5fSAndroid Build Coastguard Worker if (inputs->tsoffset)
1852*58e6ee5fSAndroid Build Coastguard Worker tracecmd_set_ts_offset(handle, inputs->tsoffset);
1853*58e6ee5fSAndroid Build Coastguard Worker
1854*58e6ee5fSAndroid Build Coastguard Worker if (inputs->ts2secs)
1855*58e6ee5fSAndroid Build Coastguard Worker tracecmd_set_ts2secs(handle, inputs->ts2secs);
1856*58e6ee5fSAndroid Build Coastguard Worker else if (ts2secs)
1857*58e6ee5fSAndroid Build Coastguard Worker tracecmd_set_ts2secs(handle, ts2secs);
1858*58e6ee5fSAndroid Build Coastguard Worker
1859*58e6ee5fSAndroid Build Coastguard Worker pevent = tracecmd_get_tep(handle);
1860*58e6ee5fSAndroid Build Coastguard Worker
1861*58e6ee5fSAndroid Build Coastguard Worker if (nanosec)
1862*58e6ee5fSAndroid Build Coastguard Worker tep_set_flag(pevent, TEP_NSEC_OUTPUT);
1863*58e6ee5fSAndroid Build Coastguard Worker
1864*58e6ee5fSAndroid Build Coastguard Worker if (raw_format)
1865*58e6ee5fSAndroid Build Coastguard Worker format_type = TEP_PRINT_INFO_RAW;
1866*58e6ee5fSAndroid Build Coastguard Worker
1867*58e6ee5fSAndroid Build Coastguard Worker if (test_filters_mode)
1868*58e6ee5fSAndroid Build Coastguard Worker tep_set_test_filters(pevent, 1);
1869*58e6ee5fSAndroid Build Coastguard Worker
1870*58e6ee5fSAndroid Build Coastguard Worker if (functions)
1871*58e6ee5fSAndroid Build Coastguard Worker add_functions(pevent, functions);
1872*58e6ee5fSAndroid Build Coastguard Worker
1873*58e6ee5fSAndroid Build Coastguard Worker if (show_endian) {
1874*58e6ee5fSAndroid Build Coastguard Worker printf("file is %s endian and host is %s endian\n",
1875*58e6ee5fSAndroid Build Coastguard Worker tep_is_file_bigendian(pevent) ? "big" : "little",
1876*58e6ee5fSAndroid Build Coastguard Worker tep_is_local_bigendian(pevent) ? "big" : "little");
1877*58e6ee5fSAndroid Build Coastguard Worker return;
1878*58e6ee5fSAndroid Build Coastguard Worker }
1879*58e6ee5fSAndroid Build Coastguard Worker
1880*58e6ee5fSAndroid Build Coastguard Worker if (print_events) {
1881*58e6ee5fSAndroid Build Coastguard Worker tracecmd_print_events(handle, NULL);
1882*58e6ee5fSAndroid Build Coastguard Worker return;
1883*58e6ee5fSAndroid Build Coastguard Worker }
1884*58e6ee5fSAndroid Build Coastguard Worker
1885*58e6ee5fSAndroid Build Coastguard Worker if (print_event) {
1886*58e6ee5fSAndroid Build Coastguard Worker tracecmd_print_events(handle, print_event);
1887*58e6ee5fSAndroid Build Coastguard Worker return;
1888*58e6ee5fSAndroid Build Coastguard Worker }
1889*58e6ee5fSAndroid Build Coastguard Worker
1890*58e6ee5fSAndroid Build Coastguard Worker ret = tracecmd_read_headers(handle, 0);
1891*58e6ee5fSAndroid Build Coastguard Worker if (check_event_parsing) {
1892*58e6ee5fSAndroid Build Coastguard Worker if (ret || tracecmd_get_parsing_failures(handle))
1893*58e6ee5fSAndroid Build Coastguard Worker exit(EINVAL);
1894*58e6ee5fSAndroid Build Coastguard Worker else
1895*58e6ee5fSAndroid Build Coastguard Worker exit(0);
1896*58e6ee5fSAndroid Build Coastguard Worker } else {
1897*58e6ee5fSAndroid Build Coastguard Worker if (ret)
1898*58e6ee5fSAndroid Build Coastguard Worker return;
1899*58e6ee5fSAndroid Build Coastguard Worker }
1900*58e6ee5fSAndroid Build Coastguard Worker
1901*58e6ee5fSAndroid Build Coastguard Worker if (show_funcs) {
1902*58e6ee5fSAndroid Build Coastguard Worker tep_print_funcs(pevent);
1903*58e6ee5fSAndroid Build Coastguard Worker return;
1904*58e6ee5fSAndroid Build Coastguard Worker }
1905*58e6ee5fSAndroid Build Coastguard Worker if (show_printk) {
1906*58e6ee5fSAndroid Build Coastguard Worker tep_print_printk(pevent);
1907*58e6ee5fSAndroid Build Coastguard Worker return;
1908*58e6ee5fSAndroid Build Coastguard Worker }
1909*58e6ee5fSAndroid Build Coastguard Worker
1910*58e6ee5fSAndroid Build Coastguard Worker if (show_events) {
1911*58e6ee5fSAndroid Build Coastguard Worker struct tep_event **events;
1912*58e6ee5fSAndroid Build Coastguard Worker struct tep_event *event;
1913*58e6ee5fSAndroid Build Coastguard Worker int i;
1914*58e6ee5fSAndroid Build Coastguard Worker
1915*58e6ee5fSAndroid Build Coastguard Worker events = tep_list_events(pevent, TEP_EVENT_SORT_SYSTEM);
1916*58e6ee5fSAndroid Build Coastguard Worker for (i = 0; events[i]; i++) {
1917*58e6ee5fSAndroid Build Coastguard Worker event = events[i];
1918*58e6ee5fSAndroid Build Coastguard Worker if (event->system)
1919*58e6ee5fSAndroid Build Coastguard Worker printf("%s:", event->system);
1920*58e6ee5fSAndroid Build Coastguard Worker printf("%s\n", event->name);
1921*58e6ee5fSAndroid Build Coastguard Worker }
1922*58e6ee5fSAndroid Build Coastguard Worker return;
1923*58e6ee5fSAndroid Build Coastguard Worker }
1924*58e6ee5fSAndroid Build Coastguard Worker
1925*58e6ee5fSAndroid Build Coastguard Worker if (show_cpus) {
1926*58e6ee5fSAndroid Build Coastguard Worker int cpus;
1927*58e6ee5fSAndroid Build Coastguard Worker int ret;
1928*58e6ee5fSAndroid Build Coastguard Worker int i;
1929*58e6ee5fSAndroid Build Coastguard Worker
1930*58e6ee5fSAndroid Build Coastguard Worker if (!tracecmd_is_buffer_instance(handle)) {
1931*58e6ee5fSAndroid Build Coastguard Worker ret = tracecmd_init_data(handle);
1932*58e6ee5fSAndroid Build Coastguard Worker if (ret < 0)
1933*58e6ee5fSAndroid Build Coastguard Worker die("failed to init data");
1934*58e6ee5fSAndroid Build Coastguard Worker }
1935*58e6ee5fSAndroid Build Coastguard Worker cpus = tracecmd_cpus(handle);
1936*58e6ee5fSAndroid Build Coastguard Worker printf("List of CPUs in %s with data:\n", inputs->file);
1937*58e6ee5fSAndroid Build Coastguard Worker for (i = 0; i < cpus; i++) {
1938*58e6ee5fSAndroid Build Coastguard Worker if (tracecmd_read_cpu_first(handle, i))
1939*58e6ee5fSAndroid Build Coastguard Worker printf(" %d\n", i);
1940*58e6ee5fSAndroid Build Coastguard Worker }
1941*58e6ee5fSAndroid Build Coastguard Worker continue;
1942*58e6ee5fSAndroid Build Coastguard Worker }
1943*58e6ee5fSAndroid Build Coastguard Worker
1944*58e6ee5fSAndroid Build Coastguard Worker set_event_flags(pevent, nohandler_events, TEP_EVENT_FL_NOHANDLE);
1945*58e6ee5fSAndroid Build Coastguard Worker set_event_flags(pevent, raw_events, TEP_EVENT_FL_PRINTRAW);
1946*58e6ee5fSAndroid Build Coastguard Worker }
1947*58e6ee5fSAndroid Build Coastguard Worker
1948*58e6ee5fSAndroid Build Coastguard Worker if (show_cpus)
1949*58e6ee5fSAndroid Build Coastguard Worker return;
1950*58e6ee5fSAndroid Build Coastguard Worker
1951*58e6ee5fSAndroid Build Coastguard Worker otype = OUTPUT_NORMAL;
1952*58e6ee5fSAndroid Build Coastguard Worker
1953*58e6ee5fSAndroid Build Coastguard Worker if (tracecmd_get_flags(handle) & TRACECMD_FL_RAW_TS) {
1954*58e6ee5fSAndroid Build Coastguard Worker tep_func_repeat_format = "%d";
1955*58e6ee5fSAndroid Build Coastguard Worker } else if (tracecmd_get_flags(handle) & TRACECMD_FL_IN_USECS) {
1956*58e6ee5fSAndroid Build Coastguard Worker if (tep_test_flag(tracecmd_get_tep(handle), TEP_NSEC_OUTPUT))
1957*58e6ee5fSAndroid Build Coastguard Worker tep_func_repeat_format = "%9.1d";
1958*58e6ee5fSAndroid Build Coastguard Worker else
1959*58e6ee5fSAndroid Build Coastguard Worker tep_func_repeat_format = "%6.1000d";
1960*58e6ee5fSAndroid Build Coastguard Worker } else {
1961*58e6ee5fSAndroid Build Coastguard Worker tep_func_repeat_format = "%12d";
1962*58e6ee5fSAndroid Build Coastguard Worker }
1963*58e6ee5fSAndroid Build Coastguard Worker
1964*58e6ee5fSAndroid Build Coastguard Worker
1965*58e6ee5fSAndroid Build Coastguard Worker if (show_stat)
1966*58e6ee5fSAndroid Build Coastguard Worker otype = OUTPUT_STAT_ONLY;
1967*58e6ee5fSAndroid Build Coastguard Worker /* yeah yeah, uname overrides stat */
1968*58e6ee5fSAndroid Build Coastguard Worker if (show_uname)
1969*58e6ee5fSAndroid Build Coastguard Worker otype = OUTPUT_UNAME_ONLY;
1970*58e6ee5fSAndroid Build Coastguard Worker /* and version overrides uname! */
1971*58e6ee5fSAndroid Build Coastguard Worker if (show_version)
1972*58e6ee5fSAndroid Build Coastguard Worker otype = OUTPUT_VERSION_ONLY;
1973*58e6ee5fSAndroid Build Coastguard Worker read_data_info(&handle_list, otype, global, align_ts);
1974*58e6ee5fSAndroid Build Coastguard Worker
1975*58e6ee5fSAndroid Build Coastguard Worker list_for_each_entry(handles, &handle_list, list) {
1976*58e6ee5fSAndroid Build Coastguard Worker tracecmd_close(handles->handle);
1977*58e6ee5fSAndroid Build Coastguard Worker }
1978*58e6ee5fSAndroid Build Coastguard Worker free_handles();
1979*58e6ee5fSAndroid Build Coastguard Worker free_inputs();
1980*58e6ee5fSAndroid Build Coastguard Worker
1981*58e6ee5fSAndroid Build Coastguard Worker finish_wakeup();
1982*58e6ee5fSAndroid Build Coastguard Worker
1983*58e6ee5fSAndroid Build Coastguard Worker return;
1984*58e6ee5fSAndroid Build Coastguard Worker }
1985