FROMGIT: f2fs: move f2fs to use reader-unfair rwsems
f2fs rw_semaphores work better if writers can starve readers, especially for the checkpoint thread, because writers are strictly more important than reader threads. This prevents significant priority inversion between low-priority readers that blocked while trying to acquire the read lock and a second acquisition of the write lock that might be blocking high priority work. Bug: 214413989 Signed-off-by: Tim Murray <timmurray@google.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> (cherry picked from commit e4544b63a7ee49e7fbebf35ece0a6acd3b9617ae git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git dev) Change-Id: Ia0eb86447488c5ba9845a6b2eb98652200e08281
This commit is contained in:
@@ -350,13 +350,13 @@ static int f2fs_write_meta_pages(struct address_space *mapping,
|
||||
goto skip_write;
|
||||
|
||||
/* if locked failed, cp will flush dirty pages instead */
|
||||
if (!down_write_trylock(&sbi->cp_global_sem))
|
||||
if (!f2fs_down_write_trylock(&sbi->cp_global_sem))
|
||||
goto skip_write;
|
||||
|
||||
trace_f2fs_writepages(mapping->host, wbc, META);
|
||||
diff = nr_pages_to_write(sbi, META, wbc);
|
||||
written = f2fs_sync_meta_pages(sbi, META, wbc->nr_to_write, FS_META_IO);
|
||||
up_write(&sbi->cp_global_sem);
|
||||
f2fs_up_write(&sbi->cp_global_sem);
|
||||
wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff);
|
||||
return 0;
|
||||
|
||||
@@ -1148,7 +1148,8 @@ static bool __need_flush_quota(struct f2fs_sb_info *sbi)
|
||||
if (!is_journalled_quota(sbi))
|
||||
return false;
|
||||
|
||||
down_write(&sbi->quota_sem);
|
||||
if (!f2fs_down_write_trylock(&sbi->quota_sem))
|
||||
return true;
|
||||
if (is_sbi_flag_set(sbi, SBI_QUOTA_SKIP_FLUSH)) {
|
||||
ret = false;
|
||||
} else if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_REPAIR)) {
|
||||
@@ -1159,7 +1160,7 @@ static bool __need_flush_quota(struct f2fs_sb_info *sbi)
|
||||
} else if (get_pages(sbi, F2FS_DIRTY_QDATA)) {
|
||||
ret = true;
|
||||
}
|
||||
up_write(&sbi->quota_sem);
|
||||
f2fs_up_write(&sbi->quota_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1216,10 +1217,10 @@ retry_flush_dents:
|
||||
* POR: we should ensure that there are no dirty node pages
|
||||
* until finishing nat/sit flush. inode->i_blocks can be updated.
|
||||
*/
|
||||
down_write(&sbi->node_change);
|
||||
f2fs_down_write(&sbi->node_change);
|
||||
|
||||
if (get_pages(sbi, F2FS_DIRTY_IMETA)) {
|
||||
up_write(&sbi->node_change);
|
||||
f2fs_up_write(&sbi->node_change);
|
||||
f2fs_unlock_all(sbi);
|
||||
err = f2fs_sync_inode_meta(sbi);
|
||||
if (err)
|
||||
@@ -1229,15 +1230,15 @@ retry_flush_dents:
|
||||
}
|
||||
|
||||
retry_flush_nodes:
|
||||
down_write(&sbi->node_write);
|
||||
f2fs_down_write(&sbi->node_write);
|
||||
|
||||
if (get_pages(sbi, F2FS_DIRTY_NODES)) {
|
||||
up_write(&sbi->node_write);
|
||||
f2fs_up_write(&sbi->node_write);
|
||||
atomic_inc(&sbi->wb_sync_req[NODE]);
|
||||
err = f2fs_sync_node_pages(sbi, &wbc, false, FS_CP_NODE_IO);
|
||||
atomic_dec(&sbi->wb_sync_req[NODE]);
|
||||
if (err) {
|
||||
up_write(&sbi->node_change);
|
||||
f2fs_up_write(&sbi->node_change);
|
||||
f2fs_unlock_all(sbi);
|
||||
return err;
|
||||
}
|
||||
@@ -1250,13 +1251,13 @@ retry_flush_nodes:
|
||||
* dirty node blocks and some checkpoint values by block allocation.
|
||||
*/
|
||||
__prepare_cp_block(sbi);
|
||||
up_write(&sbi->node_change);
|
||||
f2fs_up_write(&sbi->node_change);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void unblock_operations(struct f2fs_sb_info *sbi)
|
||||
{
|
||||
up_write(&sbi->node_write);
|
||||
f2fs_up_write(&sbi->node_write);
|
||||
f2fs_unlock_all(sbi);
|
||||
}
|
||||
|
||||
@@ -1591,7 +1592,7 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
|
||||
f2fs_warn(sbi, "Start checkpoint disabled!");
|
||||
}
|
||||
if (cpc->reason != CP_RESIZE)
|
||||
down_write(&sbi->cp_global_sem);
|
||||
f2fs_down_write(&sbi->cp_global_sem);
|
||||
|
||||
if (!is_sbi_flag_set(sbi, SBI_IS_DIRTY) &&
|
||||
((cpc->reason & CP_FASTBOOT) || (cpc->reason & CP_SYNC) ||
|
||||
@@ -1666,7 +1667,7 @@ stop:
|
||||
trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint");
|
||||
out:
|
||||
if (cpc->reason != CP_RESIZE)
|
||||
up_write(&sbi->cp_global_sem);
|
||||
f2fs_up_write(&sbi->cp_global_sem);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1714,9 +1715,9 @@ static int __write_checkpoint_sync(struct f2fs_sb_info *sbi)
|
||||
struct cp_control cpc = { .reason = CP_SYNC, };
|
||||
int err;
|
||||
|
||||
down_write(&sbi->gc_lock);
|
||||
f2fs_down_write(&sbi->gc_lock);
|
||||
err = f2fs_write_checkpoint(sbi, &cpc);
|
||||
up_write(&sbi->gc_lock);
|
||||
f2fs_up_write(&sbi->gc_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -1804,9 +1805,9 @@ int f2fs_issue_checkpoint(struct f2fs_sb_info *sbi)
|
||||
if (!test_opt(sbi, MERGE_CHECKPOINT) || cpc.reason != CP_SYNC) {
|
||||
int ret;
|
||||
|
||||
down_write(&sbi->gc_lock);
|
||||
f2fs_down_write(&sbi->gc_lock);
|
||||
ret = f2fs_write_checkpoint(sbi, &cpc);
|
||||
up_write(&sbi->gc_lock);
|
||||
f2fs_up_write(&sbi->gc_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user