summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2019-04-11 08:23:31 +0200
committerJens Axboe <axboe@kernel.dk>2019-04-12 09:06:42 -0600
commit52d52d1c98a90cfe860b83498e4b6074aad95c15 (patch)
tree98776fc54f50c9a9168162e030ee9db6b89c2d46 /include
parent7321ecbfc7cf85211460a1dc6bb0ccfc3dcf9df0 (diff)
block: only allow contiguous page structs in a bio_vec
We currently have to call nth_page when iterating over pages inside a bio_vec. Jens complained a while ago that this is fairly expensive. To mitigate this we can check that that the actual page structures are contiguous when adding them to the bio, and just do check pointer arithmetics later on. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'include')
-rw-r--r--include/linux/bvec.h13
1 files changed, 4 insertions, 9 deletions
diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index 307bbda62b7b..44b0f4684190 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -51,11 +51,6 @@ struct bvec_iter_all {
unsigned done;
};
-static inline struct page *bvec_nth_page(struct page *page, int idx)
-{
- return idx == 0 ? page : nth_page(page, idx);
-}
-
/*
* various member access, note that bio_data should of course not be used
* on highmem page vectors
@@ -92,8 +87,8 @@ static inline struct page *bvec_nth_page(struct page *page, int idx)
PAGE_SIZE - bvec_iter_offset((bvec), (iter)))
#define bvec_iter_page(bvec, iter) \
- bvec_nth_page(mp_bvec_iter_page((bvec), (iter)), \
- mp_bvec_iter_page_idx((bvec), (iter)))
+ (mp_bvec_iter_page((bvec), (iter)) + \
+ mp_bvec_iter_page_idx((bvec), (iter)))
#define bvec_iter_bvec(bvec, iter) \
((struct bio_vec) { \
@@ -157,7 +152,7 @@ static inline void mp_bvec_next_segment(const struct bio_vec *bvec,
struct bio_vec *bv = &iter_all->bv;
if (bv->bv_page) {
- bv->bv_page = nth_page(bv->bv_page, 1);
+ bv->bv_page++;
bv->bv_offset = 0;
} else {
bv->bv_page = bvec->bv_page;
@@ -177,7 +172,7 @@ static inline void mp_bvec_last_segment(const struct bio_vec *bvec,
unsigned total = bvec->bv_offset + bvec->bv_len;
unsigned last_page = (total - 1) / PAGE_SIZE;
- seg->bv_page = bvec_nth_page(bvec->bv_page, last_page);
+ seg->bv_page = bvec->bv_page + last_page;
/* the whole segment is inside the last page */
if (bvec->bv_offset >= last_page * PAGE_SIZE) {