aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSahitya Tummala2020-11-22 23:28:32 -0600
committerJaegeuk Kim2020-12-21 15:33:14 -0600
commit301e31717eb7c2f1df1d99af0b36d22c11e09326 (patch)
tree8edcc988df08ce58f6699c8409f716fedfc805bc
parentc689f750b411165af73bd730652a379d01570469 (diff)
downloadkernel-301e31717eb7c2f1df1d99af0b36d22c11e09326.tar.gz
kernel-301e31717eb7c2f1df1d99af0b36d22c11e09326.tar.xz
kernel-301e31717eb7c2f1df1d99af0b36d22c11e09326.zip
f2fs: change to use rwsem for cp_mutex
Use rwsem to ensure serialization of the callers and to avoid starvation of high priority tasks, when the system is under heavy IO workload. Signed-off-by: Sahitya Tummala <stummala@codeaurora.org> Reviewed-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fs/f2fs/checkpoint.c8
-rw-r--r--fs/f2fs/f2fs.h2
-rw-r--r--fs/f2fs/gc.c4
-rw-r--r--fs/f2fs/recovery.c4
-rw-r--r--fs/f2fs/super.c2
5 files changed, 10 insertions, 10 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 9b0628e0d8bc..e5d2ffa80b56 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -348,13 +348,13 @@ static int f2fs_write_meta_pages(struct address_space *mapping,
348 goto skip_write; 348 goto skip_write;
349 349
350 /* if locked failed, cp will flush dirty pages instead */ 350 /* if locked failed, cp will flush dirty pages instead */
351 if (!mutex_trylock(&sbi->cp_mutex)) 351 if (!down_write_trylock(&sbi->cp_global_sem))
352 goto skip_write; 352 goto skip_write;
353 353
354 trace_f2fs_writepages(mapping->host, wbc, META); 354 trace_f2fs_writepages(mapping->host, wbc, META);
355 diff = nr_pages_to_write(sbi, META, wbc); 355 diff = nr_pages_to_write(sbi, META, wbc);
356 written = f2fs_sync_meta_pages(sbi, META, wbc->nr_to_write, FS_META_IO); 356 written = f2fs_sync_meta_pages(sbi, META, wbc->nr_to_write, FS_META_IO);
357 mutex_unlock(&sbi->cp_mutex); 357 up_write(&sbi->cp_global_sem);
358 wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff); 358 wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff);
359 return 0; 359 return 0;
360 360
@@ -1572,7 +1572,7 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
1572 f2fs_warn(sbi, "Start checkpoint disabled!"); 1572 f2fs_warn(sbi, "Start checkpoint disabled!");
1573 } 1573 }
1574 if (cpc->reason != CP_RESIZE) 1574 if (cpc->reason != CP_RESIZE)
1575 mutex_lock(&sbi->cp_mutex); 1575 down_write(&sbi->cp_global_sem);
1576 1576
1577 if (!is_sbi_flag_set(sbi, SBI_IS_DIRTY) && 1577 if (!is_sbi_flag_set(sbi, SBI_IS_DIRTY) &&
1578 ((cpc->reason & CP_FASTBOOT) || (cpc->reason & CP_SYNC) || 1578 ((cpc->reason & CP_FASTBOOT) || (cpc->reason & CP_SYNC) ||
@@ -1647,7 +1647,7 @@ stop:
1647 trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint"); 1647 trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint");
1648out: 1648out:
1649 if (cpc->reason != CP_RESIZE) 1649 if (cpc->reason != CP_RESIZE)
1650 mutex_unlock(&sbi->cp_mutex); 1650 up_write(&sbi->cp_global_sem);
1651 return err; 1651 return err;
1652} 1652}
1653 1653
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index c626fb03d5bc..273f068e8899 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1369,7 +1369,7 @@ struct f2fs_sb_info {
1369 int cur_cp_pack; /* remain current cp pack */ 1369 int cur_cp_pack; /* remain current cp pack */
1370 spinlock_t cp_lock; /* for flag in ckpt */ 1370 spinlock_t cp_lock; /* for flag in ckpt */
1371 struct inode *meta_inode; /* cache meta blocks */ 1371 struct inode *meta_inode; /* cache meta blocks */
1372 struct mutex cp_mutex; /* checkpoint procedure lock */ 1372 struct rw_semaphore cp_global_sem; /* checkpoint procedure lock */
1373 struct rw_semaphore cp_rwsem; /* blocking FS operations */ 1373 struct rw_semaphore cp_rwsem; /* blocking FS operations */
1374 struct rw_semaphore node_write; /* locking node writes */ 1374 struct rw_semaphore node_write; /* locking node writes */
1375 struct rw_semaphore node_change; /* locking node change */ 1375 struct rw_semaphore node_change; /* locking node change */
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 05641a1e36cc..3ef84e6ded41 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1986,7 +1986,7 @@ int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count)
1986 1986
1987 freeze_super(sbi->sb); 1987 freeze_super(sbi->sb);
1988 down_write(&sbi->gc_lock); 1988 down_write(&sbi->gc_lock);
1989 mutex_lock(&sbi->cp_mutex); 1989 down_write(&sbi->cp_global_sem);
1990 1990
1991 spin_lock(&sbi->stat_lock); 1991 spin_lock(&sbi->stat_lock);
1992 if (shrunk_blocks + valid_user_blocks(sbi) + 1992 if (shrunk_blocks + valid_user_blocks(sbi) +
@@ -2031,7 +2031,7 @@ recover_out:
2031 spin_unlock(&sbi->stat_lock); 2031 spin_unlock(&sbi->stat_lock);
2032 } 2032 }
2033out_err: 2033out_err:
2034 mutex_unlock(&sbi->cp_mutex); 2034 up_write(&sbi->cp_global_sem);
2035 up_write(&sbi->gc_lock); 2035 up_write(&sbi->gc_lock);
2036 thaw_super(sbi->sb); 2036 thaw_super(sbi->sb);
2037 clear_sbi_flag(sbi, SBI_IS_RESIZEFS); 2037 clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 0947d36af1a8..da75d5d52f0a 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -799,7 +799,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
799 INIT_LIST_HEAD(&dir_list); 799 INIT_LIST_HEAD(&dir_list);
800 800
801 /* prevent checkpoint */ 801 /* prevent checkpoint */
802 mutex_lock(&sbi->cp_mutex); 802 down_write(&sbi->cp_global_sem);
803 803
804 /* step #1: find fsynced inode numbers */ 804 /* step #1: find fsynced inode numbers */
805 err = find_fsync_dnodes(sbi, &inode_list, check_only); 805 err = find_fsync_dnodes(sbi, &inode_list, check_only);
@@ -850,7 +850,7 @@ skip:
850 if (!err) 850 if (!err)
851 clear_sbi_flag(sbi, SBI_POR_DOING); 851 clear_sbi_flag(sbi, SBI_POR_DOING);
852 852
853 mutex_unlock(&sbi->cp_mutex); 853 up_write(&sbi->cp_global_sem);
854 854
855 /* let's drop all the directory inodes for clean checkpoint */ 855 /* let's drop all the directory inodes for clean checkpoint */
856 destroy_fsync_dnodes(&dir_list, err); 856 destroy_fsync_dnodes(&dir_list, err);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 1c282c3da263..82baaa89c893 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -3551,7 +3551,7 @@ try_onemore:
3551 sbi->valid_super_block = valid_super_block; 3551 sbi->valid_super_block = valid_super_block;
3552 init_rwsem(&sbi->gc_lock); 3552 init_rwsem(&sbi->gc_lock);
3553 mutex_init(&sbi->writepages); 3553 mutex_init(&sbi->writepages);
3554 mutex_init(&sbi->cp_mutex); 3554 init_rwsem(&sbi->cp_global_sem);
3555 init_rwsem(&sbi->node_write); 3555 init_rwsem(&sbi->node_write);
3556 init_rwsem(&sbi->node_change); 3556 init_rwsem(&sbi->node_change);
3557 3557