1e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/*
2e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * blktrace output analysis: generate a timeline & gather statistics
3e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
4e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.com>
5e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
6e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  This program is free software; you can redistribute it and/or modify
7e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  it under the terms of the GNU General Public License as published by
8e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  the Free Software Foundation; either version 2 of the License, or
9e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  (at your option) any later version.
10e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
11e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  This program is distributed in the hope that it will be useful,
12e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  GNU General Public License for more details.
15e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
16e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  You should have received a copy of the GNU General Public License
17e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  along with this program; if not, write to the Free Software
18e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
20e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */
21e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
22e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int remapper_dev(__u32 dev)
23e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
24e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	int mjr = MAJOR(dev);
25e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return mjr == 9 || mjr == 253 || mjr == 254;
26e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
27e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
28e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void region_init(struct region_info *reg)
29e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
30e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	INIT_LIST_HEAD(&reg->qranges);
31e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	INIT_LIST_HEAD(&reg->cranges);
32e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
33e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
34e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __region_exit(struct list_head *range_head)
35e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
36e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct list_head *p, *q;
37e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct range_info *rip;
38e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
39e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	list_for_each_safe(p, q, range_head) {
40e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		rip = list_entry(p, struct range_info, head);
41e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		free(rip);
42e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
43e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
44e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
45e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void region_exit(struct region_info *reg)
46e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
47e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__region_exit(&reg->qranges);
48e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__region_exit(&reg->cranges);
49e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
50e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
51e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_range(struct list_head *head_p, __u64 time)
52e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
53e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct range_info *rip;
54e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
55e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (!list_empty(head_p)) {
56e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		rip = list_entry(head_p->prev, struct range_info, head);
57e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
58e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (time < rip->end)
59e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			return;
60e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
61e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (BIT_TIME(time - rip->end) < range_delta) {
62e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			rip->end = time;
63e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			return;
64e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
65e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
66e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
67e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	rip = malloc(sizeof(*rip));
68e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	rip->start = rip->end = time;
69e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	list_add_tail(&rip->head, head_p);
70e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
71e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
72e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_qregion(struct region_info *reg, __u64 time)
73e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
74e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	update_range(&reg->qranges, time);
75e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
76e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
77e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_cregion(struct region_info *reg, __u64 time)
78e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
79e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	update_range(&reg->cranges, time);
80e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
81e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
82e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void avg_update(struct avg_info *ap, __u64 t)
83e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
84e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat        if (ap->n++ == 0)
85e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat                ap->min = ap->total = ap->max = t;
86e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat        else {
87e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat                if (t < ap->min)
88e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat                        ap->min = t;
89e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat                else if (t > ap->max)
90e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat                        ap->max = t;
91e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat                ap->total += t;
92e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat        }
93e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
94e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
95e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void avg_update_n(struct avg_info *ap, __u64 t, int n)
96e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
97e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat        if (ap->n == 0) {
98e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat                ap->min = ap->max = t;
99e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		ap->total = (n * t);
100e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	} else {
101e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat                if (t < ap->min)
102e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat                        ap->min = t;
103e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat                else if (t > ap->max)
104e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat                        ap->max = t;
105e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat                ap->total += (n * t);
106e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat        }
107e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
108e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	ap->n += n;
109e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
110e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
111e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void avg_unupdate(struct avg_info *ap, __u64 t)
112e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
113e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	ap->n--;
114e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	ap->total -= t;
115e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
116e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
117e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_lq(__u64 *last_q, struct avg_info *avg, __u64 time)
118e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
119e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (*last_q != ((__u64)-1))
120e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		avg_update(avg, (time > *last_q) ? time - *last_q : 1);
121e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	*last_q = time;
122e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
123e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
124e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void dip_update_q(struct d_info *dip, struct io *iop)
125e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
126e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (remapper_dev(dip->device))
127e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		update_lq(&dip->last_q, &dip->avgs.q2q_dm, iop->t.time);
128e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	else
129e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		update_lq(&dip->last_q, &dip->avgs.q2q, iop->t.time);
130e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	update_qregion(&dip->regions, iop->t.time);
131e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
132e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
133e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline struct io *io_alloc(void)
134e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
135e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct io *iop = malloc(sizeof(*iop));
136e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
137e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	memset(iop, 0, sizeof(struct io));
138e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	list_add_tail(&iop->a_head, &all_ios);
139e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
140e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return iop;
141e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
142e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
143e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void io_free(struct io *iop)
144e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
145e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	list_del(&iop->a_head);
146e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	free(iop);
147e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
148e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
149e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void io_free_all(void)
150e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
151e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct io *iop;
152e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct list_head *p, *q;
153e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
154e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	list_for_each_safe(p, q, &all_ios) {
155e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		iop = list_entry(p, struct io, a_head);
156e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		free(iop);
157e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
158e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
159e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
160e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int io_setup(struct io *iop, enum iop_type type)
161e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
162e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	iop->type = type;
163e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	iop->dip = dip_alloc(iop->t.device, iop);
164e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (iop->linked) {
165e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		iop->pip = find_process(iop->t.pid, NULL);
166e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		iop->bytes_left = iop->t.bytes;
167e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
168e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
169e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return iop->linked;
170e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
171e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
172e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void io_release(struct io *iop)
173e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
174e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (iop->linked)
175e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		iop_rem_dip(iop);
176e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (iop->pdu)
177e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		free(iop->pdu);
178e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
179e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	io_free(iop);
180e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
181e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
182e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define UPDATE_AVGS(_avg, _iop, _pip, _time) do {			\
183e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		avg_update(&all_avgs. _avg , _time);			\
184e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		avg_update(&_iop->dip->avgs. _avg , _time);		\
185e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (_pip) avg_update(&_pip->avgs. _avg , _time);	\
186e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	} while (0)
187e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
188e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define UPDATE_AVGS_N(_avg, _iop, _pip, _time, _n) do {			\
189e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		avg_update_n(&all_avgs. _avg , _time, _n);		\
190e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		avg_update_n(&_iop->dip->avgs. _avg , _time, _n);	\
191e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (_pip) avg_update_n(&_pip->avgs. _avg , _time,_n);	\
192e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	} while (0)
193e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
194e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define UNUPDATE_AVGS(_avg, _iop, _pip, _time) do {			\
195e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		avg_unupdate(&all_avgs. _avg , _time);			\
196e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		avg_unupdate(&_iop->dip->avgs. _avg , _time);		\
197e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (_pip) avg_unupdate(&_pip->avgs. _avg , _time);	\
198e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	} while (0)
199e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
200e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_q2c(struct io *iop, __u64 c_time)
201e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
202e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (remapper_dev(iop->dip->device))
203e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		UPDATE_AVGS(q2c_dm, iop, iop->pip, c_time);
204e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	else
205e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		UPDATE_AVGS(q2c, iop, iop->pip, c_time);
206e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
207e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
208e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_q2a(struct io *iop, __u64 a_time)
209e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
210e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (remapper_dev(iop->dip->device))
211e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		UPDATE_AVGS(q2a_dm, iop, iop->pip, a_time);
212e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	else
213e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		UPDATE_AVGS(q2a, iop, iop->pip, a_time);
214e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
215e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
216e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_q2g(struct io *iop, __u64 g_time)
217e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
218e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	UPDATE_AVGS(q2g, iop, iop->pip, g_time);
219e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
220e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
221e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_s2g(struct io *iop, __u64 g_time)
222e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
223e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	UPDATE_AVGS(s2g, iop, iop->pip, g_time);
224e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
225e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
226e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void unupdate_q2g(struct io *iop, __u64 g_time)
227e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
228e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	UNUPDATE_AVGS(q2g, iop, iop->pip, g_time);
229e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
230e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
231e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_g2i(struct io *iop, __u64 i_time)
232e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
233e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	UPDATE_AVGS(g2i, iop, iop->pip, i_time);
234e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
235e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
236e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void unupdate_g2i(struct io *iop, __u64 i_time)
237e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
238e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	UNUPDATE_AVGS(g2i, iop, iop->pip, i_time);
239e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
240e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
241e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_q2m(struct io *iop, __u64 m_time)
242e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
243e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	UPDATE_AVGS(q2m, iop, iop->pip, m_time);
244e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
245e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
246e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void unupdate_q2m(struct io *iop, __u64 m_time)
247e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
248e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	UNUPDATE_AVGS(q2m, iop, iop->pip, m_time);
249e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
250e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
251e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_i2d(struct io *iop, __u64 d_time)
252e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
253e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	UPDATE_AVGS(i2d, iop, iop->pip, d_time);
254e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
255e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
256e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void unupdate_i2d(struct io *iop, __u64 d_time)
257e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
258e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	UNUPDATE_AVGS(i2d, iop, iop->pip, d_time);
259e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
260e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
261e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_m2d(struct io *iop, __u64 d_time)
262e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
263e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	UPDATE_AVGS(m2d, iop, iop->pip, d_time);
264e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
265e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
266e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void unupdate_m2d(struct io *iop, __u64 d_time)
267e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
268e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	UNUPDATE_AVGS(m2d, iop, iop->pip, d_time);
269e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
270e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
271e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_d2c(struct io *iop, __u64 c_time)
272e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
273e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	UPDATE_AVGS(d2c, iop, iop->pip, c_time);
274e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
275e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
276e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_blks(struct io *iop)
277e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
278e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__u64 nblks = iop->t.bytes >> 9;
279e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	avg_update(&all_avgs.blks, nblks);
280e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	avg_update(&iop->dip->avgs.blks, nblks);
281e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (iop->pip)
282e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		avg_update(&iop->pip->avgs.blks, nblks);
283e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
284e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
285e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline struct rb_root *__get_root(struct d_info *dip, enum iop_type type)
286e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
287e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct rb_root *roots = dip->heads;
288e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return &roots[type];
289e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
290e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
291e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int dip_rb_ins(struct d_info *dip, struct io *iop)
292e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
293e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return rb_insert(__get_root(dip, iop->type), iop);
294e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
295e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
296e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void dip_rb_rem(struct io *iop)
297e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
298e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	rb_erase(&iop->rb_node, __get_root(iop->dip, iop->type));
299e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
300e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
301e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void dip_rb_fe(struct d_info *dip, enum iop_type type,
302e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		             struct io *iop,
303e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			     void (*fnc)(struct io *iop, struct io *this),
304e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			     struct list_head *head)
305e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
306e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	rb_foreach(__get_root(dip, type)->rb_node, iop, fnc, head);
307e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
308e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
309e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline struct io *dip_rb_find_sec(struct d_info *dip,
310e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		                         enum iop_type type, __u64 sec)
311e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
312e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return rb_find_sec(__get_root(dip, type), sec);
313e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
314e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
315e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline __u64 tdelta(__u64 from, __u64 to)
316e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
317e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return (from < to) ? (to - from) : 1;
318e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
319e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
320e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int type2c(enum iop_type type)
321e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
322e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	int c;
323e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
324e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	switch (type) {
325e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	case IOP_Q: c = 'Q'; break;
326e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	case IOP_X: c = 'X'; break;
327e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	case IOP_A: c = 'A'; break;
328e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	case IOP_I: c = 'I'; break;
329e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	case IOP_M: c = 'M'; break;
330e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	case IOP_D: c = 'D'; break;
331e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	case IOP_C: c = 'C'; break;
332e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	case IOP_R: c = 'R'; break;
333e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	case IOP_G: c = 'G'; break;
334e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	default   : c = '?'; break;
335e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
336e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
337e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return c;
338e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
339e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
340e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int histo_idx(__u64 nbytes)
341e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
342e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	int idx = (nbytes >> 9) - 1;
343e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return min(idx, N_HIST_BKTS-1);
344e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
345e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
346e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_q_histo(__u64 nbytes)
347e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
348e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	q_histo[histo_idx(nbytes)]++;
349e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
350e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
351e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void update_d_histo(__u64 nbytes)
352e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
353e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	d_histo[histo_idx(nbytes)]++;
354e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
355e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
356e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline struct io *io_first_list(struct list_head *head)
357e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
358e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (list_empty(head))
359e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		return NULL;
360e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
361e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return list_entry(head->next, struct io, f_head);
362e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
363e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
364e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __dump_iop(FILE *ofp, struct io *iop, int extra_nl)
365e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
366e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%5d.%09lu %3d,%-3d %c %10llu+%-4u\n",
367e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		(int)SECONDS(iop->t.time),
368e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		(unsigned long)NANO_SECONDS(iop->t.time),
369e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		MAJOR(iop->t.device), MINOR(iop->t.device), type2c(iop->type),
370e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		(unsigned long long)iop->t.sector, t_sec(&iop->t));
371e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (extra_nl) fprintf(ofp, "\n");
372e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
373e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
374e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __dump_iop2(FILE *ofp, struct io *a_iop, struct io *l_iop)
375e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
376e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%5d.%09lu %3d,%-3d %c %10llu+%-4u <- (%3d,%-3d) %10llu\n",
377e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		(int)SECONDS(a_iop->t.time),
378e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		(unsigned long)NANO_SECONDS(a_iop->t.time),
379e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		MAJOR(a_iop->t.device), MINOR(a_iop->t.device),
380e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		type2c(a_iop->type), (unsigned long long)a_iop->t.sector,
381e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		t_sec(&a_iop->t), MAJOR(l_iop->t.device),
382e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		MINOR(l_iop->t.device), (unsigned long long)l_iop->t.sector);
383e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
384