Commit e3b12fc1 authored by Andrew Morton's avatar Andrew Morton Committed by Russell King

[PATCH] use bio_get_nr_vecs() for sizing direct-io BIOs

From Badari Pulavarty.

Rather than allocating maximum-sized BIOs, use the new
bio_get_nr_vecs() hint when sizing the BIOs.

Also keep track of the approximate upper-bound on the number of pages
remaining to do, so we can again avoid allocating excessively-sized
BIOs.
parent 6fb75ca4
...@@ -49,6 +49,7 @@ struct dio { ...@@ -49,6 +49,7 @@ struct dio {
/* Page fetching state */ /* Page fetching state */
int curr_page; /* changes */ int curr_page; /* changes */
int total_pages; /* doesn't change */ int total_pages; /* doesn't change */
int pages_left; /* approximate total IO pages */
unsigned long curr_user_address;/* changes */ unsigned long curr_user_address;/* changes */
/* Page queue */ /* Page queue */
...@@ -396,7 +397,8 @@ static int dio_new_bio(struct dio *dio) ...@@ -396,7 +397,8 @@ static int dio_new_bio(struct dio *dio)
if (ret) if (ret)
goto out; goto out;
sector = dio->next_block_in_bio << (dio->blkbits - 9); sector = dio->next_block_in_bio << (dio->blkbits - 9);
nr_pages = min(dio->total_pages, BIO_MAX_PAGES); nr_pages = min(dio->pages_left, bio_get_nr_vecs(dio->map_bh.b_bdev));
BUG_ON(nr_pages <= 0);
ret = dio_bio_alloc(dio, dio->map_bh.b_bdev, sector, nr_pages); ret = dio_bio_alloc(dio, dio->map_bh.b_bdev, sector, nr_pages);
dio->boundary = 0; dio->boundary = 0;
out: out:
...@@ -423,6 +425,7 @@ dio_bio_add_page(struct dio *dio, struct page *page, ...@@ -423,6 +425,7 @@ dio_bio_add_page(struct dio *dio, struct page *page,
} }
} }
page_cache_release(page); page_cache_release(page);
dio->pages_left--;
out: out:
return ret; return ret;
} }
...@@ -566,6 +569,10 @@ direct_io_worker(int rw, struct inode *inode, const struct iovec *iov, ...@@ -566,6 +569,10 @@ direct_io_worker(int rw, struct inode *inode, const struct iovec *iov,
spin_lock_init(&dio.bio_list_lock); spin_lock_init(&dio.bio_list_lock);
dio.bio_list = NULL; dio.bio_list = NULL;
dio.waiter = NULL; dio.waiter = NULL;
dio.pages_left = 0;
for (seg = 0; seg < nr_segs; seg++)
dio.pages_left += (iov[seg].iov_len / PAGE_SIZE) + 2;
for (seg = 0; seg < nr_segs; seg++) { for (seg = 0; seg < nr_segs; seg++) {
user_addr = (unsigned long)iov[seg].iov_base; user_addr = (unsigned long)iov[seg].iov_base;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment