]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bcachefs: Add block plugging to read paths
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 15 Oct 2024 01:35:44 +0000 (21:35 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 21 Dec 2024 06:36:15 +0000 (01:36 -0500)
This will help with some of the btree_trans srcu lock hold time warnings
that are still turning up; submit_bio() can block for awhile if the
device is sufficiently congested.

It's not a perfect solution since blk_plug bios are submitted when
scheduling; we might want a way to disable the "submit on context
switch" behaviour, or switch to our own plugging in the future.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fs-io-buffered.c
fs/bcachefs/fs-io-direct.c

index 95972809e76d7f5740b7bb007a370dbba7340c8a..0923f38a2fcd23143121795dd04c6a388967fd6e 100644 (file)
@@ -248,6 +248,7 @@ void bch2_readahead(struct readahead_control *ractl)
        struct bch_io_opts opts;
        struct folio *folio;
        struct readpages_iter readpages_iter;
+       struct blk_plug plug;
 
        bch2_inode_opts_get(&opts, c, &inode->ei_inode);
 
@@ -255,6 +256,16 @@ void bch2_readahead(struct readahead_control *ractl)
        if (ret)
                return;
 
+       /*
+        * Besides being a general performance optimization, plugging helps with
+        * avoiding btree transaction srcu warnings - submitting a bio can
+        * block, and we don't want todo that with the transaction locked.
+        *
+        * However, plugged bios are submitted when we schedule; we ideally
+        * would have our own scheduler hook to call unlock_long() before
+        * scheduling.
+        */
+       blk_start_plug(&plug);
        bch2_pagecache_add_get(inode);
 
        struct btree_trans *trans = bch2_trans_get(c);
@@ -281,7 +292,7 @@ void bch2_readahead(struct readahead_control *ractl)
        bch2_trans_put(trans);
 
        bch2_pagecache_add_put(inode);
-
+       blk_finish_plug(&plug);
        darray_exit(&readpages_iter.folios);
 }
 
@@ -296,9 +307,13 @@ int bch2_read_single_folio(struct folio *folio, struct address_space *mapping)
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
        struct bch_read_bio *rbio;
        struct bch_io_opts opts;
+       struct blk_plug plug;
        int ret;
        DECLARE_COMPLETION_ONSTACK(done);
 
+       BUG_ON(folio_test_uptodate(folio));
+       BUG_ON(folio_test_dirty(folio));
+
        if (!bch2_folio_create(folio, GFP_KERNEL))
                return -ENOMEM;
 
@@ -313,7 +328,9 @@ int bch2_read_single_folio(struct folio *folio, struct address_space *mapping)
        rbio->bio.bi_iter.bi_sector = folio_sector(folio);
        BUG_ON(!bio_add_folio(&rbio->bio, folio, folio_size(folio), 0));
 
+       blk_start_plug(&plug);
        bch2_trans_run(c, (bchfs_read(trans, rbio, inode_inum(inode), NULL), 0));
+       blk_finish_plug(&plug);
        wait_for_completion(&done);
 
        ret = blk_status_to_errno(rbio->bio.bi_status);
index 6d3a05ae5da844ace2231957ba2ae5eac11f90b7..2089c36b5866dc4424285f384307694d28eb4711 100644 (file)
@@ -70,6 +70,7 @@ static int bch2_direct_IO_read(struct kiocb *req, struct iov_iter *iter)
        struct bch_io_opts opts;
        struct dio_read *dio;
        struct bio *bio;
+       struct blk_plug plug;
        loff_t offset = req->ki_pos;
        bool sync = is_sync_kiocb(req);
        size_t shorten;
@@ -128,6 +129,8 @@ static int bch2_direct_IO_read(struct kiocb *req, struct iov_iter *iter)
         */
        dio->should_dirty = iter_is_iovec(iter);
 
+       blk_start_plug(&plug);
+
        goto start;
        while (iter->count) {
                bio = bio_alloc_bioset(NULL,
@@ -160,6 +163,8 @@ start:
                bch2_read(c, rbio_init(bio, opts), inode_inum(inode));
        }
 
+       blk_finish_plug(&plug);
+
        iter->count += shorten;
 
        if (sync) {