]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From ab0fd1debe730ec9998678a0c53caefbd121ed10 Mon Sep 17 00:00:00 2001 |
2 | From: Tejun Heo <tj@kernel.org> | |
3 | Date: Fri, 3 Jul 2009 12:56:18 +0200 | |
4 | Subject: [PATCH] block: don't merge requests of different failfast settings | |
5 | References: bnc#519111 | |
6 | ||
7 | Block layer used to merge requests and bios with different failfast | |
8 | settings. This caused regular IOs to fail prematurely when they were | |
9 | merged into failfast requests for readahead. | |
10 | ||
11 | Niel Lambrechts could trigger the problem semi-reliably on ext4 when | |
12 | resuming from STR. ext4 uses readahead when reading inodes and | |
13 | combined with the deterministic extra SATA PHY exception cycle during | |
14 | resume on the specific configuration, non-readahead inode read would | |
15 | fail causing ext4 errors. Please read the following thread for | |
16 | details. | |
17 | ||
18 | http://lkml.org/lkml/2009/5/23/21 | |
19 | ||
20 | This patch makes block layer reject merging if the failfast settings | |
21 | don't match. This is correct but likely to lower IO performance by | |
22 | preventing regular IOs from mingling into surrounding readahead | |
23 | requests. Changes to allow such mixed merges and handle errors | |
24 | correctly will be added later. | |
25 | ||
26 | Signed-off-by: Tejun Heo <tj@kernel.org> | |
27 | Reported-by: Niel Lambrechts <niel.lambrechts@gmail.com> | |
28 | Cc: Theodore Tso <tytso@mit.edu> | |
29 | Signed-off-by: Jens Axboe <axboe@carl.(none)> | |
30 | Signed-off-by: Tejun Heo <teheo@suse.de> | |
31 | --- | |
32 | block/blk-merge.c | 6 ++++++ | |
33 | block/elevator.c | 8 ++++++++ | |
34 | 2 files changed, 14 insertions(+) | |
35 | ||
36 | --- a/block/blk-merge.c | |
37 | +++ b/block/blk-merge.c | |
38 | @@ -376,6 +376,12 @@ static int attempt_merge(struct request_ | |
39 | if (blk_integrity_rq(req) != blk_integrity_rq(next)) | |
40 | return 0; | |
41 | ||
42 | + /* don't merge requests of different failfast settings */ | |
43 | + if (blk_failfast_dev(req) != blk_failfast_dev(next) || | |
44 | + blk_failfast_transport(req) != blk_failfast_transport(next) || | |
45 | + blk_failfast_driver(req) != blk_failfast_driver(next)) | |
46 | + return 0; | |
47 | + | |
48 | /* | |
49 | * If we are allowed to merge, then append bio list | |
50 | * from next to rq and release next. merge_requests_fn | |
51 | --- a/block/elevator.c | |
52 | +++ b/block/elevator.c | |
53 | @@ -97,6 +97,14 @@ int elv_rq_merge_ok(struct request *rq, | |
54 | if (bio_integrity(bio) != blk_integrity_rq(rq)) | |
55 | return 0; | |
56 | ||
57 | + /* | |
58 | + * Don't merge if failfast settings don't match | |
59 | + */ | |
60 | + if (!bio_failfast_dev(bio) != !blk_failfast_dev(rq) || | |
61 | + !bio_failfast_transport(bio) != !blk_failfast_transport(rq) || | |
62 | + !bio_failfast_driver(bio) != !blk_failfast_driver(rq)) | |
63 | + return 0; | |
64 | + | |
65 | if (!elv_iosched_allow_merge(rq, bio)) | |
66 | return 0; | |
67 |