diff options
author | NeilBrown <neilb@suse.com> | 2017-06-18 00:38:58 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-06-18 14:40:59 -0400 |
commit | a8821f3f32bea173c7f9546b3b025898f0e09f58 (patch) | |
tree | d911354d3c07a5663256d5684d87f8d27435bdb6 /block/blk-merge.c | |
parent | 93b27e72904a9869e648c870bf0d04b124fda1c7 (diff) |
block: Improvements to bounce-buffer handling
Since commit 23688bf4f830 ("block: ensure to split after potentially
bouncing a bio") blk_queue_bounce() is called *before*
blk_queue_split().
This means that:
1/ the comments blk_queue_split() about bounce buffers are
irrelevant, and
2/ a very large bio (more than BIO_MAX_PAGES) will no longer be
split before it arrives at blk_queue_bounce(), leading to the
possibility that bio_clone_bioset() will fail and a NULL
will be dereferenced.
Separately, blk_queue_bounce() shouldn't use fs_bio_set as the bio
being copied could be from the same set, and this could lead to a
deadlock.
So:
- allocate 2 private biosets for blk_queue_bounce, one for
splitting enormous bios and one for cloning bios.
- add code to split a bio that exceeds BIO_MAX_PAGES.
- Fix up the comments in blk_queue_split()
Credit-to: Ming Lei <tom.leiming@gmail.com> (suggested using single bio_for_each_segment loop)
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/blk-merge.c')
-rw-r--r-- | block/blk-merge.c | 14 |
1 files changed, 4 insertions, 10 deletions
diff --git a/block/blk-merge.c b/block/blk-merge.c index d59074556703..51c84540d3bb 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -117,17 +117,11 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, | |||
117 | * each holds at most BIO_MAX_PAGES bvecs because | 117 | * each holds at most BIO_MAX_PAGES bvecs because |
118 | * bio_clone() can fail to allocate big bvecs. | 118 | * bio_clone() can fail to allocate big bvecs. |
119 | * | 119 | * |
120 | * It should have been better to apply the limit per | 120 | * Those drivers which will need to use bio_clone() |
121 | * request queue in which bio_clone() is involved, | 121 | * should tell us in some way. For now, impose the |
122 | * instead of globally. The biggest blocker is the | 122 | * BIO_MAX_PAGES limit on all queues. |
123 | * bio_clone() in bio bounce. | ||
124 | * | 123 | * |
125 | * If bio is splitted by this reason, we should have | 124 | * TODO: handle users of bio_clone() differently. |
126 | * allowed to continue bios merging, but don't do | ||
127 | * that now for making the change simple. | ||
128 | * | ||
129 | * TODO: deal with bio bounce's bio_clone() gracefully | ||
130 | * and convert the global limit into per-queue limit. | ||
131 | */ | 125 | */ |
132 | if (bvecs++ >= BIO_MAX_PAGES) | 126 | if (bvecs++ >= BIO_MAX_PAGES) |
133 | goto split; | 127 | goto split; |