btrfs: add manual PSI accounting for compressed reads

btrfs compressed reads try to always read the entire compressed chunk,
even if only a subset is requested.  Currently this is covered by the
magic PSI accounting underneath submit_bio, but that is about to go
away. Instead add manual psi_memstall_{enter,leave} annotations.

Note that for readahead this really should be using readahead_expand,
but the additionals reads are also done for plain ->read_folio where
readahead_expand can't work, so this overall logic is left as-is for
now.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: David Sterba <dsterba@suse.com>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Link: https://lore.kernel.org/r/20220915094200.139713-4-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Christoph Hellwig 2022-09-15 10:41:58 +01:00 committed by Jens Axboe
parent 527eb453bb
commit 4088a47e78
1 changed files with 12 additions and 2 deletions

View File

@ -15,6 +15,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <linux/writeback.h> #include <linux/writeback.h>
#include <linux/psi.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/sched/mm.h> #include <linux/sched/mm.h>
#include <linux/log2.h> #include <linux/log2.h>
@ -519,7 +520,8 @@ static u64 bio_end_offset(struct bio *bio)
*/ */
static noinline int add_ra_bio_pages(struct inode *inode, static noinline int add_ra_bio_pages(struct inode *inode,
u64 compressed_end, u64 compressed_end,
struct compressed_bio *cb) struct compressed_bio *cb,
unsigned long *pflags)
{ {
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
unsigned long end_index; unsigned long end_index;
@ -588,6 +590,9 @@ static noinline int add_ra_bio_pages(struct inode *inode,
continue; continue;
} }
if (PageWorkingset(page))
psi_memstall_enter(pflags);
ret = set_page_extent_mapped(page); ret = set_page_extent_mapped(page);
if (ret < 0) { if (ret < 0) {
unlock_page(page); unlock_page(page);
@ -674,6 +679,8 @@ void btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
u64 em_len; u64 em_len;
u64 em_start; u64 em_start;
struct extent_map *em; struct extent_map *em;
/* Initialize to 1 to make skip psi_memstall_leave unless needed */
unsigned long pflags = 1;
blk_status_t ret; blk_status_t ret;
int ret2; int ret2;
int i; int i;
@ -729,7 +736,7 @@ void btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
goto fail; goto fail;
} }
add_ra_bio_pages(inode, em_start + em_len, cb); add_ra_bio_pages(inode, em_start + em_len, cb, &pflags);
/* include any pages we added in add_ra-bio_pages */ /* include any pages we added in add_ra-bio_pages */
cb->len = bio->bi_iter.bi_size; cb->len = bio->bi_iter.bi_size;
@ -810,6 +817,9 @@ void btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
} }
} }
if (!pflags)
psi_memstall_leave(&pflags);
if (refcount_dec_and_test(&cb->pending_ios)) if (refcount_dec_and_test(&cb->pending_ios))
finish_compressed_bio_read(cb); finish_compressed_bio_read(cb);
return; return;