mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-28 21:33:52 +00:00
readahead: stricter check for bdi io_pages
commitdc30b96ab6
upstream. ondemand_readahead() checks bdi->io_pages to cap the maximum pages that need to be processed. This works until the readit section. If we would do an async only readahead (async size = sync size) and target is at beginning of window we expand the pages by another get_next_ra_size() pages. Btrace for large reads shows that kernel always issues a doubled size read at the beginning of processing. Add an additional check for io_pages in the lower part of the func. The fix helps devices that hard limit bio pages and rely on proper handling of max_hw_read_sectors (e.g. older FusionIO cards). For that reason it could qualify for stable. Fixes:9491ae4a
("mm: don't cap request size based on read-ahead setting") Cc: stable@vger.kernel.org Signed-off-by: Markus Stockhausen stockhausen@collogia.de Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8513c01ae1
commit
cf12d0f9c0
1 changed files with 10 additions and 2 deletions
|
@ -380,6 +380,7 @@ ondemand_readahead(struct address_space *mapping,
|
||||||
{
|
{
|
||||||
struct backing_dev_info *bdi = inode_to_bdi(mapping->host);
|
struct backing_dev_info *bdi = inode_to_bdi(mapping->host);
|
||||||
unsigned long max_pages = ra->ra_pages;
|
unsigned long max_pages = ra->ra_pages;
|
||||||
|
unsigned long add_pages;
|
||||||
pgoff_t prev_offset;
|
pgoff_t prev_offset;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -469,10 +470,17 @@ ondemand_readahead(struct address_space *mapping,
|
||||||
* Will this read hit the readahead marker made by itself?
|
* Will this read hit the readahead marker made by itself?
|
||||||
* If so, trigger the readahead marker hit now, and merge
|
* If so, trigger the readahead marker hit now, and merge
|
||||||
* the resulted next readahead window into the current one.
|
* the resulted next readahead window into the current one.
|
||||||
|
* Take care of maximum IO pages as above.
|
||||||
*/
|
*/
|
||||||
if (offset == ra->start && ra->size == ra->async_size) {
|
if (offset == ra->start && ra->size == ra->async_size) {
|
||||||
ra->async_size = get_next_ra_size(ra, max_pages);
|
add_pages = get_next_ra_size(ra, max_pages);
|
||||||
ra->size += ra->async_size;
|
if (ra->size + add_pages <= max_pages) {
|
||||||
|
ra->async_size = add_pages;
|
||||||
|
ra->size += add_pages;
|
||||||
|
} else {
|
||||||
|
ra->size = max_pages;
|
||||||
|
ra->async_size = max_pages >> 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ra_submit(ra, mapping, filp);
|
return ra_submit(ra, mapping, filp);
|
||||||
|
|
Loading…
Reference in a new issue