1*1a3d31e3SAndroid Build Coastguard Worker /*
2*1a3d31e3SAndroid Build Coastguard Worker * blktrace output analysis: generate a timeline & gather statistics
3*1a3d31e3SAndroid Build Coastguard Worker *
4*1a3d31e3SAndroid Build Coastguard Worker * Copyright (C) 2006 Alan D. Brunelle <[email protected]>
5*1a3d31e3SAndroid Build Coastguard Worker *
6*1a3d31e3SAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or modify
7*1a3d31e3SAndroid Build Coastguard Worker * it under the terms of the GNU General Public License as published by
8*1a3d31e3SAndroid Build Coastguard Worker * the Free Software Foundation; either version 2 of the License, or
9*1a3d31e3SAndroid Build Coastguard Worker * (at your option) any later version.
10*1a3d31e3SAndroid Build Coastguard Worker *
11*1a3d31e3SAndroid Build Coastguard Worker * This program is distributed in the hope that it will be useful,
12*1a3d31e3SAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*1a3d31e3SAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*1a3d31e3SAndroid Build Coastguard Worker * GNU General Public License for more details.
15*1a3d31e3SAndroid Build Coastguard Worker *
16*1a3d31e3SAndroid Build Coastguard Worker * You should have received a copy of the GNU General Public License
17*1a3d31e3SAndroid Build Coastguard Worker * along with this program; if not, write to the Free Software
18*1a3d31e3SAndroid Build Coastguard Worker * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*1a3d31e3SAndroid Build Coastguard Worker *
20*1a3d31e3SAndroid Build Coastguard Worker */
21*1a3d31e3SAndroid Build Coastguard Worker #include <stdio.h>
22*1a3d31e3SAndroid Build Coastguard Worker #include "globals.h"
23*1a3d31e3SAndroid Build Coastguard Worker
24*1a3d31e3SAndroid Build Coastguard Worker #define N_DEV_HASH 128
25*1a3d31e3SAndroid Build Coastguard Worker #define DEV_HASH(dev) ((MAJOR(dev) ^ MINOR(dev)) & (N_DEV_HASH - 1))
26*1a3d31e3SAndroid Build Coastguard Worker struct list_head dev_heads[N_DEV_HASH];
27*1a3d31e3SAndroid Build Coastguard Worker
dip_rb_mkhds(void)28*1a3d31e3SAndroid Build Coastguard Worker static inline void *dip_rb_mkhds(void)
29*1a3d31e3SAndroid Build Coastguard Worker {
30*1a3d31e3SAndroid Build Coastguard Worker size_t len = N_IOP_TYPES * sizeof(struct rb_root);
31*1a3d31e3SAndroid Build Coastguard Worker return memset(malloc(len), 0, len);
32*1a3d31e3SAndroid Build Coastguard Worker }
33*1a3d31e3SAndroid Build Coastguard Worker
__destroy(struct rb_node * n)34*1a3d31e3SAndroid Build Coastguard Worker static void __destroy(struct rb_node *n)
35*1a3d31e3SAndroid Build Coastguard Worker {
36*1a3d31e3SAndroid Build Coastguard Worker if (n) {
37*1a3d31e3SAndroid Build Coastguard Worker struct io *iop = rb_entry(n, struct io, rb_node);
38*1a3d31e3SAndroid Build Coastguard Worker
39*1a3d31e3SAndroid Build Coastguard Worker __destroy(n->rb_left);
40*1a3d31e3SAndroid Build Coastguard Worker __destroy(n->rb_right);
41*1a3d31e3SAndroid Build Coastguard Worker io_release(iop);
42*1a3d31e3SAndroid Build Coastguard Worker }
43*1a3d31e3SAndroid Build Coastguard Worker }
44*1a3d31e3SAndroid Build Coastguard Worker
__destroy_heads(struct rb_root * roots)45*1a3d31e3SAndroid Build Coastguard Worker static void __destroy_heads(struct rb_root *roots)
46*1a3d31e3SAndroid Build Coastguard Worker {
47*1a3d31e3SAndroid Build Coastguard Worker int i;
48*1a3d31e3SAndroid Build Coastguard Worker
49*1a3d31e3SAndroid Build Coastguard Worker for (i = 0; i < N_IOP_TYPES; i++)
50*1a3d31e3SAndroid Build Coastguard Worker __destroy(roots[i].rb_node);
51*1a3d31e3SAndroid Build Coastguard Worker
52*1a3d31e3SAndroid Build Coastguard Worker free(roots);
53*1a3d31e3SAndroid Build Coastguard Worker }
54*1a3d31e3SAndroid Build Coastguard Worker
init_dev_heads(void)55*1a3d31e3SAndroid Build Coastguard Worker void init_dev_heads(void)
56*1a3d31e3SAndroid Build Coastguard Worker {
57*1a3d31e3SAndroid Build Coastguard Worker int i;
58*1a3d31e3SAndroid Build Coastguard Worker for (i = 0; i < N_DEV_HASH; i++)
59*1a3d31e3SAndroid Build Coastguard Worker INIT_LIST_HEAD(&dev_heads[i]);
60*1a3d31e3SAndroid Build Coastguard Worker }
61*1a3d31e3SAndroid Build Coastguard Worker
__dip_find(__u32 device)62*1a3d31e3SAndroid Build Coastguard Worker struct d_info *__dip_find(__u32 device)
63*1a3d31e3SAndroid Build Coastguard Worker {
64*1a3d31e3SAndroid Build Coastguard Worker struct d_info *dip;
65*1a3d31e3SAndroid Build Coastguard Worker struct list_head *p;
66*1a3d31e3SAndroid Build Coastguard Worker
67*1a3d31e3SAndroid Build Coastguard Worker __list_for_each(p, &dev_heads[DEV_HASH(device)]) {
68*1a3d31e3SAndroid Build Coastguard Worker dip = list_entry(p, struct d_info, hash_head);
69*1a3d31e3SAndroid Build Coastguard Worker if (device == dip->device)
70*1a3d31e3SAndroid Build Coastguard Worker return dip;
71*1a3d31e3SAndroid Build Coastguard Worker }
72*1a3d31e3SAndroid Build Coastguard Worker
73*1a3d31e3SAndroid Build Coastguard Worker return NULL;
74*1a3d31e3SAndroid Build Coastguard Worker }
75*1a3d31e3SAndroid Build Coastguard Worker
__dip_exit(struct d_info * dip)76*1a3d31e3SAndroid Build Coastguard Worker void __dip_exit(struct d_info *dip)
77*1a3d31e3SAndroid Build Coastguard Worker {
78*1a3d31e3SAndroid Build Coastguard Worker list_del(&dip->all_head);
79*1a3d31e3SAndroid Build Coastguard Worker __destroy_heads(dip->heads);
80*1a3d31e3SAndroid Build Coastguard Worker region_exit(&dip->regions);
81*1a3d31e3SAndroid Build Coastguard Worker seeki_free(dip->seek_handle);
82*1a3d31e3SAndroid Build Coastguard Worker seeki_free(dip->q2q_handle);
83*1a3d31e3SAndroid Build Coastguard Worker aqd_free(dip->aqd_handle);
84*1a3d31e3SAndroid Build Coastguard Worker plat_free(dip->q2d_plat_handle);
85*1a3d31e3SAndroid Build Coastguard Worker plat_free(dip->q2c_plat_handle);
86*1a3d31e3SAndroid Build Coastguard Worker plat_free(dip->d2c_plat_handle);
87*1a3d31e3SAndroid Build Coastguard Worker p_live_free(dip->p_live_handle);
88*1a3d31e3SAndroid Build Coastguard Worker bno_dump_free(dip->bno_dump_handle);
89*1a3d31e3SAndroid Build Coastguard Worker unplug_hist_free(dip->up_hist_handle);
90*1a3d31e3SAndroid Build Coastguard Worker rstat_free(dip->rstat_handle);
91*1a3d31e3SAndroid Build Coastguard Worker if (output_all_data)
92*1a3d31e3SAndroid Build Coastguard Worker q2d_free(dip->q2d_priv);
93*1a3d31e3SAndroid Build Coastguard Worker if (dip->pit_fp)
94*1a3d31e3SAndroid Build Coastguard Worker fclose(dip->pit_fp);
95*1a3d31e3SAndroid Build Coastguard Worker free(dip);
96*1a3d31e3SAndroid Build Coastguard Worker }
97*1a3d31e3SAndroid Build Coastguard Worker
dip_exit(void)98*1a3d31e3SAndroid Build Coastguard Worker void dip_exit(void)
99*1a3d31e3SAndroid Build Coastguard Worker {
100*1a3d31e3SAndroid Build Coastguard Worker struct list_head *p, *q;
101*1a3d31e3SAndroid Build Coastguard Worker
102*1a3d31e3SAndroid Build Coastguard Worker list_for_each_safe(p, q, &all_devs) {
103*1a3d31e3SAndroid Build Coastguard Worker struct d_info *dip = list_entry(p, struct d_info, all_head);
104*1a3d31e3SAndroid Build Coastguard Worker __dip_exit(dip);
105*1a3d31e3SAndroid Build Coastguard Worker }
106*1a3d31e3SAndroid Build Coastguard Worker }
107*1a3d31e3SAndroid Build Coastguard Worker
open_pit(struct d_info * dip)108*1a3d31e3SAndroid Build Coastguard Worker static inline FILE *open_pit(struct d_info *dip)
109*1a3d31e3SAndroid Build Coastguard Worker {
110*1a3d31e3SAndroid Build Coastguard Worker FILE *fp;
111*1a3d31e3SAndroid Build Coastguard Worker char str[256];
112*1a3d31e3SAndroid Build Coastguard Worker
113*1a3d31e3SAndroid Build Coastguard Worker sprintf(str, "%s_pit.dat", dip->dip_name);
114*1a3d31e3SAndroid Build Coastguard Worker if ((fp = my_fopen(str, "w")) == NULL)
115*1a3d31e3SAndroid Build Coastguard Worker perror(str);
116*1a3d31e3SAndroid Build Coastguard Worker
117*1a3d31e3SAndroid Build Coastguard Worker return fp;
118*1a3d31e3SAndroid Build Coastguard Worker }
119*1a3d31e3SAndroid Build Coastguard Worker
dip_alloc(__u32 device,struct io * iop)120*1a3d31e3SAndroid Build Coastguard Worker struct d_info *dip_alloc(__u32 device, struct io *iop)
121*1a3d31e3SAndroid Build Coastguard Worker {
122*1a3d31e3SAndroid Build Coastguard Worker struct d_info *dip = __dip_find(device);
123*1a3d31e3SAndroid Build Coastguard Worker
124*1a3d31e3SAndroid Build Coastguard Worker if (dip == NULL) {
125*1a3d31e3SAndroid Build Coastguard Worker dip = malloc(sizeof(struct d_info));
126*1a3d31e3SAndroid Build Coastguard Worker memset(dip, 0, sizeof(*dip));
127*1a3d31e3SAndroid Build Coastguard Worker dip->device = device;
128*1a3d31e3SAndroid Build Coastguard Worker dip->devmap = dev_map_find(device);
129*1a3d31e3SAndroid Build Coastguard Worker dip->last_q = (__u64)-1;
130*1a3d31e3SAndroid Build Coastguard Worker dip->heads = dip_rb_mkhds();
131*1a3d31e3SAndroid Build Coastguard Worker region_init(&dip->regions);
132*1a3d31e3SAndroid Build Coastguard Worker dip->start_time = BIT_TIME(iop->t.time);
133*1a3d31e3SAndroid Build Coastguard Worker dip->pre_culling = 1;
134*1a3d31e3SAndroid Build Coastguard Worker
135*1a3d31e3SAndroid Build Coastguard Worker mkhandle(dip, dip->dip_name, 256);
136*1a3d31e3SAndroid Build Coastguard Worker
137*1a3d31e3SAndroid Build Coastguard Worker latency_alloc(dip);
138*1a3d31e3SAndroid Build Coastguard Worker dip->aqd_handle = aqd_alloc(dip);
139*1a3d31e3SAndroid Build Coastguard Worker dip->bno_dump_handle = bno_dump_alloc(dip);
140*1a3d31e3SAndroid Build Coastguard Worker dip->up_hist_handle = unplug_hist_alloc(dip);
141*1a3d31e3SAndroid Build Coastguard Worker dip->seek_handle = seeki_alloc(dip, "_d2d");
142*1a3d31e3SAndroid Build Coastguard Worker dip->q2q_handle = seeki_alloc(dip, "_q2q");
143*1a3d31e3SAndroid Build Coastguard Worker dip->q2d_plat_handle = plat_alloc(dip, "_q2d");
144*1a3d31e3SAndroid Build Coastguard Worker dip->q2c_plat_handle = plat_alloc(dip, "_q2c");
145*1a3d31e3SAndroid Build Coastguard Worker dip->d2c_plat_handle = plat_alloc(dip, "_d2c");
146*1a3d31e3SAndroid Build Coastguard Worker dip->rstat_handle = rstat_alloc(dip);
147*1a3d31e3SAndroid Build Coastguard Worker dip->p_live_handle = p_live_alloc();
148*1a3d31e3SAndroid Build Coastguard Worker
149*1a3d31e3SAndroid Build Coastguard Worker if (per_io_trees)
150*1a3d31e3SAndroid Build Coastguard Worker dip->pit_fp = open_pit(dip);
151*1a3d31e3SAndroid Build Coastguard Worker
152*1a3d31e3SAndroid Build Coastguard Worker if (output_all_data)
153*1a3d31e3SAndroid Build Coastguard Worker dip->q2d_priv = q2d_alloc();
154*1a3d31e3SAndroid Build Coastguard Worker
155*1a3d31e3SAndroid Build Coastguard Worker list_add_tail(&dip->hash_head, &dev_heads[DEV_HASH(device)]);
156*1a3d31e3SAndroid Build Coastguard Worker list_add_tail(&dip->all_head, &all_devs);
157*1a3d31e3SAndroid Build Coastguard Worker n_devs++;
158*1a3d31e3SAndroid Build Coastguard Worker }
159*1a3d31e3SAndroid Build Coastguard Worker
160*1a3d31e3SAndroid Build Coastguard Worker if (dip->pre_culling) {
161*1a3d31e3SAndroid Build Coastguard Worker if (iop->type == IOP_Q || iop->type == IOP_A)
162*1a3d31e3SAndroid Build Coastguard Worker dip->pre_culling = 0;
163*1a3d31e3SAndroid Build Coastguard Worker else
164*1a3d31e3SAndroid Build Coastguard Worker return NULL;
165*1a3d31e3SAndroid Build Coastguard Worker }
166*1a3d31e3SAndroid Build Coastguard Worker
167*1a3d31e3SAndroid Build Coastguard Worker iop->linked = dip_rb_ins(dip, iop);
168*1a3d31e3SAndroid Build Coastguard Worker dip->end_time = BIT_TIME(iop->t.time);
169*1a3d31e3SAndroid Build Coastguard Worker
170*1a3d31e3SAndroid Build Coastguard Worker return dip;
171*1a3d31e3SAndroid Build Coastguard Worker }
172*1a3d31e3SAndroid Build Coastguard Worker
iop_rem_dip(struct io * iop)173*1a3d31e3SAndroid Build Coastguard Worker void iop_rem_dip(struct io *iop)
174*1a3d31e3SAndroid Build Coastguard Worker {
175*1a3d31e3SAndroid Build Coastguard Worker if (iop->linked) {
176*1a3d31e3SAndroid Build Coastguard Worker dip_rb_rem(iop);
177*1a3d31e3SAndroid Build Coastguard Worker iop->linked = 0;
178*1a3d31e3SAndroid Build Coastguard Worker }
179*1a3d31e3SAndroid Build Coastguard Worker }
180*1a3d31e3SAndroid Build Coastguard Worker
dip_foreach(struct io * iop,enum iop_type type,void (* fnc)(struct io * iop,struct io * this),int rm_after)181*1a3d31e3SAndroid Build Coastguard Worker void dip_foreach(struct io *iop, enum iop_type type,
182*1a3d31e3SAndroid Build Coastguard Worker void (*fnc)(struct io *iop, struct io *this), int rm_after)
183*1a3d31e3SAndroid Build Coastguard Worker {
184*1a3d31e3SAndroid Build Coastguard Worker if (rm_after) {
185*1a3d31e3SAndroid Build Coastguard Worker LIST_HEAD(head);
186*1a3d31e3SAndroid Build Coastguard Worker struct io *this;
187*1a3d31e3SAndroid Build Coastguard Worker struct list_head *p, *q;
188*1a3d31e3SAndroid Build Coastguard Worker
189*1a3d31e3SAndroid Build Coastguard Worker dip_rb_fe(iop->dip, type, iop, fnc, &head);
190*1a3d31e3SAndroid Build Coastguard Worker list_for_each_safe(p, q, &head) {
191*1a3d31e3SAndroid Build Coastguard Worker this = list_entry(p, struct io, f_head);
192*1a3d31e3SAndroid Build Coastguard Worker list_del(&this->f_head);
193*1a3d31e3SAndroid Build Coastguard Worker io_release(this);
194*1a3d31e3SAndroid Build Coastguard Worker }
195*1a3d31e3SAndroid Build Coastguard Worker } else
196*1a3d31e3SAndroid Build Coastguard Worker dip_rb_fe(iop->dip, type, iop, fnc, NULL);
197*1a3d31e3SAndroid Build Coastguard Worker }
198*1a3d31e3SAndroid Build Coastguard Worker
dip_foreach_list(struct io * iop,enum iop_type type,struct list_head * hd)199*1a3d31e3SAndroid Build Coastguard Worker void dip_foreach_list(struct io *iop, enum iop_type type, struct list_head *hd)
200*1a3d31e3SAndroid Build Coastguard Worker {
201*1a3d31e3SAndroid Build Coastguard Worker dip_rb_fe(iop->dip, type, iop, NULL, hd);
202*1a3d31e3SAndroid Build Coastguard Worker }
203*1a3d31e3SAndroid Build Coastguard Worker
dip_find_sec(struct d_info * dip,enum iop_type type,__u64 sec)204*1a3d31e3SAndroid Build Coastguard Worker struct io *dip_find_sec(struct d_info *dip, enum iop_type type, __u64 sec)
205*1a3d31e3SAndroid Build Coastguard Worker {
206*1a3d31e3SAndroid Build Coastguard Worker return dip_rb_find_sec(dip, type, sec);
207*1a3d31e3SAndroid Build Coastguard Worker }
208*1a3d31e3SAndroid Build Coastguard Worker
dip_foreach_out(void (* func)(struct d_info *,void *),void * arg)209*1a3d31e3SAndroid Build Coastguard Worker void dip_foreach_out(void (*func)(struct d_info *, void *), void *arg)
210*1a3d31e3SAndroid Build Coastguard Worker {
211*1a3d31e3SAndroid Build Coastguard Worker if (devices == NULL) {
212*1a3d31e3SAndroid Build Coastguard Worker struct list_head *p;
213*1a3d31e3SAndroid Build Coastguard Worker __list_for_each(p, &all_devs)
214*1a3d31e3SAndroid Build Coastguard Worker func(list_entry(p, struct d_info, all_head), arg);
215*1a3d31e3SAndroid Build Coastguard Worker } else {
216*1a3d31e3SAndroid Build Coastguard Worker int i;
217*1a3d31e3SAndroid Build Coastguard Worker struct d_info *dip;
218*1a3d31e3SAndroid Build Coastguard Worker unsigned int mjr, mnr;
219*1a3d31e3SAndroid Build Coastguard Worker char *p = devices;
220*1a3d31e3SAndroid Build Coastguard Worker
221*1a3d31e3SAndroid Build Coastguard Worker while (p && ((i = sscanf(p, "%u,%u", &mjr, &mnr)) == 2)) {
222*1a3d31e3SAndroid Build Coastguard Worker dip = __dip_find((__u32)((mjr << MINORBITS) | mnr));
223*1a3d31e3SAndroid Build Coastguard Worker func(dip, arg);
224*1a3d31e3SAndroid Build Coastguard Worker p = strchr(p, ';');
225*1a3d31e3SAndroid Build Coastguard Worker if (p) p++;
226*1a3d31e3SAndroid Build Coastguard Worker }
227*1a3d31e3SAndroid Build Coastguard Worker }
228*1a3d31e3SAndroid Build Coastguard Worker }
229*1a3d31e3SAndroid Build Coastguard Worker
dip_plug(__u32 dev,double cur_time)230*1a3d31e3SAndroid Build Coastguard Worker void dip_plug(__u32 dev, double cur_time)
231*1a3d31e3SAndroid Build Coastguard Worker {
232*1a3d31e3SAndroid Build Coastguard Worker struct d_info *dip = __dip_find(dev);
233*1a3d31e3SAndroid Build Coastguard Worker
234*1a3d31e3SAndroid Build Coastguard Worker if (dip && !dip->is_plugged) {
235*1a3d31e3SAndroid Build Coastguard Worker dip->is_plugged = 1;
236*1a3d31e3SAndroid Build Coastguard Worker dip->last_plug = cur_time;
237*1a3d31e3SAndroid Build Coastguard Worker }
238*1a3d31e3SAndroid Build Coastguard Worker }
239*1a3d31e3SAndroid Build Coastguard Worker
unplug(struct d_info * dip,double cur_time)240*1a3d31e3SAndroid Build Coastguard Worker static inline void unplug(struct d_info *dip, double cur_time)
241*1a3d31e3SAndroid Build Coastguard Worker {
242*1a3d31e3SAndroid Build Coastguard Worker dip->is_plugged = 0;
243*1a3d31e3SAndroid Build Coastguard Worker dip->plugged_time += (cur_time - dip->last_plug);
244*1a3d31e3SAndroid Build Coastguard Worker }
245*1a3d31e3SAndroid Build Coastguard Worker
dip_unplug(__u32 dev,double cur_time,__u64 nios_up)246*1a3d31e3SAndroid Build Coastguard Worker void dip_unplug(__u32 dev, double cur_time, __u64 nios_up)
247*1a3d31e3SAndroid Build Coastguard Worker {
248*1a3d31e3SAndroid Build Coastguard Worker struct d_info *dip = __dip_find(dev);
249*1a3d31e3SAndroid Build Coastguard Worker
250*1a3d31e3SAndroid Build Coastguard Worker if (dip && dip->is_plugged) {
251*1a3d31e3SAndroid Build Coastguard Worker dip->nplugs++;
252*1a3d31e3SAndroid Build Coastguard Worker dip->nios_up += nios_up;
253*1a3d31e3SAndroid Build Coastguard Worker unplug(dip, cur_time);
254*1a3d31e3SAndroid Build Coastguard Worker }
255*1a3d31e3SAndroid Build Coastguard Worker }
256*1a3d31e3SAndroid Build Coastguard Worker
dip_unplug_tm(__u32 dev,double cur_time,__u64 nios_up)257*1a3d31e3SAndroid Build Coastguard Worker void dip_unplug_tm(__u32 dev, double cur_time, __u64 nios_up)
258*1a3d31e3SAndroid Build Coastguard Worker {
259*1a3d31e3SAndroid Build Coastguard Worker struct d_info *dip = __dip_find(dev);
260*1a3d31e3SAndroid Build Coastguard Worker
261*1a3d31e3SAndroid Build Coastguard Worker if (dip && dip->is_plugged) {
262*1a3d31e3SAndroid Build Coastguard Worker dip->nios_upt += nios_up;
263*1a3d31e3SAndroid Build Coastguard Worker dip->nplugs_t++;
264*1a3d31e3SAndroid Build Coastguard Worker unplug(dip, cur_time);
265*1a3d31e3SAndroid Build Coastguard Worker }
266*1a3d31e3SAndroid Build Coastguard Worker }
267*1a3d31e3SAndroid Build Coastguard Worker
dip_cleanup(void)268*1a3d31e3SAndroid Build Coastguard Worker void dip_cleanup(void)
269*1a3d31e3SAndroid Build Coastguard Worker {
270*1a3d31e3SAndroid Build Coastguard Worker struct list_head *p, *q;
271*1a3d31e3SAndroid Build Coastguard Worker
272*1a3d31e3SAndroid Build Coastguard Worker list_for_each_safe(p, q, &all_devs) {
273*1a3d31e3SAndroid Build Coastguard Worker struct d_info *dip = list_entry(p, struct d_info, all_head);
274*1a3d31e3SAndroid Build Coastguard Worker
275*1a3d31e3SAndroid Build Coastguard Worker if (dip->n_qs == 0 && dip->n_ds == 0)
276*1a3d31e3SAndroid Build Coastguard Worker __dip_exit(dip);
277*1a3d31e3SAndroid Build Coastguard Worker }
278*1a3d31e3SAndroid Build Coastguard Worker }
279