aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2014-01-07 20:09:51 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2014-01-07 21:16:20 -0500
commitfb5566da9181d33ecdd9892e44f90320e7d4cc9f (patch)
treed3b1656ec7e454ea2d831f673a538f2f78d1f85a
parent04a17fb17fafada39f96bfb41ceb2dc1c11b2af6 (diff)
f2fs: improve write performance under frequent fsync calls
When considering a bunch of data writes with very frequent fsync calls, we are able to think the following performance regression. N: Node IO, D: Data IO, IO scheduler: cfq Issue pending IOs D1 D2 D3 D4 D1 D2 D3 D4 N1 D2 D3 D4 N1 N2 N1 D3 D4 N2 D1 --> N1 can be selected by cfq becase of the same priority of N and D. Then D3 and D4 would be delayed, resuling in performance degradation. So, when processing the fsync call, it'd better give higher priority to data IOs than node IOs by assigning WRITE and WRITE_SYNC respectively. This patch improves the random wirte performance with frequent fsync calls by up to 10%. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
-rw-r--r--fs/f2fs/f2fs.h4
-rw-r--r--fs/f2fs/file.c2
-rw-r--r--fs/f2fs/node.c7
-rw-r--r--fs/f2fs/segment.c8
4 files changed, 11 insertions, 10 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 07a7ae0d4413..b69f190fb195 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1118,8 +1118,8 @@ int npages_for_summary_flush(struct f2fs_sb_info *);
1118void allocate_new_segments(struct f2fs_sb_info *); 1118void allocate_new_segments(struct f2fs_sb_info *);
1119struct page *get_sum_page(struct f2fs_sb_info *, unsigned int); 1119struct page *get_sum_page(struct f2fs_sb_info *, unsigned int);
1120void write_meta_page(struct f2fs_sb_info *, struct page *); 1120void write_meta_page(struct f2fs_sb_info *, struct page *);
1121void write_node_page(struct f2fs_sb_info *, struct page *, unsigned int, 1121void write_node_page(struct f2fs_sb_info *, struct page *,
1122 block_t, block_t *); 1122 struct f2fs_io_info *, unsigned int, block_t, block_t *);
1123void write_data_page(struct page *, struct dnode_of_data *, block_t *, 1123void write_data_page(struct page *, struct dnode_of_data *, block_t *,
1124 struct f2fs_io_info *); 1124 struct f2fs_io_info *);
1125void rewrite_data_page(struct page *, block_t, struct f2fs_io_info *); 1125void rewrite_data_page(struct page *, block_t, struct f2fs_io_info *);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index c77ad4d8b564..14511b00fffa 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -115,7 +115,7 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
115 int ret = 0; 115 int ret = 0;
116 bool need_cp = false; 116 bool need_cp = false;
117 struct writeback_control wbc = { 117 struct writeback_control wbc = {
118 .sync_mode = WB_SYNC_ALL, 118 .sync_mode = WB_SYNC_NONE,
119 .nr_to_write = LONG_MAX, 119 .nr_to_write = LONG_MAX,
120 .for_reclaim = 0, 120 .for_reclaim = 0,
121 }; 121 };
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 0230326be495..b8c9301db52c 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1194,6 +1194,10 @@ static int f2fs_write_node_page(struct page *page,
1194 nid_t nid; 1194 nid_t nid;
1195 block_t new_addr; 1195 block_t new_addr;
1196 struct node_info ni; 1196 struct node_info ni;
1197 struct f2fs_io_info fio = {
1198 .type = NODE,
1199 .rw = (wbc->sync_mode == WB_SYNC_ALL) ? WRITE_SYNC: WRITE,
1200 };
1197 1201
1198 if (unlikely(sbi->por_doing)) 1202 if (unlikely(sbi->por_doing))
1199 goto redirty_out; 1203 goto redirty_out;
@@ -1218,7 +1222,7 @@ static int f2fs_write_node_page(struct page *page,
1218 1222
1219 mutex_lock(&sbi->node_write); 1223 mutex_lock(&sbi->node_write);
1220 set_page_writeback(page); 1224 set_page_writeback(page);
1221 write_node_page(sbi, page, nid, ni.blk_addr, &new_addr); 1225 write_node_page(sbi, page, &fio, nid, ni.blk_addr, &new_addr);
1222 set_node_addr(sbi, &ni, new_addr); 1226 set_node_addr(sbi, &ni, new_addr);
1223 dec_page_count(sbi, F2FS_DIRTY_NODES); 1227 dec_page_count(sbi, F2FS_DIRTY_NODES);
1224 mutex_unlock(&sbi->node_write); 1228 mutex_unlock(&sbi->node_write);
@@ -1253,6 +1257,7 @@ static int f2fs_write_node_pages(struct address_space *mapping,
1253 1257
1254 /* if mounting is failed, skip writing node pages */ 1258 /* if mounting is failed, skip writing node pages */
1255 wbc->nr_to_write = 3 * max_hw_blocks(sbi); 1259 wbc->nr_to_write = 3 * max_hw_blocks(sbi);
1260 wbc->sync_mode = WB_SYNC_NONE;
1256 sync_node_pages(sbi, 0, wbc); 1261 sync_node_pages(sbi, 0, wbc);
1257 wbc->nr_to_write = nr_to_write - (3 * max_hw_blocks(sbi) - 1262 wbc->nr_to_write = nr_to_write - (3 * max_hw_blocks(sbi) -
1258 wbc->nr_to_write); 1263 wbc->nr_to_write);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 555ae7693ea0..5f84639354e3 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -924,16 +924,12 @@ void write_meta_page(struct f2fs_sb_info *sbi, struct page *page)
924} 924}
925 925
926void write_node_page(struct f2fs_sb_info *sbi, struct page *page, 926void write_node_page(struct f2fs_sb_info *sbi, struct page *page,
927 struct f2fs_io_info *fio,
927 unsigned int nid, block_t old_blkaddr, block_t *new_blkaddr) 928 unsigned int nid, block_t old_blkaddr, block_t *new_blkaddr)
928{ 929{
929 struct f2fs_summary sum; 930 struct f2fs_summary sum;
930 struct f2fs_io_info fio = {
931 .type = NODE,
932 .rw = WRITE_SYNC,
933 };
934
935 set_summary(&sum, nid, 0, 0); 931 set_summary(&sum, nid, 0, 0);
936 do_write_page(sbi, page, old_blkaddr, new_blkaddr, &sum, &fio); 932 do_write_page(sbi, page, old_blkaddr, new_blkaddr, &sum, fio);
937} 933}
938 934
939void write_data_page(struct page *page, struct dnode_of_data *dn, 935void write_data_page(struct page *page, struct dnode_of_data *dn,