f2fs: do not bother checkpoint by f2fs_get_node_info
authorJaegeuk Kim <jaegeuk@kernel.org>
Mon, 13 Dec 2021 22:16:32 +0000 (14:16 -0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Tue, 4 Jan 2022 21:20:49 +0000 (13:20 -0800)
This patch tries to mitigate lock contention between f2fs_write_checkpoint and
f2fs_get_node_info along with nat_tree_lock.

The idea is, if checkpoint is currently running, other threads that try to grab
nat_tree_lock would be better to wait for checkpoint.

Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/checkpoint.c
fs/f2fs/compress.c
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/file.c
fs/f2fs/gc.c
fs/f2fs/inline.c
fs/f2fs/inode.c
fs/f2fs/node.c
fs/f2fs/recovery.c
fs/f2fs/segment.c

index f1693d45bb782767f0b9c2fd40d77693a6a08bc5..55e3c54d99c1d4bfd7086e1df45e7622acf0d4b2 100644 (file)
@@ -664,7 +664,7 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
        /* truncate all the data during iput */
        iput(inode);
 
-       err = f2fs_get_node_info(sbi, ino, &ni);
+       err = f2fs_get_node_info(sbi, ino, &ni, false);
        if (err)
                goto err_out;
 
index 4b49038d150d5a4c78daf209aeb76bf241511d84..d0c3aeba594549f835bca3b96b70987de5b4d405 100644 (file)
@@ -1286,7 +1286,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
 
        psize = (loff_t)(cc->rpages[last_index]->index + 1) << PAGE_SHIFT;
 
-       err = f2fs_get_node_info(fio.sbi, dn.nid, &ni);
+       err = f2fs_get_node_info(fio.sbi, dn.nid, &ni, false);
        if (err)
                goto out_put_dnode;
 
index 40c0d1426a11d05ecccfe6739c1078fc27b74591..2737fcc0dbcf3d006dfe17c4325f38f49fa1d642 100644 (file)
@@ -1355,7 +1355,7 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
        if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
                return -EPERM;
 
-       err = f2fs_get_node_info(sbi, dn->nid, &ni);
+       err = f2fs_get_node_info(sbi, dn->nid, &ni, false);
        if (err)
                return err;
 
@@ -1757,7 +1757,7 @@ static int f2fs_xattr_fiemap(struct inode *inode,
                if (!page)
                        return -ENOMEM;
 
-               err = f2fs_get_node_info(sbi, inode->i_ino, &ni);
+               err = f2fs_get_node_info(sbi, inode->i_ino, &ni, false);
                if (err) {
                        f2fs_put_page(page, 1);
                        return err;
@@ -1789,7 +1789,7 @@ static int f2fs_xattr_fiemap(struct inode *inode,
                if (!page)
                        return -ENOMEM;
 
-               err = f2fs_get_node_info(sbi, xnid, &ni);
+               err = f2fs_get_node_info(sbi, xnid, &ni, false);
                if (err) {
                        f2fs_put_page(page, 1);
                        return err;
@@ -2649,7 +2649,7 @@ got_it:
                fio->need_lock = LOCK_REQ;
        }
 
-       err = f2fs_get_node_info(fio->sbi, dn.nid, &ni);
+       err = f2fs_get_node_info(fio->sbi, dn.nid, &ni, false);
        if (err)
                goto out_writepage;
 
index 5da5922867210ea14f94062681641999cb64649e..a9ed2fd3fffb923804a8a96f31bf86fc9d395272 100644 (file)
@@ -3412,7 +3412,7 @@ int f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid);
 bool f2fs_is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid);
 bool f2fs_need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino);
 int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
-                                               struct node_info *ni);
+                               struct node_info *ni, bool checkpoint_context);
 pgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs);
 int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode);
 int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from);
index 5ec6bef3937f27909eb7df2f6b7c9b024a06aecd..f540c1cbddca40581965256cf58f28636e9d573c 100644 (file)
@@ -1233,7 +1233,7 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
                        if (ret)
                                return ret;
 
-                       ret = f2fs_get_node_info(sbi, dn.nid, &ni);
+                       ret = f2fs_get_node_info(sbi, dn.nid, &ni, false);
                        if (ret) {
                                f2fs_put_dnode(&dn);
                                return ret;
index 7fbe46477a5acaca4de8d42e3a3b58bdf964f710..a6accec60d04885553245a50c4982035dfdf1679 100644 (file)
@@ -959,7 +959,7 @@ next_step:
                        continue;
                }
 
