Commit a716ce6e authored by Bas Zoetekouw's avatar Bas Zoetekouw Committed by Dmitry Smirnov

Imported Debian snapshot 0~git-20070910192508-1

parent ec3b65f7
......@@ -5,7 +5,11 @@ PROGS = blkparse blktrace verify_blkparse blkrawverify
LIBS = -lpthread
SCRIPTS = btrace
all: $(PROGS) $(SCRIPTS)
ALL = $(PROGS) $(SCRIPTS) btt/btt
all: $(ALL)
btt/btt:
$(MAKE) -C btt
%.o: %.c
......@@ -39,6 +43,7 @@ depend:
INSTALL = install
prefix = /usr/local
bindir = $(prefix)/bin
mandir = $(prefix)/man
RPMBUILD = rpmbuild
TAR = tar
......@@ -59,10 +64,13 @@ clean: docsclean
-rm -f *.o $(PROGS) .depend btrace-1.0.tar.bz2
$(MAKE) -C btt clean
install: $(PROGS) $(SCRIPTS)
$(INSTALL) -m755 -d $(DESTDIR)$(bindir)
$(INSTALL) $(PROGS) $(SCRIPTS) $(DESTDIR)$(bindir)
$(INSTALL) btt/btt $(DESTDIR)$(bindir)
install: all
$(INSTALL) -m 755 -d $(DESTDIR)$(bindir)
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man8
$(INSTALL) -m 755 $(ALL) $(DESTDIR)$(bindir)
$(INSTALL) -m 644 doc/*.1 $(DESTDIR)$(mandir)/man1
$(INSTALL) -m 644 doc/*.8 $(DESTDIR)$(mandir)/man8
ifneq ($(wildcard .depend),)
include .depend
......
......@@ -36,7 +36,7 @@
#include "rbtree.h"
#include "jhash.h"
static char blkparse_version[] = "0.99.2";
static char blkparse_version[] = "0.99.3";
struct skip_info {
unsigned long start, end;
......
......@@ -47,7 +47,7 @@
#include "blktrace.h"
#include "barrier.h"
static char blktrace_version[] = "0.99.2";
static char blktrace_version[] = "0.99.3";
/*
* You may want to increase this even more, if you are logging at a high
......
......@@ -6,41 +6,40 @@
#
CC = gcc
CFLAGS = -Wall -W -O2 -g
INCS = -I. -I..
OCFLAGS = -UCOUNT_IOS -UDEBUG -DNDEBUG
XCFLAGS = -Wall -W -g -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
CFLAGS = $(INCS) -O2 $(XCFLAGS) $(OCFLAGS)
XCFLAGS = -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
override CFLAGS += $(INCS) $(XCFLAGS) $(OCFLAGS)
PROGS = btt
LIBS = $(PLIBS) $(ELIBS)
OBJS = args.o bt_timeline.o devmap.o devs.o dip_rb.o iostat.o latency.o \
misc.o output.o proc.o seek.o trace.o trace_complete.o trace_im.o \
trace_issue.o trace_queue.o trace_remap.o trace_requeue.o rbtree.o \
mmap.o trace_plug.o bno_dump.o unplug_hist.o
trace_issue.o trace_queue.o trace_remap.o trace_requeue.o \
../rbtree.o mmap.o trace_plug.o bno_dump.o unplug_hist.o
all: depend $(PROGS)
rbtree.o: ../rbtree.c
$(CC) -o $*.o -c $(CFLAGS) $<
.PHONY : depend
depend: $(patsubst %.o,%.c,$(filter %.o,$(OBJS)))
@$(CC) -MM $(CFLAGS) -I.. $^ 1> .depend
depend:
@$(CC) -MM $(CFLAGS) -I.. *.c 1> .depend
docs:
$(MAKE) -C doc all
docsclean:
$(MAKE) -C doc clean
clean: docsclean
-rm -f *.o $(PROGS) .depend
%.o: %.c
$(CC) -o $*.o -c $(CFLAGS) $<
$(CC) $(CFLAGS) -c -o $*.o $<
btt: $(OBJS)
$(CC) $(CFLAGS) -o $@ $(filter %.o,$^) $(LIBS)
docs:
$(MAKE) -C doc all
docsclean:
$(MAKE) -C doc clean
ifneq ($(wildcard .depend),)
include .depend
endif
......@@ -25,7 +25,7 @@
#include <time.h>
#include "globals.h"
char bt_timeline_version[] = "0.99.1";
char bt_timeline_version[] = "2.00";
char *devices, *exes, *input_name, *output_name, *seek_name, *bno_dump_name;
char *d2c_name, *q2c_name, *per_io_name, *unplug_hist_name;
......@@ -40,13 +40,10 @@ LIST_HEAD(all_devs);
LIST_HEAD(all_procs);
LIST_HEAD(free_ios);
LIST_HEAD(free_bilinks);
LIST_HEAD(rmhd);
LIST_HEAD(retries);
__u64 q_histo[N_HIST_BKTS], d_histo[N_HIST_BKTS];
double range_delta = 0.1;
__u64 last_q = (__u64)-1;
__u64 next_retry_check = 0;
struct region_info all_regions = {
.qranges = LIST_HEAD_INIT(all_regions.qranges),
......@@ -90,7 +87,6 @@ int main(int argc, char *argv[])
dip_exit();
pip_exit();
io_free_all();
bilink_free_all();
region_exit(&all_regions);
free(input_name);
......@@ -120,7 +116,6 @@ int process(void)
}
io_release(iop);
do_retries(0);
gettimeofday(&tve, NULL);
if (verbose) {
......
......@@ -58,10 +58,7 @@ void __dump_rb_node(struct rb_node *n)
struct io *iop = rb_entry(n, struct io, rb_node);
dbg_ping();
if (iop->type == IOP_A)
__dump_iop2(stdout, iop, bilink_first_down(iop, NULL));
else
__dump_iop(stdout, iop, 0);
__dump_iop(stdout, iop, 0);
if (n->rb_left)
__dump_rb_node(n->rb_left);
if (n->rb_right)
......@@ -92,10 +89,8 @@ void dump_rb_trees(void)
dip = list_entry(p, struct d_info, hash_head);
printf("Trees for %3d,%-3d\n", MAJOR(dip->device),
MINOR(dip->device));
for (type = IOP_Q; type < N_IOP_TYPES; type++) {
if (type != IOP_L)
__dump_rb_tree(dip, type);
}
for (type = IOP_Q; type < N_IOP_TYPES; type++)
__dump_rb_tree(dip, type);
}
}
}
......@@ -133,17 +128,29 @@ void dip_exit(void)
__destroy_heads(dip->heads);
region_exit(&dip->regions);
seeki_exit(dip->seek_handle);
seeki_exit(dip->q2q_handle);
bno_dump_exit(dip->bno_dump_handle);
unplug_hist_exit(dip->unplug_hist_handle);
free(dip);
}
}
static inline char *mkhandle(char *str, __u32 device, char *post)
{
int mjr = device >> MINORBITS;
int mnr = device & ((1 << MINORBITS) - 1);
sprintf(str, "%03d,%03d%s", mjr, mnr, post);
return str;
}
struct d_info *dip_add(__u32 device, struct io *iop)
{
struct d_info *dip = __dip_find(device);
if (dip == NULL) {
char str[256];
dip = malloc(sizeof(struct d_info));
memset(dip, 0, sizeof(*dip));
dip->heads = dip_rb_mkhds();
......@@ -151,9 +158,10 @@ struct d_info *dip_add(__u32 device, struct io *iop)
dip->device = device;
dip->last_q = (__u64)-1;
dip->map = dev_map_find(device);
dip->seek_handle = seeki_init(device);
dip->bno_dump_handle = bno_dump_init(device);
dip->unplug_hist_handle = unplug_hist_init(device);
dip->seek_handle = seeki_init(mkhandle(str, device, "_d2d"));
dip->q2q_handle = seeki_init(mkhandle(str, device, "_q2q"));
latency_init(dip);
list_add_tail(&dip->hash_head, &dev_heads[DEV_HASH(device)]);
list_add_tail(&dip->all_head, &all_devs);
......
This diff is collapsed.
\begin{verbatim}
==================== All Devices ====================
ALL MIN AVG MAX N
--------------- ------------- ------------- ------------- -----------
Q2Q 0.000000001 0.000171953 0.248458647 3163303
Q2A 0.000285034 0.000285034 0.000285034 1
Q2I 0.000000400 0.000010041 0.004243885 3163305
I2D 0.000000001 0.000048286 0.077015932 3163304
D2C 0.000000001 0.001732394 0.360111706 3163299
Q2C 0.000131596 0.001790722 0.360143154 3163299
\end{verbatim}\newpage\begin{verbatim}
==================== Device Overhead ====================
DEV | Q2I I2D D2C
---------- | ------ ------ ------
( 65, 16) | 0.5% 8.1% 91.4%
( 65,176) | 0.5% 1.5% 98.0%
( 65,160) | 0.5% 1.5% 98.0%
( 65,192) | 0.5% 1.2% 98.3%
( 65,208) | 0.5% 6.1% 93.4%
( 65,240) | 0.5% 1.1% 98.3%
( 65,224) | 0.5% 5.8% 93.7%
( 66, 0) | 0.6% 1.1% 98.3%
( 66, 16) | 0.6% 1.1% 98.3%
( 66, 32) | 0.6% 1.1% 98.3%
( 66, 48) | 0.6% 1.0% 98.4%
( 65, 32) | 0.6% 9.7% 89.7%
( 66, 64) | 0.6% 3.1% 96.3%
( 65, 48) | 0.6% 1.5% 97.9%
( 65, 64) | 0.6% 1.5% 98.0%
( 65, 80) | 0.6% 1.5% 98.0%
( 65, 96) | 0.6% 1.4% 98.0%
( 65,112) | 0.6% 1.4% 98.0%
( 65,128) | 0.6% 1.4% 98.0%
( 65,144) | 0.6% 1.3% 98.1%
\end{verbatim}\newpage\begin{verbatim}
==================== Device Merge Information ====================
DEV | #Q #D Ratio | BLKmin BLKavg BLKmax Total
---------- | -------- -------- ------- | -------- -------- -------- --------
( 65, 16) | 165163 163803 1.0 | 1 9 104 1605272
( 65,176) | 159070 158236 1.0 | 8 9 96 1524016
( 65,160) | 159580 158705 1.0 | 1 9 120 1525712
( 65,192) | 158697 157879 1.0 | 8 9 96 1520184
( 65,208) | 161893 161061 1.0 | 3 9 96 1544184
( 65,240) | 157983 157175 1.0 | 8 9 128 1512600
( 65,224) | 162596 161750 1.0 | 6 9 120 1575528
( 66, 0) | 158474 157646 1.0 | 8 9 96 1518704
( 66, 16) | 158453 157656 1.0 | 8 9 112 1516704
( 66, 32) | 156270 155467 1.0 | 8 9 112 1499744
( 66, 48) | 156296 155472 1.0 | 8 9 96 1501064
( 65, 32) | 162500 161664 1.0 | 1 10 128 1625368
( 66, 64) | 157908 156648 1.0 | 1 9 96 1504648
( 65, 48) | 155031 154203 1.0 | 8 9 128 1490840
( 65, 64) | 155879 155042 1.0 | 8 9 128 1495192
( 65, 80) | 155590 154756 1.0 | 6 9 128 1494080
( 65, 96) | 155967 155139 1.0 | 6 9 96 1500504
( 65,112) | 155780 154968 1.0 | 8 9 128 1495784
( 65,128) | 154916 154105 1.0 | 8 9 128 1487712
( 65,144) | 155253 154440 1.0 | 8 9 128 1491592
---------- | -------- -------- ------- | -------- -------- -------- --------
DEV | #Q #D Ratio | BLKmin BLKavg BLKmax Total
TOTAL | 3163299 3145815 1.0 | 1 9 128 30429432
\end{verbatim}\newpage\begin{verbatim}
==================== Device Q2Q Seek Information ====================
DEV | NSEEKS MEAN MEDIAN | MODE
---------- | --------------- --------------- --------------- | ---------------
( 65, 16) | 165164 34513601.2 0 | 0(10240)
( 65,176) | 159070 35875810.3 0 | 0(7279)
( 65,160) | 159580 35686855.3 0 | 0(7396)
( 65,192) | 158697 35873254.0 0 | 0(7097)
( 65,208) | 161895 35251205.6 0 | 0(8950)
( 65,240) | 157983 35690510.7 0 | 0(7058)
( 65,224) | 162597 35215774.0 0 | 0(8931)
( 66, 0) | 158474 35679927.3 0 | 0(7089)
( 66, 16) | 158453 35953391.0 0 | 0(7115)
( 66, 32) | 156270 35835785.0 0 | 0(7107)
( 66, 48) | 156296 35693042.3 0 | 0(7135)
( 65, 32) | 162501 34412411.2 0 | 0(7749)
( 66, 64) | 157908 35159261.5 0 | 0(9040)
( 65, 48) | 155031 35670294.2 0 | 0(7010)
( 65, 64) | 155879 35634563.5 0 | 0(7094)
( 65, 80) | 155590 35768901.5 0 | 0(7126)
( 65, 96) | 155967 35774790.5 0 | 0(7160)
( 65,112) | 155780 35715302.8 0 | 0(7096)
( 65,128) | 154916 35863718.6 0 | 0(7102)
( 65,144) | 155253 35831897.7 0 | 0(7158)
---------- | --------------- --------------- --------------- | ---------------
Overall | NSEEKS MEAN MEDIAN | MODE
Average | 3163304 35549147.0 0 | 0(151932)
\end{verbatim}\newpage\begin{verbatim}
==================== Device D2D Seek Information ====================
DEV | NSEEKS MEAN MEDIAN | MODE
---------- | --------------- --------------- --------------- | ---------------
( 65, 16) | 163803 34673643.1 0 | 0(9165)
( 65,176) | 158236 36061875.3 0 | 0(6488)
( 65,160) | 158705 35885601.9 0 | 0(6575)
( 65,192) | 157879 36058734.5 0 | 0(6294)
( 65,208) | 161061 35327230.2 0 | 0(8538)
( 65,240) | 157175 35867982.1 0 | 0(6282)
( 65,224) | 161750 35312998.9 0 | 0(8512)
( 66, 0) | 157646 35867654.4 0 | 0(6287)
( 66, 16) | 157656 36130706.7 0 | 0(6355)
( 66, 32) | 155467 36012662.4 0 | 0(6334)
( 66, 48) | 155472 35867912.7 0 | 0(6346)
( 65, 32) | 161664 34441442.0 0 | 0(7107)
( 66, 64) | 156648 35403718.1 0 | 0(7957)
( 65, 48) | 154203 35841703.8 0 | 0(6214)
( 65, 64) | 155042 35821650.7 0 | 0(6294)
( 65, 80) | 154756 35957188.1 0 | 0(6318)
( 65, 96) | 155139 35961290.3 0 | 0(6345)
( 65,112) | 154968 35897688.9 0 | 0(6299)
( 65,128) | 154105 36039309.9 0 | 0(6306)
( 65,144) | 154440 36008517.2 0 | 0(6381)
---------- | --------------- --------------- --------------- | ---------------
Overall | NSEEKS MEAN MEDIAN | MODE
Average | 3145815 35715829.0 0 | 0(136397)
\end{verbatim}\newpage\begin{verbatim}
==================== Plug Information ====================
DEV | # Plugs # Timer Us | % Time Q Plugged
---------- | ---------- ---------- | ----------------
( 65, 16) | 2( 1) | 0.183841368%
( 65, 32) | 2( 1) | 0.207033397%
( 65, 48) | 2( 1) | 0.207120028%
( 65, 64) | 2( 1) | 0.207174813%
( 65, 80) | 2( 1) | 0.207215340%
( 65, 96) | 2( 1) | 0.207275962%
( 65,112) | 2( 1) | 0.207305990%
( 65,128) | 2( 1) | 0.207349645%
( 65,144) | 2( 1) | 0.207413334%
---------- | ---------- ---------- | ----------------
Overall | # Plugs # Timer Us | % Time Q Plugged
Average | 2( 1) | 0.204636653%
\end{verbatim}
......@@ -72,14 +72,14 @@ enum iop_type {
IOP_Q = 0,
IOP_X = 1,
IOP_A = 2,
IOP_I = 3,
IOP_G = 3,
IOP_M = 4,
IOP_D = 5,
IOP_C = 6,
IOP_R = 7,
IOP_L = 8, // IOP_A -> IOP_A + IOP_L
IOP_I = 8
};
#define N_IOP_TYPES (IOP_L + 1)
#define N_IOP_TYPES (IOP_I + 1)
struct file_info {
struct file_info *next;
......@@ -158,7 +158,7 @@ struct d_info {
void *heads;
struct region_info regions;
struct devmap *map;
void *seek_handle, *bno_dump_handle, *unplug_hist_handle;
void *q2q_handle, *seek_handle, *bno_dump_handle, *unplug_hist_handle;
FILE *d2c_ofp, *q2c_ofp;
struct avgs_info avgs;
struct stats stats, all_stats;
......@@ -172,26 +172,23 @@ struct d_info {
struct io {
struct rb_node rb_node;
struct list_head f_head, c_pending, retry, rm_head;
struct list_head down_list, up_list;
struct list_head f_head;
struct d_info *dip;
struct p_info *pip;
void *pdu;
__u64 bytes_left, i_time, gm_time, d_time, c_time, d_sec, c_sec;
__u32 d_nsec, c_nsec;
struct blk_io_trace t;
__u64 bytes_left;
int linked, on_retry_list, down_len, up_len, on_rm_list;
int linked, is_getrq;
enum iop_type type;
#if defined(COUNT_IOS)
struct list_head cio_head;
#endif
};
struct bilink {
struct list_head down_head, up_head;
struct io *diop, *uiop;
};
#define bilink_free_head down_head
/* bt_timeline.c */
extern char bt_timeline_version[], *devices, *exes, *input_name, *output_name;
......@@ -202,11 +199,11 @@ extern FILE *ranges_ofp, *avgs_ofp, *iostat_ofp, *per_io_ofp;
extern int verbose, done, time_bounded, output_all_data, seek_absolute;
extern unsigned int n_devs;
extern unsigned long n_traces;
extern struct list_head all_devs, all_procs, retries, rmhd;
extern struct list_head all_devs, all_procs;
extern struct avgs_info all_avgs;
extern __u64 last_q, next_retry_check;
extern __u64 last_q;
extern struct region_info all_regions;
extern struct list_head free_ios, free_bilinks;
extern struct list_head free_ios;
extern __u64 iostat_interval, iostat_last_stamp;
extern time_t genesis, last_vtrace;
extern double t_astart, t_aend;
......@@ -253,7 +250,7 @@ void rb_foreach(struct rb_node *n, struct io *iop,
/* iostat.c */
void iostat_init(void);
void iostat_insert(struct io *iop);
void iostat_getrq(struct io *iop);
void iostat_merge(struct io *iop);
void iostat_issue(struct io *iop);
void iostat_unissue(struct io *iop);
......@@ -299,7 +296,7 @@ void bno_dump_add(void *handle, struct io *iop);
void bno_dump_clean(void);
/* seek.c */
void *seeki_init(__u32 device);
void *seeki_init(char *str);
void seeki_exit(void *param);
void seek_clean(void);
void seeki_add(void *handle, struct io *iop);
......@@ -309,15 +306,10 @@ long long seeki_median(void *handle);
int seeki_mode(void *handle, struct mode *mp);
/* trace.c */
void __dump_iop(FILE *ofp, struct io *iop, int extra_nl);
void __dump_iop2(FILE *ofp, struct io *a_iop, struct io *l_iop);
void release_iops(void);
void add_trace(struct io *iop);
void do_retries(__u64 now);
/* trace_complete.c */
void trace_complete(struct io *c_iop);
void retry_complete(struct io *c_iop, __u64 now);
/* trace_im.c */
void run_im(struct io *im_iop, struct io *d_iop, struct io *c_iop);
......@@ -325,6 +317,7 @@ void run_unim(struct io *im_iop, struct io *d_iop, struct io *c_iop);
int ready_im(struct io *im_iop, struct io *c_iop);
void trace_insert(struct io *i_iop);
void trace_merge(struct io *m_iop);
void trace_getrq(struct io *g_iop);
/* trace_issue.c */
void run_issue(struct io *d_iop, struct io *u_iop, struct io *c_iop);
......
......@@ -143,13 +143,9 @@ static inline struct io *io_alloc(void)
}
memset(iop, 0, sizeof(struct io));
INIT_LIST_HEAD(&iop->down_list);
INIT_LIST_HEAD(&iop->up_list);
# if defined(DEBUG)
iop->f_head.next = LIST_POISON1;
iop->c_pending.next = LIST_POISON1;
iop->retry.next = LIST_POISON1;
# endif
# if defined(COUNT_IOS)
......@@ -199,10 +195,6 @@ static inline int io_setup(struct io *iop, enum iop_type type)
static inline void io_release(struct io *iop)
{
ASSERT(iop->f_head.next == LIST_POISON1);
ASSERT(iop->c_pending.next == LIST_POISON1);
ASSERT(iop->retry.next == LIST_POISON1);
ASSERT(list_empty(&iop->up_list));
ASSERT(list_empty(&iop->down_list));
if (iop->linked)
dip_rem(iop);
......@@ -278,15 +270,14 @@ static inline void unupdate_i2d(struct io *iop, __u64 d_time)
UNUPDATE_AVGS(i2d, iop, iop->pip, d_time);
}
static inline void update_d2c(struct io *iop, int n, __u64 c_time)
static inline void update_d2c(struct io *iop, __u64 c_time)
{
# if defined(DEBUG)
if (per_io_ofp)
fprintf(per_io_ofp, "d2c %13.9f\n",
n*BIT_TIME(c_time));
fprintf(per_io_ofp, "d2c %13.9f\n", BIT_TIME(c_time));
# endif
UPDATE_AVGS_N(d2c, iop, iop->pip, c_time, n);
UPDATE_AVGS(d2c, iop, iop->pip, c_time);
}
static inline void update_blks(struct io *iop)
......@@ -333,37 +324,9 @@ static inline struct io *dip_rb_find_sec(struct d_info *dip,
return rb_find_sec(__get_root(dip, type), sec);
}
static inline void bump_retry(__u64 now)
static inline __u64 tdelta(__u64 from, __u64 to)
{
if (!list_empty(&retries))
next_retry_check = now + (100 * 1000); // 100 usec
else
next_retry_check = 0;
}
static inline void add_retry(struct io *iop)
{
bump_retry(iop->t.time);
if (!iop->on_retry_list) {
list_add_tail(&iop->retry, &retries);
iop->on_retry_list = 1;
}
}
static inline void del_retry(struct io *iop)
{
if (iop->on_retry_list) {
LIST_DEL(&iop->retry);
iop->on_retry_list = 0;
}
bump_retry(iop->t.time);
}
static inline __u64 tdelta(struct io *iop1, struct io *iop2)
{
__u64 t1 = iop1->t.time;
__u64 t2 = iop2->t.time;
return (t1 < t2) ? (t2 - t1) : 1;
return (from < to) ? (to - from) : 1;
}
static inline int remapper_dev(__u32 dev)
......@@ -372,18 +335,6 @@ static inline int remapper_dev(__u32 dev)
return mjr == 9 || mjr == 253 || mjr == 254;
}
static inline void dump_iop(struct io *iop, int extra_nl)
{
if (per_io_ofp)
__dump_iop(per_io_ofp, iop, extra_nl);
}
static inline void dump_iop2(struct io *a_iop, struct io *l_iop)
{
if (per_io_ofp)
__dump_iop2(per_io_ofp, a_iop, l_iop);
}
static inline int type2c(enum iop_type type)
{
int c;
......@@ -397,130 +348,54 @@ static inline int type2c(enum iop_type type)
case IOP_D: c = 'D'; break;
case IOP_C: c = 'C'; break;
case IOP_R: c = 'R'; break;
case IOP_L: c = 'L'; break;
case IOP_G: c = 'G'; break;
default : c = '?'; break;
}
return c;
}
static inline void bilink_free(struct bilink *blp)
{
list_add_tail(&blp->bilink_free_head, &free_bilinks);
}
static inline void bilink_free_all(void)
{
struct bilink *blp;
struct list_head *p, *q;
list_for_each_safe(p, q, &free_bilinks) {
blp = list_entry(p, struct bilink, bilink_free_head);
free(blp);
}
}
static inline struct bilink *bilink_alloc(struct io *diop, struct io *uiop)
{
struct bilink *blp;
if (!list_empty(&free_bilinks)) {
blp = list_entry(free_bilinks.prev, struct bilink,
bilink_free_head);
LIST_DEL(&blp->bilink_free_head);
}
else
blp = malloc(sizeof(*blp));
blp->diop = diop;
blp->uiop = uiop;
return blp;
}
static inline void bilink(struct io *diop, struct io *uiop)
static inline int histo_idx(__u64 nbytes)
{
struct bilink *blp = bilink_alloc(diop, uiop);
list_add_tail(&blp->down_head, &diop->up_list);
list_add_tail(&blp->up_head, &uiop->down_list);
diop->up_len++;
uiop->down_len++;
int idx = (nbytes >> 9) - 1;
return min(idx, N_HIST_BKTS-1);
}
static inline void biunlink(struct bilink *blp)
static inline void update_q_histo(__u64 nbytes)
{
LIST_DEL(&blp->down_head);
LIST_DEL(&blp->up_head);
blp->diop->up_len--;
blp->uiop->down_len--;
bilink_free(blp);
q_histo[histo_idx(nbytes)]++;
}
static inline struct io *bilink_first_down(struct io *iop,
struct bilink **blp_p)
static inline void update_d_histo(__u64 nbytes)
{
struct bilink *blp;
if (list_empty(&iop->down_list))
return NULL;
blp = list_entry(iop->down_list.next, struct bilink, up_head);
if (blp_p != NULL)
*blp_p = blp;
return blp->diop;
d_histo[histo_idx(nbytes)]++;
}
static inline struct io *bilink_first_up(struct io *iop, struct bilink **blp_p)
static inline struct io *io_first_list(struct list_head *head)
{
struct bilink *blp;
if (list_empty(&iop->up_list))
if (list_empty(head))
return NULL;
blp = list_entry(iop->up_list.next, struct bilink, down_head);
if (blp_p != NULL)
*blp_p = blp;
return blp->uiop;
return list_entry(head->next, struct io, f_head);
}
typedef void (*bilink_func)(struct io *diop, struct io *uiop,
struct io *c_iop);
static inline void bilink_for_each_down(bilink_func func, struct io *uiop,
struct io *c_iop, int ul)
static inline void __dump_iop(FILE *ofp, struct io *iop, int extra_nl)
{
struct bilink *blp;
struct list_head *p, *q;
list_for_each_safe(p, q, &uiop->down_list) {
blp = list_entry(p, struct bilink, up_head);
func(blp->diop, uiop, c_iop);
if (ul)
biunlink(blp);
}
fprintf(ofp, "%5d.%09lu %3d,%-3d %c %10llu+%-4u\n",
(int)SECONDS(iop->t.time),
(unsigned long)NANO_SECONDS(iop->t.time),
MAJOR(iop->t.device), MINOR(iop->t.device), type2c(iop->type),
(unsigned long long)iop->t.sector, t_sec(&iop->t));
if (extra_nl) fprintf(ofp, "\n");
}
static inline int histo_idx(__u64 nbytes)
static inline void __dump_iop2(FILE *ofp, struct io *a_iop, struct io *l_iop)
{
int idx = (nbytes >> 9) - 1;
return min(idx, N_HIST_BKTS-1);
}
static inline void update_q_histo(__u64 nbytes)
{
q_histo[histo_idx(nbytes)]++;
}
static inline void update_d_histo(__u64 nbytes)
{
d_histo[histo_idx(nbytes)]++;
}
static inline void add_rmhd(struct io *iop)
{
if (!iop->on_rm_list) {
list_add_tail(&iop->rm_head, &rmhd);
iop->on_rm_list = 1;
}
fprintf(ofp, "%5d.%09lu %3d,%-3d %c %10llu+%-4u <- (%3d,%-3d) %10llu\n",
(int)SECONDS(a_iop->t.time),
(unsigned long)NANO_SECONDS(a_iop->t.time),
MAJOR(a_iop->t.device), MINOR(a_iop->t.device),
type2c(a_iop->type), (unsigned long long)a_iop->t.sector,
t_sec(&a_iop->t), MAJOR(l_iop->t.device),
MINOR(l_iop->t.device), (unsigned long long)l_iop->t.sector);