summaryrefslogtreecommitdiff
blob: 11c495efbc0cdb9514cb745f9d57eb0c9e4f3911 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
http://git.kernel.dk/?p=blktrace.git;a=commit;h=8fc451c6b0b9a7db7c376ea6865c35321e561f00

From 8fc451c6b0b9a7db7c376ea6865c35321e561f00 Mon Sep 17 00:00:00 2001
From: Gwendal Grignou <gwendal@chromium.org>
Date: Fri, 18 Aug 2017 15:00:22 -0700
Subject: [PATCH] btt: Fix overlapping IO stats.

Keep scanning the tree for overlapping IO otherwise Q2G and process
traces will be incorrect.

Let assume we have 2 IOs:

A                                      A+a
|---------------------------------------|
       B                B+b
       |-----------------|

In the red/black tree we have:

                    o -> [A,A+a]
                   / \
                left right
                 /    \
           [...]o      o -> [B, B+b]

In the current code, if we would not be able to find [B+b] in the tree:
B is greater than A, so we won't go left
B+b is smaller than A+a, so we are not going right either.

When we have a [X, X+x] IO to look for:
We need to check for right when either:
 X+x >= A+a (for merged IO)
and
 X > A (for overlapping IO)

TEST=Check with a trace with overlapping IO: Q2C and Q2G are expected.

Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 btt/dip_rb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/btt/dip_rb.c b/btt/dip_rb.c
index 2aa7ffcc763b..6efef6c03b8f 100644
--- a/btt/dip_rb.c
+++ b/btt/dip_rb.c
@@ -57,7 +57,7 @@ struct io *rb_find_sec(struct rb_root *root, __u64 sec)
 		__iop = rb_entry(n, struct io, rb_node);
 		if (sec < BIT_START(__iop))
 			n = n->rb_left;
-		else if (sec >= BIT_END(__iop))
+		else if (sec > BIT_START(__iop))
 			n = n->rb_right;
 		else
 			return __iop;
@@ -82,7 +82,7 @@ void rb_foreach(struct rb_node *n, struct io *iop,
 		}
 		if (iop_s < this_s)
 			rb_foreach(n->rb_left, iop, fnc, head);
-		if (this_e < iop_e)
+		if ((this_e < iop_e) || (this_s < iop_s))
 			rb_foreach(n->rb_right, iop, fnc, head);
 	}
 }
-- 
2.15.1