From cda22646adaa453519fac28222f20b0d73aa8562 Mon Sep 17 00:00:00 2001 From: Mike Krinkin Date: Thu, 3 Dec 2015 17:32:30 +0300 Subject: block: add call to split trace point There is a split tracepoint that is supposed to be called when bio is splitted, and it was called in bio_split function until commit 4b1faf931650d4a35b2a ("block: Kill bio_pair_split()"). But now, no one reports splits, so this patch adds call to trace_block_split back in blk_queue_split right after split. Signed-off-by: Mike Krinkin Signed-off-by: Jens Axboe --- block/blk-merge.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'block/blk-merge.c') diff --git a/block/blk-merge.c b/block/blk-merge.c index 41a55ba0d78e..0e5643a5d1c3 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -7,6 +7,8 @@ #include #include +#include + #include "blk.h" static struct bio *blk_bio_discard_split(struct request_queue *q, @@ -159,6 +161,7 @@ void blk_queue_split(struct request_queue *q, struct bio **bio, split->bi_rw |= REQ_NOMERGE; bio_chain(split, *bio); + trace_block_split(q, split, (*bio)->bi_iter.bi_sector); generic_make_request(*bio); *bio = split; } -- cgit From e36f6204288088fda50d1c84830340ccb70f85ff Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 12 Jan 2016 15:08:39 -0700 Subject: block: split bios to max possible length This splits bio in the middle of a vector to form the largest possible bio at the h/w's desired alignment, and guarantees the bio being split will have some data. The criteria for splitting is changed from the max sectors to the h/w's optimal sector alignment if it is provided. For h/w that advertise their block storage's underlying chunk size, it's a big performance win to not submit commands that cross them. If sector alignment is not provided, this patch uses the max sectors as before. This addresses the performance issue commit d380561113 attempted to fix, but was reverted due to splitting logic error. Signed-off-by: Keith Busch Cc: Jens Axboe Cc: Ming Lei Cc: Kent Overstreet Cc: # 4.4.x- Signed-off-by: Jens Axboe --- block/blk-merge.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'block/blk-merge.c') diff --git a/block/blk-merge.c b/block/blk-merge.c index 0e5643a5d1c3..237b087d3529 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -83,9 +83,6 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, struct bio *new = NULL; bio_for_each_segment(bv, bio, iter) { - if (sectors + (bv.bv_len >> 9) > queue_max_sectors(q)) - goto split; - /* * If the queue doesn't support SG gaps and adding this * offset would create a gap, disallow it. @@ -93,6 +90,22 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, if (bvprvp && bvec_gap_to_prev(q, bvprvp, bv.bv_offset)) goto split; + if (sectors + (bv.bv_len >> 9) > + blk_max_size_offset(q, bio->bi_iter.bi_sector)) { + /* + * Consider this a new segment if we're splitting in + * the middle of this vector. + */ + if (nsegs < queue_max_segments(q) && + sectors < blk_max_size_offset(q, + bio->bi_iter.bi_sector)) { + nsegs++; + sectors = blk_max_size_offset(q, + bio->bi_iter.bi_sector); + } + goto split; + } + if (bvprvp && blk_queue_cluster(q)) { if (seg_size + bv.bv_len > queue_max_segment_size(q)) goto new_segment; -- cgit