-               if (f2fs_get_node_info(sbi, nid, &ni)) {
+               if (f2fs_get_node_info(sbi, nid, &ni, false)) {
                        f2fs_put_page(node_page, 1);
                        continue;
                }
@@ -1027,7 +1027,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
        if (IS_ERR(node_page))
                return false;
 
-       if (f2fs_get_node_info(sbi, nid, dni)) {
+       if (f2fs_get_node_info(sbi, nid, dni, false)) {
                f2fs_put_page(node_page, 1);
                return false;
        }
@@ -1221,7 +1221,7 @@ static int move_data_block(struct inode *inode, block_t bidx,
 
        f2fs_wait_on_block_writeback(inode, dn.data_blkaddr);
 
-       err = f2fs_get_node_info(fio.sbi, dn.nid, &ni);
+       err = f2fs_get_node_info(fio.sbi, dn.nid, &ni, false);
        if (err)
                goto put_out;
 
index ea08f0dfa1bdff58ad9c3d5f35d3a8d1d31d69f7..4b5cefa3f90c11a1c9c0a533db2b1825a20bb241 100644 (file)
@@ -131,7 +131,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
        if (err)
                return err;
 
-       err = f2fs_get_node_info(fio.sbi, dn->nid, &ni);
+       err = f2fs_get_node_info(fio.sbi, dn->nid, &ni, false);
        if (err) {
                f2fs_truncate_data_blocks_range(dn, 1);
                f2fs_put_dnode(dn);
@@ -786,7 +786,7 @@ int f2fs_inline_data_fiemap(struct inode *inode,
                ilen = start + len;
        ilen -= start;
 
-       err = f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni);
+       err = f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni, false);
        if (err)
                goto out;
 
index 935016e56010b0045055ba1a11e6481de7c3145c..2ab3b424735a444da216decf4ede88cd575e91f6 100644 (file)
@@ -881,7 +881,7 @@ void f2fs_handle_failed_inode(struct inode *inode)
         * so we can prevent losing this orphan when encoutering checkpoint
         * and following suddenly power-off.
         */
-       err = f2fs_get_node_info(sbi, inode->i_ino, &ni);
+       err = f2fs_get_node_info(sbi, inode->i_ino, &ni, false);
        if (err) {
                set_sbi_flag(sbi, SBI_NEED_FSCK);
                f2fs_warn(sbi, "May loss orphan inode, run fsck to fix.");
index b1bc7d76da3b6031cf819891161fd73e8d105ad4..e0b5eb28d3839a724ecf1f42a82a159a62306f35 100644 (file)
@@ -543,7 +543,7 @@ int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink)
 }
 
 int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
-                                               struct node_info *ni)
+                               struct node_info *ni, bool checkpoint_context)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
        struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
@@ -576,9 +576,10 @@ retry:
         * nat_tree_lock. Therefore, we should retry, if we failed to grab here
         * while not bothering checkpoint.
         */
-       if (!rwsem_is_locked(&sbi->cp_global_sem)) {
+       if (!rwsem_is_locked(&sbi->cp_global_sem) || checkpoint_context) {
                down_read(&curseg->journal_rwsem);
-       } else if (!down_read_trylock(&curseg->journal_rwsem)) {
+       } else if (rwsem_is_contended(&nm_i->nat_tree_lock) ||
+                               !down_read_trylock(&curseg->journal_rwsem)) {
                up_read(&nm_i->nat_tree_lock);
                goto retry;
        }
@@ -891,7 +892,7 @@ static int truncate_node(struct dnode_of_data *dn)
        int err;
        pgoff_t index;
 
-       err = f2fs_get_node_info(sbi, dn->nid, &ni);
+       err = f2fs_get_node_info(sbi, dn->nid, &ni, false);
        if (err)
                return err;
 
@@ -1290,7 +1291,7 @@ struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs)
                goto fail;
 
 #ifdef CONFIG_F2FS_CHECK_FS
-       err = f2fs_get_node_info(sbi, dn->nid, &new_ni);
+       err = f2fs_get_node_info(sbi, dn->nid, &new_ni, false);
        if (err) {
                dec_valid_node_count(sbi, dn->inode, !ofs);
                goto fail;
@@ -1352,7 +1353,7 @@ static int read_node_page(struct page *page, int op_flags)
                return LOCKED_PAGE;
        }
 
-       err = f2fs_get_node_info(sbi, page->index, &ni);
+       err = f2fs_get_node_info(sbi, page->index, &ni, false);
        if (err)
                return err;
 
@@ -1604,7 +1605,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
        nid = nid_of_node(page);
        f2fs_bug_on(sbi, page->index != nid);
 
-       if (f2fs_get_node_info(sbi, nid, &ni))
+       if (f2fs_get_node_info(sbi, nid, &ni, !do_balance))
                goto redirty_out;
 
        if (wbc->for_reclaim) {
@@ -2705,7 +2706,7 @@ int f2fs_recover_xattr_data(struct inode *inode, struct page *page)
                goto recover_xnid;
 
        /* 1: invalidate the previous xattr nid */
-       err = f2fs_get_node_info(sbi, prev_xnid, &ni);
+       err = f2fs_get_node_info(sbi, prev_xnid, &ni, false);
        if (err)
                return err;
 
@@ -2745,7 +2746,7 @@ int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
        struct page *ipage;
        int err;
 
-       err = f2fs_get_node_info(sbi, ino, &old_ni);
+       err = f2fs_get_node_info(sbi, ino, &old_ni, false);
        if (err)
                return err;
 
index 6a1b4668d933aad629a4c4426a12429da1d66b87..e65c73c4411dcbf901ae0f6cdf5e241118a5a185 100644 (file)
@@ -595,7 +595,7 @@ retry_dn:
 
        f2fs_wait_on_page_writeback(dn.node_page, NODE, true, true);
 
-       err = f2fs_get_node_info(sbi, dn.nid, &ni);
+       err = f2fs_get_node_info(sbi, dn.nid, &ni, false);
        if (err)
                goto err;
 
index df9ed75f0b7a766a4466ee0bf2733e15c5e60d36..b4a2f8c36149a186de112d34a16e32d625f73a67 100644 (file)
@@ -254,7 +254,7 @@ retry:
                                goto next;
                        }
 
-                       err = f2fs_get_node_info(sbi, dn.nid, &ni);
+                       err = f2fs_get_node_info(sbi, dn.nid, &ni, false);
                        if (err) {
                                f2fs_put_dnode(&dn);
                                return err;