Skip to content

Commit 61ed3a1

Browse files
lorddoskiaskdave
authored andcommitted
btrfs: Refactor main loop in extent_readpages
extent_readpages processes all pages in the readlist in batches of 16, this is implemented by a single for loop but thanks to an if condition the loop does 2 things based on whether we've filled the batch or not. Additionally due to the structure of the code there is an additional check which deals with partial batches. Streamline all of this by explicitly using two loops. The outter one is used to process all pages while the inner one just fills in the batch of 16 (currently). Due to this new structure the code guarantees that all pages are processed in the loop hence the code to deal with any leftovers is eliminated. This also enable the compiler to inline __extent_readpages: ./scripts/bloat-o-meter fs/btrfs/extent_io.o extent_io.for add/remove: 0/1 grow/shrink: 1/0 up/down: 660/-820 (-160) Function old new delta extent_readpages 476 1136 +660 __extent_readpages 820 - -820 Total: Before=44315, After=44155, chg -0.36% Signed-off-by: Nikolay Borisov <nborisov@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 15c8276 commit 61ed3a1

File tree

1 file changed

+14
-20
lines changed

1 file changed

+14
-20
lines changed

fs/btrfs/extent_io.c

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4094,42 +4094,36 @@ int extent_readpages(struct address_space *mapping, struct list_head *pages,
40944094
unsigned nr_pages)
40954095
{
40964096
struct bio *bio = NULL;
4097-
unsigned page_idx;
40984097
unsigned long bio_flags = 0;
40994098
struct page *pagepool[16];
4100-
struct page *page;
41014099
struct extent_map *em_cached = NULL;
41024100
struct extent_io_tree *tree = &BTRFS_I(mapping->host)->io_tree;
41034101
int nr = 0;
41044102
u64 prev_em_start = (u64)-1;
41054103

4106-
for (page_idx = 0; page_idx < nr_pages; page_idx++) {
4107-
page = list_entry(pages->prev, struct page, lru);
4104+
while (!list_empty(pages)) {
4105+
for (nr = 0; nr < ARRAY_SIZE(pagepool) && !list_empty(pages);) {
4106+
struct page *page = list_entry(pages->prev,
4107+
struct page, lru);
41084108

4109-
prefetchw(&page->flags);
4110-
list_del(&page->lru);
4111-
if (add_to_page_cache_lru(page, mapping,
4112-
page->index,
4113-
readahead_gfp_mask(mapping))) {
4114-
put_page(page);
4115-
continue;
4109+
prefetchw(&page->flags);
4110+
list_del(&page->lru);
4111+
if (add_to_page_cache_lru(page, mapping, page->index,
4112+
readahead_gfp_mask(mapping))) {
4113+
put_page(page);
4114+
continue;
4115+
}
4116+
4117+
pagepool[nr++] = page;
41164118
}
41174119

4118-
pagepool[nr++] = page;
4119-
if (nr < ARRAY_SIZE(pagepool))
4120-
continue;
41214120
__extent_readpages(tree, pagepool, nr, &em_cached, &bio,
4122-
&bio_flags, &prev_em_start);
4123-
nr = 0;
4121+
&bio_flags, &prev_em_start);
41244122
}
4125-
if (nr)
4126-
__extent_readpages(tree, pagepool, nr, &em_cached, &bio,
4127-
&bio_flags, &prev_em_start);
41284123

41294124
if (em_cached)
41304125
free_extent_map(em_cached);
41314126

4132-
BUG_ON(!list_empty(pages));
41334127
if (bio)
41344128
return submit_one_bio(bio, 0, bio_flags);
41354129
return 0;

0 commit comments

Comments
 (0)