xref: /aosp_15_r20/external/trace-cmd/tracecmd/trace-mem.c (revision 58e6ee5f017f6a8912852c892d18457e4bafb554)
1*58e6ee5fSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0
2*58e6ee5fSAndroid Build Coastguard Worker /*
3*58e6ee5fSAndroid Build Coastguard Worker  * Copyright (C) 2013 Red Hat Inc, Steven Rostedt <[email protected]>
4*58e6ee5fSAndroid Build Coastguard Worker  *
5*58e6ee5fSAndroid Build Coastguard Worker  *
6*58e6ee5fSAndroid Build Coastguard Worker  * This code was inspired by Ezequiel Garcia's trace_analyze program:
7*58e6ee5fSAndroid Build Coastguard Worker  *   git://github.com/ezequielgarcia/trace_analyze.git
8*58e6ee5fSAndroid Build Coastguard Worker  *
9*58e6ee5fSAndroid Build Coastguard Worker  * Unfortuntately, I hate working with Python, and I also had trouble
10*58e6ee5fSAndroid Build Coastguard Worker  * getting it to work, as I had an old python on my Fedora 13, and it
11*58e6ee5fSAndroid Build Coastguard Worker  * was written for the newer version. I decided to do some of it here
12*58e6ee5fSAndroid Build Coastguard Worker  * in C.
13*58e6ee5fSAndroid Build Coastguard Worker  */
14*58e6ee5fSAndroid Build Coastguard Worker #define _LARGEFILE64_SOURCE
15*58e6ee5fSAndroid Build Coastguard Worker #include <dirent.h>
16*58e6ee5fSAndroid Build Coastguard Worker #include <stdio.h>
17*58e6ee5fSAndroid Build Coastguard Worker #include <stdlib.h>
18*58e6ee5fSAndroid Build Coastguard Worker #include <string.h>
19*58e6ee5fSAndroid Build Coastguard Worker #include <getopt.h>
20*58e6ee5fSAndroid Build Coastguard Worker #include <signal.h>
21*58e6ee5fSAndroid Build Coastguard Worker 
22*58e6ee5fSAndroid Build Coastguard Worker #include "trace-local.h"
23*58e6ee5fSAndroid Build Coastguard Worker #include "trace-hash-local.h"
24*58e6ee5fSAndroid Build Coastguard Worker #include "list.h"
25*58e6ee5fSAndroid Build Coastguard Worker 
26*58e6ee5fSAndroid Build Coastguard Worker static int kmalloc_type;
27*58e6ee5fSAndroid Build Coastguard Worker static int kmalloc_node_type;
28*58e6ee5fSAndroid Build Coastguard Worker static int kfree_type;
29*58e6ee5fSAndroid Build Coastguard Worker static int kmem_cache_alloc_type;
30*58e6ee5fSAndroid Build Coastguard Worker static int kmem_cache_alloc_node_type;
31*58e6ee5fSAndroid Build Coastguard Worker static int kmem_cache_free_type;
32*58e6ee5fSAndroid Build Coastguard Worker 
33*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *common_type_mem;
34*58e6ee5fSAndroid Build Coastguard Worker 
35*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmalloc_callsite_field;
36*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmalloc_bytes_req_field;
37*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmalloc_bytes_alloc_field;
38*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmalloc_ptr_field;
39*58e6ee5fSAndroid Build Coastguard Worker 
40*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmalloc_node_callsite_field;
41*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmalloc_node_bytes_req_field;
42*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmalloc_node_bytes_alloc_field;
43*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmalloc_node_ptr_field;
44*58e6ee5fSAndroid Build Coastguard Worker 
45*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kfree_ptr_field;
46*58e6ee5fSAndroid Build Coastguard Worker 
47*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmem_cache_callsite_field;
48*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmem_cache_bytes_req_field;
49*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmem_cache_bytes_alloc_field;
50*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmem_cache_ptr_field;
51*58e6ee5fSAndroid Build Coastguard Worker 
52*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmem_cache_node_callsite_field;
53*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmem_cache_node_bytes_req_field;
54*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmem_cache_node_bytes_alloc_field;
55*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmem_cache_node_ptr_field;
56*58e6ee5fSAndroid Build Coastguard Worker 
57*58e6ee5fSAndroid Build Coastguard Worker static struct tep_format_field *kmem_cache_free_ptr_field;
58*58e6ee5fSAndroid Build Coastguard Worker 
zalloc(size_t size)59*58e6ee5fSAndroid Build Coastguard Worker static void *zalloc(size_t size)
60*58e6ee5fSAndroid Build Coastguard Worker {
61*58e6ee5fSAndroid Build Coastguard Worker 	return calloc(1, size);
62*58e6ee5fSAndroid Build Coastguard Worker }
63*58e6ee5fSAndroid Build Coastguard Worker 
64*58e6ee5fSAndroid Build Coastguard Worker static struct tep_event *
update_event(struct tep_handle * pevent,const char * sys,const char * name,int * id)65*58e6ee5fSAndroid Build Coastguard Worker update_event(struct tep_handle *pevent,
66*58e6ee5fSAndroid Build Coastguard Worker 	     const char *sys, const char *name, int *id)
67*58e6ee5fSAndroid Build Coastguard Worker {
68*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_event *event;
69*58e6ee5fSAndroid Build Coastguard Worker 
70*58e6ee5fSAndroid Build Coastguard Worker 	event = tep_find_event_by_name(pevent, sys, name);
71*58e6ee5fSAndroid Build Coastguard Worker 	if (!event)
72*58e6ee5fSAndroid Build Coastguard Worker 		return NULL;
73*58e6ee5fSAndroid Build Coastguard Worker 
74*58e6ee5fSAndroid Build Coastguard Worker 	*id = event->id;
75*58e6ee5fSAndroid Build Coastguard Worker 
76*58e6ee5fSAndroid Build Coastguard Worker 	return event;
77*58e6ee5fSAndroid Build Coastguard Worker }
78*58e6ee5fSAndroid Build Coastguard Worker 
update_kmalloc(struct tep_handle * pevent)79*58e6ee5fSAndroid Build Coastguard Worker static void update_kmalloc(struct tep_handle *pevent)
80*58e6ee5fSAndroid Build Coastguard Worker {
81*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_event *event;
82*58e6ee5fSAndroid Build Coastguard Worker 
83*58e6ee5fSAndroid Build Coastguard Worker 	event = update_event(pevent, "kmem", "kmalloc", &kmalloc_type);
84*58e6ee5fSAndroid Build Coastguard Worker 	if (!event)
85*58e6ee5fSAndroid Build Coastguard Worker 		return;
86*58e6ee5fSAndroid Build Coastguard Worker 
87*58e6ee5fSAndroid Build Coastguard Worker 	kmalloc_callsite_field = tep_find_field(event, "call_site");
88*58e6ee5fSAndroid Build Coastguard Worker 	kmalloc_bytes_req_field = tep_find_field(event, "bytes_req");
89*58e6ee5fSAndroid Build Coastguard Worker 	kmalloc_bytes_alloc_field = tep_find_field(event, "bytes_alloc");
90*58e6ee5fSAndroid Build Coastguard Worker 	kmalloc_ptr_field = tep_find_field(event, "ptr");
91*58e6ee5fSAndroid Build Coastguard Worker }
92*58e6ee5fSAndroid Build Coastguard Worker 
update_kmalloc_node(struct tep_handle * pevent)93*58e6ee5fSAndroid Build Coastguard Worker static void update_kmalloc_node(struct tep_handle *pevent)
94*58e6ee5fSAndroid Build Coastguard Worker {
95*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_event *event;
96*58e6ee5fSAndroid Build Coastguard Worker 
97*58e6ee5fSAndroid Build Coastguard Worker 	event = update_event(pevent, "kmem", "kmalloc_node", &kmalloc_node_type);
98*58e6ee5fSAndroid Build Coastguard Worker 	if (!event)
99*58e6ee5fSAndroid Build Coastguard Worker 		return;
100*58e6ee5fSAndroid Build Coastguard Worker 
101*58e6ee5fSAndroid Build Coastguard Worker 	kmalloc_node_callsite_field = tep_find_field(event, "call_site");
102*58e6ee5fSAndroid Build Coastguard Worker 	kmalloc_node_bytes_req_field = tep_find_field(event, "bytes_req");
103*58e6ee5fSAndroid Build Coastguard Worker 	kmalloc_node_bytes_alloc_field = tep_find_field(event, "bytes_alloc");
104*58e6ee5fSAndroid Build Coastguard Worker 	kmalloc_node_ptr_field = tep_find_field(event, "ptr");
105*58e6ee5fSAndroid Build Coastguard Worker }
106*58e6ee5fSAndroid Build Coastguard Worker 
update_kfree(struct tep_handle * pevent)107*58e6ee5fSAndroid Build Coastguard Worker static void update_kfree(struct tep_handle *pevent)
108*58e6ee5fSAndroid Build Coastguard Worker {
109*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_event *event;
110*58e6ee5fSAndroid Build Coastguard Worker 
111*58e6ee5fSAndroid Build Coastguard Worker 	event = update_event(pevent, "kmem", "kfree", &kfree_type);
112*58e6ee5fSAndroid Build Coastguard Worker 	if (!event)
113*58e6ee5fSAndroid Build Coastguard Worker 		return;
114*58e6ee5fSAndroid Build Coastguard Worker 
115*58e6ee5fSAndroid Build Coastguard Worker 	kfree_ptr_field = tep_find_field(event, "ptr");
116*58e6ee5fSAndroid Build Coastguard Worker }
117*58e6ee5fSAndroid Build Coastguard Worker 
update_kmem_cache_alloc(struct tep_handle * pevent)118*58e6ee5fSAndroid Build Coastguard Worker static void update_kmem_cache_alloc(struct tep_handle *pevent)
119*58e6ee5fSAndroid Build Coastguard Worker {
120*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_event *event;
121*58e6ee5fSAndroid Build Coastguard Worker 
122*58e6ee5fSAndroid Build Coastguard Worker 	event = update_event(pevent, "kmem", "kmem_cache_alloc", &kmem_cache_alloc_type);
123*58e6ee5fSAndroid Build Coastguard Worker 	if (!event)
124*58e6ee5fSAndroid Build Coastguard Worker 		return;
125*58e6ee5fSAndroid Build Coastguard Worker 
126*58e6ee5fSAndroid Build Coastguard Worker 	kmem_cache_callsite_field = tep_find_field(event, "call_site");
127*58e6ee5fSAndroid Build Coastguard Worker 	kmem_cache_bytes_req_field = tep_find_field(event, "bytes_req");
128*58e6ee5fSAndroid Build Coastguard Worker 	kmem_cache_bytes_alloc_field = tep_find_field(event, "bytes_alloc");
129*58e6ee5fSAndroid Build Coastguard Worker 	kmem_cache_ptr_field = tep_find_field(event, "ptr");
130*58e6ee5fSAndroid Build Coastguard Worker }
131*58e6ee5fSAndroid Build Coastguard Worker 
update_kmem_cache_alloc_node(struct tep_handle * pevent)132*58e6ee5fSAndroid Build Coastguard Worker static void update_kmem_cache_alloc_node(struct tep_handle *pevent)
133*58e6ee5fSAndroid Build Coastguard Worker {
134*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_event *event;
135*58e6ee5fSAndroid Build Coastguard Worker 
136*58e6ee5fSAndroid Build Coastguard Worker 	event = update_event(pevent, "kmem", "kmem_cache_alloc_node",
137*58e6ee5fSAndroid Build Coastguard Worker 			     &kmem_cache_alloc_node_type);
138*58e6ee5fSAndroid Build Coastguard Worker 	if (!event)
139*58e6ee5fSAndroid Build Coastguard Worker 		return;
140*58e6ee5fSAndroid Build Coastguard Worker 
141*58e6ee5fSAndroid Build Coastguard Worker 	kmem_cache_node_callsite_field = tep_find_field(event, "call_site");
142*58e6ee5fSAndroid Build Coastguard Worker 	kmem_cache_node_bytes_req_field = tep_find_field(event, "bytes_req");
143*58e6ee5fSAndroid Build Coastguard Worker 	kmem_cache_node_bytes_alloc_field = tep_find_field(event, "bytes_alloc");
144*58e6ee5fSAndroid Build Coastguard Worker 	kmem_cache_node_ptr_field = tep_find_field(event, "ptr");
145*58e6ee5fSAndroid Build Coastguard Worker }
146*58e6ee5fSAndroid Build Coastguard Worker 
update_kmem_cache_free(struct tep_handle * pevent)147*58e6ee5fSAndroid Build Coastguard Worker static void update_kmem_cache_free(struct tep_handle *pevent)
148*58e6ee5fSAndroid Build Coastguard Worker {
149*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_event *event;
150*58e6ee5fSAndroid Build Coastguard Worker 
151*58e6ee5fSAndroid Build Coastguard Worker 	event = update_event(pevent, "kmem", "kmem_cache_free", &kmem_cache_free_type);
152*58e6ee5fSAndroid Build Coastguard Worker 	if (!event)
153*58e6ee5fSAndroid Build Coastguard Worker 		return;
154*58e6ee5fSAndroid Build Coastguard Worker 
155*58e6ee5fSAndroid Build Coastguard Worker 	kmem_cache_free_ptr_field = tep_find_field(event, "ptr");
156*58e6ee5fSAndroid Build Coastguard Worker }
157*58e6ee5fSAndroid Build Coastguard Worker 
158*58e6ee5fSAndroid Build Coastguard Worker struct func_descr {
159*58e6ee5fSAndroid Build Coastguard Worker 	struct func_descr	*next;
160*58e6ee5fSAndroid Build Coastguard Worker 	const char		*func;
161*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long		total_alloc;
162*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long		total_req;
163*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long		current_alloc;
164*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long		current_req;
165*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long		max_alloc;
166*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long		max_req;
167*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long		waste;
168*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long		max_waste;
169*58e6ee5fSAndroid Build Coastguard Worker };
170*58e6ee5fSAndroid Build Coastguard Worker 
171*58e6ee5fSAndroid Build Coastguard Worker struct ptr_descr {
172*58e6ee5fSAndroid Build Coastguard Worker 	struct ptr_descr	*next;
173*58e6ee5fSAndroid Build Coastguard Worker 	struct func_descr	*func;
174*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long	ptr;
175*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long		alloc;
176*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long		req;
177*58e6ee5fSAndroid Build Coastguard Worker };
178*58e6ee5fSAndroid Build Coastguard Worker 
179*58e6ee5fSAndroid Build Coastguard Worker #define HASH_BITS	12
180*58e6ee5fSAndroid Build Coastguard Worker #define HASH_SIZE	(1 << HASH_BITS)
181*58e6ee5fSAndroid Build Coastguard Worker #define HASH_MASK	(HASH_SIZE - 1);
182*58e6ee5fSAndroid Build Coastguard Worker 
183*58e6ee5fSAndroid Build Coastguard Worker static struct func_descr *func_hash[HASH_SIZE];
184*58e6ee5fSAndroid Build Coastguard Worker static struct ptr_descr *ptr_hash[HASH_SIZE];
185*58e6ee5fSAndroid Build Coastguard Worker static struct func_descr **func_list;
186*58e6ee5fSAndroid Build Coastguard Worker 
187*58e6ee5fSAndroid Build Coastguard Worker static unsigned func_count;
188*58e6ee5fSAndroid Build Coastguard Worker 
make_key(const void * ptr,int size)189*58e6ee5fSAndroid Build Coastguard Worker static int make_key(const void *ptr, int size)
190*58e6ee5fSAndroid Build Coastguard Worker {
191*58e6ee5fSAndroid Build Coastguard Worker 	int key = 0;
192*58e6ee5fSAndroid Build Coastguard Worker 	int i;
193*58e6ee5fSAndroid Build Coastguard Worker 	char *kp = (char *)&key;
194*58e6ee5fSAndroid Build Coastguard Worker 	const char *indx = ptr;
195*58e6ee5fSAndroid Build Coastguard Worker 
196*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < size; i++)
197*58e6ee5fSAndroid Build Coastguard Worker 		kp[i & 3] ^= indx[i];
198*58e6ee5fSAndroid Build Coastguard Worker 
199*58e6ee5fSAndroid Build Coastguard Worker 	return trace_hash(key);
200*58e6ee5fSAndroid Build Coastguard Worker }
201*58e6ee5fSAndroid Build Coastguard Worker 
find_func(const char * func)202*58e6ee5fSAndroid Build Coastguard Worker static struct func_descr *find_func(const char *func)
203*58e6ee5fSAndroid Build Coastguard Worker {
204*58e6ee5fSAndroid Build Coastguard Worker 	struct func_descr *funcd;
205*58e6ee5fSAndroid Build Coastguard Worker 	int key = make_key(func, strlen(func)) & HASH_MASK;
206*58e6ee5fSAndroid Build Coastguard Worker 
207*58e6ee5fSAndroid Build Coastguard Worker 	for (funcd = func_hash[key]; funcd; funcd = funcd->next) {
208*58e6ee5fSAndroid Build Coastguard Worker 		/*
209*58e6ee5fSAndroid Build Coastguard Worker 		 * As func is always a constant to one pointer,
210*58e6ee5fSAndroid Build Coastguard Worker 		 * we can use a direct compare instead of strcmp.
211*58e6ee5fSAndroid Build Coastguard Worker 		 */
212*58e6ee5fSAndroid Build Coastguard Worker 		if (funcd->func == func)
213*58e6ee5fSAndroid Build Coastguard Worker 			return funcd;
214*58e6ee5fSAndroid Build Coastguard Worker 	}
215*58e6ee5fSAndroid Build Coastguard Worker 
216*58e6ee5fSAndroid Build Coastguard Worker 	return NULL;
217*58e6ee5fSAndroid Build Coastguard Worker }
218*58e6ee5fSAndroid Build Coastguard Worker 
create_func(const char * func)219*58e6ee5fSAndroid Build Coastguard Worker static struct func_descr *create_func(const char *func)
220*58e6ee5fSAndroid Build Coastguard Worker {
221*58e6ee5fSAndroid Build Coastguard Worker 	struct func_descr *funcd;
222*58e6ee5fSAndroid Build Coastguard Worker 	int key = make_key(func, strlen(func)) & HASH_MASK;
223*58e6ee5fSAndroid Build Coastguard Worker 
224*58e6ee5fSAndroid Build Coastguard Worker 	funcd = zalloc(sizeof(*funcd));
225*58e6ee5fSAndroid Build Coastguard Worker 	if (!funcd)
226*58e6ee5fSAndroid Build Coastguard Worker 		die("malloc");
227*58e6ee5fSAndroid Build Coastguard Worker 
228*58e6ee5fSAndroid Build Coastguard Worker 	funcd->func = func;
229*58e6ee5fSAndroid Build Coastguard Worker 	funcd->next = func_hash[key];
230*58e6ee5fSAndroid Build Coastguard Worker 	func_hash[key] = funcd;
231*58e6ee5fSAndroid Build Coastguard Worker 
232*58e6ee5fSAndroid Build Coastguard Worker 	func_count++;
233*58e6ee5fSAndroid Build Coastguard Worker 
234*58e6ee5fSAndroid Build Coastguard Worker 	return funcd;
235*58e6ee5fSAndroid Build Coastguard Worker }
236*58e6ee5fSAndroid Build Coastguard Worker 
find_ptr(unsigned long long ptr)237*58e6ee5fSAndroid Build Coastguard Worker static struct ptr_descr *find_ptr(unsigned long long ptr)
238*58e6ee5fSAndroid Build Coastguard Worker {
239*58e6ee5fSAndroid Build Coastguard Worker 	struct ptr_descr *ptrd;
240*58e6ee5fSAndroid Build Coastguard Worker 	int key = make_key(&ptr, sizeof(ptr)) & HASH_MASK;
241*58e6ee5fSAndroid Build Coastguard Worker 
242*58e6ee5fSAndroid Build Coastguard Worker 	for (ptrd = ptr_hash[key]; ptrd; ptrd = ptrd->next) {
243*58e6ee5fSAndroid Build Coastguard Worker 		if (ptrd->ptr == ptr)
244*58e6ee5fSAndroid Build Coastguard Worker 			return ptrd;
245*58e6ee5fSAndroid Build Coastguard Worker 	}
246*58e6ee5fSAndroid Build Coastguard Worker 
247*58e6ee5fSAndroid Build Coastguard Worker 	return NULL;
248*58e6ee5fSAndroid Build Coastguard Worker }
249*58e6ee5fSAndroid Build Coastguard Worker 
create_ptr(unsigned long long ptr)250*58e6ee5fSAndroid Build Coastguard Worker static struct ptr_descr *create_ptr(unsigned long long ptr)
251*58e6ee5fSAndroid Build Coastguard Worker {
252*58e6ee5fSAndroid Build Coastguard Worker 	struct ptr_descr *ptrd;
253*58e6ee5fSAndroid Build Coastguard Worker 	int key = make_key(&ptr, sizeof(ptr)) & HASH_MASK;
254*58e6ee5fSAndroid Build Coastguard Worker 
255*58e6ee5fSAndroid Build Coastguard Worker 	ptrd = zalloc(sizeof(*ptrd));
256*58e6ee5fSAndroid Build Coastguard Worker 	if (!ptrd)
257*58e6ee5fSAndroid Build Coastguard Worker 		die("malloc");
258*58e6ee5fSAndroid Build Coastguard Worker 
259*58e6ee5fSAndroid Build Coastguard Worker 	ptrd->ptr = ptr;
260*58e6ee5fSAndroid Build Coastguard Worker 	ptrd->next = ptr_hash[key];
261*58e6ee5fSAndroid Build Coastguard Worker 	ptr_hash[key] = ptrd;
262*58e6ee5fSAndroid Build Coastguard Worker 
263*58e6ee5fSAndroid Build Coastguard Worker 	return ptrd;
264*58e6ee5fSAndroid Build Coastguard Worker }
265*58e6ee5fSAndroid Build Coastguard Worker 
remove_ptr(unsigned long long ptr)266*58e6ee5fSAndroid Build Coastguard Worker static void remove_ptr(unsigned long long ptr)
267*58e6ee5fSAndroid Build Coastguard Worker {
268*58e6ee5fSAndroid Build Coastguard Worker 	struct ptr_descr *ptrd, **last;
269*58e6ee5fSAndroid Build Coastguard Worker 	int key = make_key(&ptr, sizeof(ptr)) & HASH_MASK;
270*58e6ee5fSAndroid Build Coastguard Worker 
271*58e6ee5fSAndroid Build Coastguard Worker 	last = &ptr_hash[key];
272*58e6ee5fSAndroid Build Coastguard Worker 	for (ptrd = ptr_hash[key]; ptrd; ptrd = ptrd->next) {
273*58e6ee5fSAndroid Build Coastguard Worker 		if (ptrd->ptr == ptr)
274*58e6ee5fSAndroid Build Coastguard Worker 			break;
275*58e6ee5fSAndroid Build Coastguard Worker 		last = &ptrd->next;
276*58e6ee5fSAndroid Build Coastguard Worker 	}
277*58e6ee5fSAndroid Build Coastguard Worker 
278*58e6ee5fSAndroid Build Coastguard Worker 	if (!ptrd)
279*58e6ee5fSAndroid Build Coastguard Worker 		return;
280*58e6ee5fSAndroid Build Coastguard Worker 
281*58e6ee5fSAndroid Build Coastguard Worker 	*last = ptrd->next;
282*58e6ee5fSAndroid Build Coastguard Worker 	free(ptrd);
283*58e6ee5fSAndroid Build Coastguard Worker }
284*58e6ee5fSAndroid Build Coastguard Worker 
add_kmalloc(const char * func,unsigned long long ptr,unsigned int req,int alloc)285*58e6ee5fSAndroid Build Coastguard Worker static void add_kmalloc(const char *func, unsigned long long ptr,
286*58e6ee5fSAndroid Build Coastguard Worker 			unsigned int req, int alloc)
287*58e6ee5fSAndroid Build Coastguard Worker {
288*58e6ee5fSAndroid Build Coastguard Worker 	struct func_descr *funcd;
289*58e6ee5fSAndroid Build Coastguard Worker 	struct ptr_descr *ptrd;
290*58e6ee5fSAndroid Build Coastguard Worker 
291*58e6ee5fSAndroid Build Coastguard Worker 	funcd = find_func(func);
292*58e6ee5fSAndroid Build Coastguard Worker 	if (!funcd)
293*58e6ee5fSAndroid Build Coastguard Worker 		funcd = create_func(func);
294*58e6ee5fSAndroid Build Coastguard Worker 
295*58e6ee5fSAndroid Build Coastguard Worker 	funcd->total_alloc += alloc;
296*58e6ee5fSAndroid Build Coastguard Worker 	funcd->total_req += req;
297*58e6ee5fSAndroid Build Coastguard Worker 	funcd->current_alloc += alloc;
298*58e6ee5fSAndroid Build Coastguard Worker 	funcd->current_req += req;
299*58e6ee5fSAndroid Build Coastguard Worker 	if (funcd->current_alloc > funcd->max_alloc)
300*58e6ee5fSAndroid Build Coastguard Worker 		funcd->max_alloc = funcd->current_alloc;
301*58e6ee5fSAndroid Build Coastguard Worker 	if (funcd->current_req > funcd->max_req)
302*58e6ee5fSAndroid Build Coastguard Worker 		funcd->max_req = funcd->current_req;
303*58e6ee5fSAndroid Build Coastguard Worker 
304*58e6ee5fSAndroid Build Coastguard Worker 	ptrd = find_ptr(ptr);
305*58e6ee5fSAndroid Build Coastguard Worker 	if (!ptrd)
306*58e6ee5fSAndroid Build Coastguard Worker 		ptrd = create_ptr(ptr);
307*58e6ee5fSAndroid Build Coastguard Worker 
308*58e6ee5fSAndroid Build Coastguard Worker 	ptrd->alloc = alloc;
309*58e6ee5fSAndroid Build Coastguard Worker 	ptrd->req = req;
310*58e6ee5fSAndroid Build Coastguard Worker 	ptrd->func = funcd;
311*58e6ee5fSAndroid Build Coastguard Worker }
312*58e6ee5fSAndroid Build Coastguard Worker 
remove_kmalloc(unsigned long long ptr)313*58e6ee5fSAndroid Build Coastguard Worker static void remove_kmalloc(unsigned long long ptr)
314*58e6ee5fSAndroid Build Coastguard Worker {
315*58e6ee5fSAndroid Build Coastguard Worker 	struct func_descr *funcd;
316*58e6ee5fSAndroid Build Coastguard Worker 	struct ptr_descr *ptrd;
317*58e6ee5fSAndroid Build Coastguard Worker 
318*58e6ee5fSAndroid Build Coastguard Worker 	ptrd = find_ptr(ptr);
319*58e6ee5fSAndroid Build Coastguard Worker 	if (!ptrd)
320*58e6ee5fSAndroid Build Coastguard Worker 		return;
321*58e6ee5fSAndroid Build Coastguard Worker 
322*58e6ee5fSAndroid Build Coastguard Worker 	funcd = ptrd->func;
323*58e6ee5fSAndroid Build Coastguard Worker 	funcd->current_alloc -= ptrd->alloc;
324*58e6ee5fSAndroid Build Coastguard Worker 	funcd->current_req -= ptrd->req;
325*58e6ee5fSAndroid Build Coastguard Worker 
326*58e6ee5fSAndroid Build Coastguard Worker 	remove_ptr(ptr);
327*58e6ee5fSAndroid Build Coastguard Worker }
328*58e6ee5fSAndroid Build Coastguard Worker 
329*58e6ee5fSAndroid Build Coastguard Worker static void
process_kmalloc(struct tep_handle * pevent,struct tep_record * record,struct tep_format_field * callsite_field,struct tep_format_field * bytes_req_field,struct tep_format_field * bytes_alloc_field,struct tep_format_field * ptr_field)330*58e6ee5fSAndroid Build Coastguard Worker process_kmalloc(struct tep_handle *pevent, struct tep_record *record,
331*58e6ee5fSAndroid Build Coastguard Worker 		struct tep_format_field *callsite_field,
332*58e6ee5fSAndroid Build Coastguard Worker 		struct tep_format_field *bytes_req_field,
333*58e6ee5fSAndroid Build Coastguard Worker 		struct tep_format_field *bytes_alloc_field,
334*58e6ee5fSAndroid Build Coastguard Worker 		struct tep_format_field *ptr_field)
335*58e6ee5fSAndroid Build Coastguard Worker {
336*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long callsite;
337*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long val;
338*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long ptr;
339*58e6ee5fSAndroid Build Coastguard Worker 	unsigned int req;
340*58e6ee5fSAndroid Build Coastguard Worker 	int alloc;
341*58e6ee5fSAndroid Build Coastguard Worker 	const char *func;
342*58e6ee5fSAndroid Build Coastguard Worker 
343*58e6ee5fSAndroid Build Coastguard Worker 	tep_read_number_field(callsite_field, record->data, &callsite);
344*58e6ee5fSAndroid Build Coastguard Worker 	tep_read_number_field(bytes_req_field, record->data, &val);
345*58e6ee5fSAndroid Build Coastguard Worker 	req = val;
346*58e6ee5fSAndroid Build Coastguard Worker 	tep_read_number_field(bytes_alloc_field, record->data, &val);
347*58e6ee5fSAndroid Build Coastguard Worker 	alloc = val;
348*58e6ee5fSAndroid Build Coastguard Worker 	tep_read_number_field(ptr_field, record->data, &ptr);
349*58e6ee5fSAndroid Build Coastguard Worker 
350*58e6ee5fSAndroid Build Coastguard Worker 	func = tep_find_function(pevent, callsite);
351*58e6ee5fSAndroid Build Coastguard Worker 
352*58e6ee5fSAndroid Build Coastguard Worker 	add_kmalloc(func, ptr, req, alloc);
353*58e6ee5fSAndroid Build Coastguard Worker }
354*58e6ee5fSAndroid Build Coastguard Worker 
355*58e6ee5fSAndroid Build Coastguard Worker static void
process_kfree(struct tep_handle * pevent,struct tep_record * record,struct tep_format_field * ptr_field)356*58e6ee5fSAndroid Build Coastguard Worker process_kfree(struct tep_handle *pevent, struct tep_record *record,
357*58e6ee5fSAndroid Build Coastguard Worker 	      struct tep_format_field *ptr_field)
358*58e6ee5fSAndroid Build Coastguard Worker {
359*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long ptr;
360*58e6ee5fSAndroid Build Coastguard Worker 
361*58e6ee5fSAndroid Build Coastguard Worker 	tep_read_number_field(ptr_field, record->data, &ptr);
362*58e6ee5fSAndroid Build Coastguard Worker 
363*58e6ee5fSAndroid Build Coastguard Worker 	remove_kmalloc(ptr);
364*58e6ee5fSAndroid Build Coastguard Worker }
365*58e6ee5fSAndroid Build Coastguard Worker 
366*58e6ee5fSAndroid Build Coastguard Worker static void
process_record(struct tep_handle * pevent,struct tep_record * record)367*58e6ee5fSAndroid Build Coastguard Worker process_record(struct tep_handle *pevent, struct tep_record *record)
368*58e6ee5fSAndroid Build Coastguard Worker {
369*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long val;
370*58e6ee5fSAndroid Build Coastguard Worker 	int type;
371*58e6ee5fSAndroid Build Coastguard Worker 
372*58e6ee5fSAndroid Build Coastguard Worker 	tep_read_number_field(common_type_mem, record->data, &val);
373*58e6ee5fSAndroid Build Coastguard Worker 	type = val;
374*58e6ee5fSAndroid Build Coastguard Worker 
375*58e6ee5fSAndroid Build Coastguard Worker 	if (type == kmalloc_type)
376*58e6ee5fSAndroid Build Coastguard Worker 		return process_kmalloc(pevent, record,
377*58e6ee5fSAndroid Build Coastguard Worker 				       kmalloc_callsite_field,
378*58e6ee5fSAndroid Build Coastguard Worker 				       kmalloc_bytes_req_field,
379*58e6ee5fSAndroid Build Coastguard Worker 				       kmalloc_bytes_alloc_field,
380*58e6ee5fSAndroid Build Coastguard Worker 				       kmalloc_ptr_field);
381*58e6ee5fSAndroid Build Coastguard Worker 	if (type == kmalloc_node_type)
382*58e6ee5fSAndroid Build Coastguard Worker 		return process_kmalloc(pevent, record,
383*58e6ee5fSAndroid Build Coastguard Worker 				       kmalloc_node_callsite_field,
384*58e6ee5fSAndroid Build Coastguard Worker 				       kmalloc_node_bytes_req_field,
385*58e6ee5fSAndroid Build Coastguard Worker 				       kmalloc_node_bytes_alloc_field,
386*58e6ee5fSAndroid Build Coastguard Worker 				       kmalloc_node_ptr_field);
387*58e6ee5fSAndroid Build Coastguard Worker 	if (type == kfree_type)
388*58e6ee5fSAndroid Build Coastguard Worker 		return process_kfree(pevent, record, kfree_ptr_field);
389*58e6ee5fSAndroid Build Coastguard Worker 
390*58e6ee5fSAndroid Build Coastguard Worker 	if (type == kmem_cache_alloc_type)
391*58e6ee5fSAndroid Build Coastguard Worker 		return process_kmalloc(pevent, record,
392*58e6ee5fSAndroid Build Coastguard Worker 				       kmem_cache_callsite_field,
393*58e6ee5fSAndroid Build Coastguard Worker 				       kmem_cache_bytes_req_field,
394*58e6ee5fSAndroid Build Coastguard Worker 				       kmem_cache_bytes_alloc_field,
395*58e6ee5fSAndroid Build Coastguard Worker 				       kmem_cache_ptr_field);
396*58e6ee5fSAndroid Build Coastguard Worker 	if (type == kmem_cache_alloc_node_type)
397*58e6ee5fSAndroid Build Coastguard Worker 		return process_kmalloc(pevent, record,
398*58e6ee5fSAndroid Build Coastguard Worker 				       kmem_cache_node_callsite_field,
399*58e6ee5fSAndroid Build Coastguard Worker 				       kmem_cache_node_bytes_req_field,
400*58e6ee5fSAndroid Build Coastguard Worker 				       kmem_cache_node_bytes_alloc_field,
401*58e6ee5fSAndroid Build Coastguard Worker 				       kmem_cache_node_ptr_field);
402*58e6ee5fSAndroid Build Coastguard Worker 	if (type == kmem_cache_free_type)
403*58e6ee5fSAndroid Build Coastguard Worker 		return process_kfree(pevent, record, kmem_cache_free_ptr_field);
404*58e6ee5fSAndroid Build Coastguard Worker }
405*58e6ee5fSAndroid Build Coastguard Worker 
func_cmp(const void * a,const void * b)406*58e6ee5fSAndroid Build Coastguard Worker static int func_cmp(const void *a, const void *b)
407*58e6ee5fSAndroid Build Coastguard Worker {
408*58e6ee5fSAndroid Build Coastguard Worker 	const struct func_descr *fa = *(const struct func_descr **)a;
409*58e6ee5fSAndroid Build Coastguard Worker 	const struct func_descr *fb = *(const struct func_descr **)b;
410*58e6ee5fSAndroid Build Coastguard Worker 
411*58e6ee5fSAndroid Build Coastguard Worker 	if (fa->waste > fb->waste)
412*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
413*58e6ee5fSAndroid Build Coastguard Worker 	if (fa->waste < fb->waste)
414*58e6ee5fSAndroid Build Coastguard Worker 		return 1;
415*58e6ee5fSAndroid Build Coastguard Worker 	return 0;
416*58e6ee5fSAndroid Build Coastguard Worker }
417*58e6ee5fSAndroid Build Coastguard Worker 
sort_list(void)418*58e6ee5fSAndroid Build Coastguard Worker static void sort_list(void)
419*58e6ee5fSAndroid Build Coastguard Worker {
420*58e6ee5fSAndroid Build Coastguard Worker 	struct func_descr *funcd;
421*58e6ee5fSAndroid Build Coastguard Worker 	int h;
422*58e6ee5fSAndroid Build Coastguard Worker 	int i = 0;
423*58e6ee5fSAndroid Build Coastguard Worker 
424*58e6ee5fSAndroid Build Coastguard Worker 	func_list = zalloc(sizeof(*func_list) * func_count);
425*58e6ee5fSAndroid Build Coastguard Worker 
426*58e6ee5fSAndroid Build Coastguard Worker 	for (h = 0; h < HASH_SIZE; h++) {
427*58e6ee5fSAndroid Build Coastguard Worker 		for (funcd = func_hash[h]; funcd; funcd = funcd->next) {
428*58e6ee5fSAndroid Build Coastguard Worker 			funcd->waste = funcd->current_alloc - funcd->current_req;
429*58e6ee5fSAndroid Build Coastguard Worker 			funcd->max_waste = funcd->max_alloc - funcd->max_req;
430*58e6ee5fSAndroid Build Coastguard Worker 			if (i == func_count)
431*58e6ee5fSAndroid Build Coastguard Worker 				die("more funcs than expected\n");
432*58e6ee5fSAndroid Build Coastguard Worker 			func_list[i++] = funcd;
433*58e6ee5fSAndroid Build Coastguard Worker 		}
434*58e6ee5fSAndroid Build Coastguard Worker 	}
435*58e6ee5fSAndroid Build Coastguard Worker 
436*58e6ee5fSAndroid Build Coastguard Worker 	qsort(func_list, func_count, sizeof(*func_list), func_cmp);
437*58e6ee5fSAndroid Build Coastguard Worker }
438*58e6ee5fSAndroid Build Coastguard Worker 
print_list(void)439*58e6ee5fSAndroid Build Coastguard Worker static void print_list(void)
440*58e6ee5fSAndroid Build Coastguard Worker {
441*58e6ee5fSAndroid Build Coastguard Worker 	struct func_descr *funcd;
442*58e6ee5fSAndroid Build Coastguard Worker 	int i;
443*58e6ee5fSAndroid Build Coastguard Worker 
444*58e6ee5fSAndroid Build Coastguard Worker 	printf("                Function            \t");
445*58e6ee5fSAndroid Build Coastguard Worker 	printf("Waste\tAlloc\treq\t\tTotAlloc     TotReq\t\tMaxAlloc     MaxReq\t");
446*58e6ee5fSAndroid Build Coastguard Worker 	printf("MaxWaste\n");
447*58e6ee5fSAndroid Build Coastguard Worker 	printf("                --------            \t");
448*58e6ee5fSAndroid Build Coastguard Worker 	printf("-----\t-----\t---\t\t--------     ------\t\t--------     ------\t");
449*58e6ee5fSAndroid Build Coastguard Worker 	printf("--------\n");
450*58e6ee5fSAndroid Build Coastguard Worker 
451*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < func_count; i++) {
452*58e6ee5fSAndroid Build Coastguard Worker 		funcd = func_list[i];
453*58e6ee5fSAndroid Build Coastguard Worker 
454*58e6ee5fSAndroid Build Coastguard Worker 		printf("%32s\t%ld\t%ld\t%ld\t\t%8ld   %8ld\t\t%8ld   %8ld\t%ld\n",
455*58e6ee5fSAndroid Build Coastguard Worker 		       funcd->func, funcd->waste,
456*58e6ee5fSAndroid Build Coastguard Worker 		       funcd->current_alloc, funcd->current_req,
457*58e6ee5fSAndroid Build Coastguard Worker 		       funcd->total_alloc, funcd->total_req,
458*58e6ee5fSAndroid Build Coastguard Worker 		       funcd->max_alloc, funcd->max_req, funcd->max_waste);
459*58e6ee5fSAndroid Build Coastguard Worker 	}
460*58e6ee5fSAndroid Build Coastguard Worker }
461*58e6ee5fSAndroid Build Coastguard Worker 
do_trace_mem(struct tracecmd_input * handle)462*58e6ee5fSAndroid Build Coastguard Worker static void do_trace_mem(struct tracecmd_input *handle)
463*58e6ee5fSAndroid Build Coastguard Worker {
464*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_handle *pevent = tracecmd_get_tep(handle);
465*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_record *record;
466*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_event *event;
467*58e6ee5fSAndroid Build Coastguard Worker 	int missed_events = 0;
468*58e6ee5fSAndroid Build Coastguard Worker 	int cpus;
469*58e6ee5fSAndroid Build Coastguard Worker 	int cpu;
470*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
471*58e6ee5fSAndroid Build Coastguard Worker 
472*58e6ee5fSAndroid Build Coastguard Worker 	ret = tracecmd_init_data(handle);
473*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
474*58e6ee5fSAndroid Build Coastguard Worker 		die("failed to init data");
475*58e6ee5fSAndroid Build Coastguard Worker 
476*58e6ee5fSAndroid Build Coastguard Worker 	if (ret > 0)
477*58e6ee5fSAndroid Build Coastguard Worker 		die("trace-cmd mem does not work with latency traces\n");
478*58e6ee5fSAndroid Build Coastguard Worker 
479*58e6ee5fSAndroid Build Coastguard Worker 	cpus = tracecmd_cpus(handle);
480*58e6ee5fSAndroid Build Coastguard Worker 
481*58e6ee5fSAndroid Build Coastguard Worker 	/* Need to get any event */
482*58e6ee5fSAndroid Build Coastguard Worker 	for (cpu = 0; cpu < cpus; cpu++) {
483*58e6ee5fSAndroid Build Coastguard Worker 		record = tracecmd_peek_data(handle, cpu);
484*58e6ee5fSAndroid Build Coastguard Worker 		if (record)
485*58e6ee5fSAndroid Build Coastguard Worker 			break;
486*58e6ee5fSAndroid Build Coastguard Worker 	}
487*58e6ee5fSAndroid Build Coastguard Worker 	if (!record)
488*58e6ee5fSAndroid Build Coastguard Worker 		die("No records found in file");
489*58e6ee5fSAndroid Build Coastguard Worker 
490*58e6ee5fSAndroid Build Coastguard Worker 	ret = tep_data_type(pevent, record);
491*58e6ee5fSAndroid Build Coastguard Worker 	event = tep_find_event(pevent, ret);
492*58e6ee5fSAndroid Build Coastguard Worker 
493*58e6ee5fSAndroid Build Coastguard Worker 	common_type_mem = tep_find_common_field(event, "common_type");
494*58e6ee5fSAndroid Build Coastguard Worker 	if (!common_type_mem)
495*58e6ee5fSAndroid Build Coastguard Worker 		die("Can't find a 'type' field?");
496*58e6ee5fSAndroid Build Coastguard Worker 
497*58e6ee5fSAndroid Build Coastguard Worker 	update_kmalloc(pevent);
498*58e6ee5fSAndroid Build Coastguard Worker 	update_kmalloc_node(pevent);
499*58e6ee5fSAndroid Build Coastguard Worker 	update_kfree(pevent);
500*58e6ee5fSAndroid Build Coastguard Worker 	update_kmem_cache_alloc(pevent);
501*58e6ee5fSAndroid Build Coastguard Worker 	update_kmem_cache_alloc_node(pevent);
502*58e6ee5fSAndroid Build Coastguard Worker 	update_kmem_cache_free(pevent);
503*58e6ee5fSAndroid Build Coastguard Worker 
504*58e6ee5fSAndroid Build Coastguard Worker 	while ((record = tracecmd_read_next_data(handle, &cpu))) {
505*58e6ee5fSAndroid Build Coastguard Worker 
506*58e6ee5fSAndroid Build Coastguard Worker 		/* record missed event */
507*58e6ee5fSAndroid Build Coastguard Worker 		if (!missed_events && record->missed_events)
508*58e6ee5fSAndroid Build Coastguard Worker 			missed_events = 1;
509*58e6ee5fSAndroid Build Coastguard Worker 
510*58e6ee5fSAndroid Build Coastguard Worker 		process_record(pevent, record);
511*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_free_record(record);
512*58e6ee5fSAndroid Build Coastguard Worker 	}
513*58e6ee5fSAndroid Build Coastguard Worker 
514*58e6ee5fSAndroid Build Coastguard Worker 	sort_list();
515*58e6ee5fSAndroid Build Coastguard Worker 	print_list();
516*58e6ee5fSAndroid Build Coastguard Worker }
517*58e6ee5fSAndroid Build Coastguard Worker 
trace_mem(int argc,char ** argv)518*58e6ee5fSAndroid Build Coastguard Worker void trace_mem(int argc, char **argv)
519*58e6ee5fSAndroid Build Coastguard Worker {
520*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_input *handle;
521*58e6ee5fSAndroid Build Coastguard Worker 	const char *input_file = NULL;
522*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
523*58e6ee5fSAndroid Build Coastguard Worker 
524*58e6ee5fSAndroid Build Coastguard Worker 	for (;;) {
525*58e6ee5fSAndroid Build Coastguard Worker 		int c;
526*58e6ee5fSAndroid Build Coastguard Worker 
527*58e6ee5fSAndroid Build Coastguard Worker 		c = getopt(argc-1, argv+1, "+hi:");
528*58e6ee5fSAndroid Build Coastguard Worker 		if (c == -1)
529*58e6ee5fSAndroid Build Coastguard Worker 			break;
530*58e6ee5fSAndroid Build Coastguard Worker 		switch (c) {
531*58e6ee5fSAndroid Build Coastguard Worker 		case 'h':
532*58e6ee5fSAndroid Build Coastguard Worker 			usage(argv);
533*58e6ee5fSAndroid Build Coastguard Worker 			break;
534*58e6ee5fSAndroid Build Coastguard Worker 		case 'i':
535*58e6ee5fSAndroid Build Coastguard Worker 			if (input_file)
536*58e6ee5fSAndroid Build Coastguard Worker 				die("Only one input for mem");
537*58e6ee5fSAndroid Build Coastguard Worker 			input_file = optarg;
538*58e6ee5fSAndroid Build Coastguard Worker 			break;
539*58e6ee5fSAndroid Build Coastguard Worker 		default:
540*58e6ee5fSAndroid Build Coastguard Worker 			usage(argv);
541*58e6ee5fSAndroid Build Coastguard Worker 		}
542*58e6ee5fSAndroid Build Coastguard Worker 	}
543*58e6ee5fSAndroid Build Coastguard Worker 
544*58e6ee5fSAndroid Build Coastguard Worker 	if ((argc - optind) >= 2) {
545*58e6ee5fSAndroid Build Coastguard Worker 		if (input_file)
546*58e6ee5fSAndroid Build Coastguard Worker 			usage(argv);
547*58e6ee5fSAndroid Build Coastguard Worker 		input_file = argv[optind + 1];
548*58e6ee5fSAndroid Build Coastguard Worker 	}
549*58e6ee5fSAndroid Build Coastguard Worker 
550*58e6ee5fSAndroid Build Coastguard Worker 	if (!input_file)
551*58e6ee5fSAndroid Build Coastguard Worker 		input_file = DEFAULT_INPUT_FILE;
552*58e6ee5fSAndroid Build Coastguard Worker 
553*58e6ee5fSAndroid Build Coastguard Worker 	handle = tracecmd_alloc(input_file, 0);
554*58e6ee5fSAndroid Build Coastguard Worker 	if (!handle)
555*58e6ee5fSAndroid Build Coastguard Worker 		die("can't open %s\n", input_file);
556*58e6ee5fSAndroid Build Coastguard Worker 
557*58e6ee5fSAndroid Build Coastguard Worker 	ret = tracecmd_read_headers(handle, 0);
558*58e6ee5fSAndroid Build Coastguard Worker 	if (ret)
559*58e6ee5fSAndroid Build Coastguard Worker 		return;
560*58e6ee5fSAndroid Build Coastguard Worker 
561*58e6ee5fSAndroid Build Coastguard Worker 	do_trace_mem(handle);
562*58e6ee5fSAndroid Build Coastguard Worker 
563*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_close(handle);
564*58e6ee5fSAndroid Build Coastguard Worker }
565