block: fix bio_add_page for non trivial merge_bvec_fn case
PATCH 1/1 block: fix bio_add_page for non trivial merge_bvec_fn case
Hi, year ago I've sent a patch which fix false bio merge rejects, but seems patch was missed. Currently the issue is still present.
Quoted 1 line
From
92a97ef181e15caa94bd56a1ade5c337db599b79Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <[email protected]>
Date: Tue, 26 Jan 2010 16:01:34 +0300
Subject: [PATCH] [PATCH] block: fix bio_add_page for non trivial merge_bvec_fn case
We have to properly decrease bi_size in order to merge_bvec_fn return right result. Otherwise this result in false merge rejects for two absolutely valid bio_vecs. This may cause significant performance penalty for example Itanium: page_size == 16k, fs_block_size == 1k and block device is raid with small chunk_size.
--- fs/bio.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
fs/bio.c +2 -1
@@ -548,7 +548,8 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct pagestruct bvec_merge_data bvm = { .bi_bdev = bio->bi_bdev, .bi_sector = bio->bi_sector, - .bi_size = bio->bi_size, + .bi_size = bio->bi_size - + (prev->bv_len - len), .bi_rw = bio->bi_rw, };
Signature · 1 line
1.6.3.3
Quoted 25 lines · Dmitry Monakhov
Hi, year ago I've sent a patch which fix false bio merge rejects, but seems patch was missed. Currently the issue is still present.
From
92a97ef181e15caa94bd56a1ade5c337db599b79Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <[email protected]>
Date: Tue, 26 Jan 2010 16:01:34 +0300
Subject: [PATCH] [PATCH] block: fixbio_add_pagefor non trivialmerge_bvec_fncaseWe have to properly decrease
bi_sizein order tomerge_bvec_fnreturn right result. Otherwise this result in false merge rejects for two absolutely validbio_vecs. This may cause significant performance penalty for example Itanium:page_size== 16k,fs_block_size== 1k and block device is raid with smallchunk_size.Signed-off-by Dmitry Monakhov <[email protected]>--- fs/bio.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)fs/bio.c +0
-0
fs/bio.c static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page · line 554
Quoted 8 lines
fs/bio.c +2
-1@@ -548,7 +548,8 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct pagestruct bvec_merge_data bvm = { .bi_bdev = bio->bi_bdev, .bi_sector = bio->bi_sector, - .bi_size = bio->bi_size, + .bi_size = bio->bi_size - + (prev->bv_len - len), .bi_rw = bio->bi_rw, };
Hmm confused. why isn't this just bio->bi_size - len?
Signature · 1 line
Jens Axboe
Quoted 21 lines · Jens Axboe
Quoted 20 lines · Dmitry Monakhov
Hi, year ago I've sent a patch which fix false bio merge rejects, but seems patch was missed. Currently the issue is still present.
From
92a97ef181e15caa94bd56a1ade5c337db599b79Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <[email protected]>
Date: Tue, 26 Jan 2010 16:01:34 +0300
Subject: [PATCH] [PATCH] block: fixbio_add_pagefor non trivialmerge_bvec_fncaseWe have to properly decrease
bi_sizein order tomerge_bvec_fnreturn right result. Otherwise this result in false merge rejects for two absolutely validbio_vecs. This may cause significant performance penalty for example Itanium:page_size== 16k,fs_block_size== 1k and block device is raid with smallchunk_size.Signed-off-by Dmitry Monakhov <[email protected]>---
fs/bio.c | 3 ++-1 files changed, 2 insertions(+), 1 deletions(-)
Quoted 15 lines
fs/bio.c static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page · line 554
Quoted 13 lines
fs/bio.c +2
-1@@ -548,7 +548,8 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page struct bvec_merge_data bvm = { .bi_bdev = bio->bi_bdev, .bi_sector = bio->bi_sector, - .bi_size = bio->bi_size, + .bi_size = bio->bi_size - + (prev->bv_len - len), .bi_rw = bio->bi_rw, };Hmm confused. why isn't this just
bio->bi_size- len?
because we have following scenario:
0) old_bv_len = prev->bv_len ;
1) prev->bv_len += len;
2)->merge_bvec_fn()
usually it looks like follows
if (bio->bv_len + bvm->bi_size > max_chunk_size)
goto fail
So formally we detach last bvec increase it size and try to
attach it to bio.
but old_bv_len is already accounted in bi_size, so we have to decrease
bi_size to this value, and old_bv_len = (prev->bv_len - len) at
that moment.
I've used math manipuation in order to avoid temporary variable because stack size is matter on block layer.
Quoted 5 lines
--
Jens Axboe
Quoted 22 lines · Dmitry Monakhov
Quoted 21 lines · Jens Axboe
Quoted 20 lines · Dmitry Monakhov
Hi, year ago I've sent a patch which fix false bio merge rejects, but seems patch was missed. Currently the issue is still present.
From
92a97ef181e15caa94bd56a1ade5c337db599b79Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <[email protected]>
Date: Tue, 26 Jan 2010 16:01:34 +0300
Subject: [PATCH] [PATCH] block: fixbio_add_pagefor non trivialmerge_bvec_fncaseWe have to properly decrease
bi_sizein order tomerge_bvec_fnreturn right result. Otherwise this result in false merge rejects for two absolutely validbio_vecs. This may cause significant performance penalty for example Itanium:page_size== 16k,fs_block_size== 1k and block device is raid with smallchunk_size.Signed-off-by Dmitry Monakhov <[email protected]>---
fs/bio.c | 3 ++-1 files changed, 2 insertions(+), 1 deletions(-)
Quoted 15 lines
Quoted 7 lines
Quoted 7 lines
fs/bio.c +0
-0@@ -548,7 +548,8 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page struct bvec_merge_data bvm = { .bi_bdev = bio->bi_bdev,Quoted 8 lines
fs/bio.c static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page · line 554
Quoted 6 lines
fs/bio.c +2
-1.bi_sector = bio->bi_sector, - .bi_size = bio->bi_size, + .bi_size = bio->bi_size - + (prev->bv_len - len), .bi_rw = bio->bi_rw, };Hmm confused. why isn't this just
bio->bi_size- len?
I've attached more descriptive version of the patch. Jens, please clarify your opinion to the patch( do you like it or not?) I don't want it miss again.
Quoted 1 line
From
65ac8c9a2988310a79215b68e9c93b6dca6c6665Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <[email protected]>
Date: Wed, 27 Jan 2010 22:44:36 +0300
Subject: [PATCH] [PATCH] block: fix bio_add_page for non trivial merge_bvec_fn case
We have to properly decrease bi_size in order to merge_bvec_fn return right result. Otherwise this result in false merge rejects for two absolutely valid bio_vecs. This may cause significant performance penalty for example fs_block_size == 1k and block device is raid0 with small chunk_size = 8k. Then it is impossible to merge 7-th fs-block in to bio which already has 6 fs-blocks.
--- fs/bio.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-)
fs/bio.c +6 -1
@@ -542,13 +542,18 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct pageif (page == prev->bv_page && offset == prev->bv_offset + prev->bv_len) { +unsigned int prev_bv_len = prev->bv_len; prev->bv_len += len;if (q->merge_bvec_fn) {struct bvec_merge_data bvm = { +/* prev_bvec is already charged in +bi_size, discharge it in order to +simulate merging updated prev_bvec +as new bvec. */ .bi_bdev = bio->bi_bdev, .bi_sector = bio->bi_sector, - .bi_size = bio->bi_size, + .bi_size = bio->bi_size - prev_bv_len, .bi_rw = bio->bi_rw, };
Signature · 1 line
1.6.3.3
Quoted 39 lines · Dmitry Monakhov
Quoted 22 lines · Dmitry Monakhov
Quoted 21 lines · Jens Axboe
Quoted 20 lines · Dmitry Monakhov
Hi, year ago I've sent a patch which fix false bio merge rejects, but seems patch was missed. Currently the issue is still present.
From
92a97ef181e15caa94bd56a1ade5c337db599b79Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <[email protected]>
Date: Tue, 26 Jan 2010 16:01:34 +0300
Subject: [PATCH] [PATCH] block: fixbio_add_pagefor non trivialmerge_bvec_fncaseWe have to properly decrease
bi_sizein order tomerge_bvec_fnreturn right result. Otherwise this result in false merge rejects for two absolutely validbio_vecs. This may cause significant performance penalty for example Itanium:page_size== 16k,fs_block_size== 1k and block device is raid with smallchunk_size.Signed-off-by Dmitry Monakhov <[email protected]>---
fs/bio.c | 3 ++-1 files changed, 2 insertions(+), 1 deletions(-)Quoted 15 lines
Quoted 7 lines
Quoted 7 lines
fs/bio.c +0
-0@@ -548,7 +548,8 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page struct bvec_merge_data bvm = { .bi_bdev = bio->bi_bdev,Quoted 8 lines
fs/bio.c static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page · line 558
Quoted 6 lines
fs/bio.c +2
-1.bi_sector = bio->bi_sector, - .bi_size = bio->bi_size, + .bi_size = bio->bi_size - + (prev->bv_len - len), .bi_rw = bio->bi_rw, };Hmm confused. why isn't this just
bio->bi_size- len?
Quoted 3 lines
I've attached more descriptive version of the patch. Jens, please clarify your opinion to the patch( do you like it or not?) I don't want it miss again.
Yes thanks, I agree with your evaluation, it's definitely correct. I'll add it.
Signature · 1 line
Jens Axboe