aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2014-01-08 10:09:51 +0900
committerrogersb11 <brettrogers11@gmail.com>2016-02-13 21:06:27 -0500
commitcc8c6bbf559cd5a87cff8435321877fe5f5266a5 (patch)
treeae363179b668eb4f614e0b856a5d6d8a3ef249d4
parentd4322cd694ca73be92c2b6f8d96226ba4734bd6a (diff)
downloadkernel_samsung_smdk4412-cc8c6bbf559cd5a87cff8435321877fe5f5266a5.zip
kernel_samsung_smdk4412-cc8c6bbf559cd5a87cff8435321877fe5f5266a5.tar.gz
kernel_samsung_smdk4412-cc8c6bbf559cd5a87cff8435321877fe5f5266a5.tar.bz2
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%. Change-Id: I4812ac05db179d83914c7bb0942fa6738280e1ea 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 4581644..4847982 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1119,8 +1119,8 @@ int npages_for_summary_flush(struct f2fs_sb_info *);
void allocate_new_segments(struct f2fs_sb_info *);
struct page *get_sum_page(struct f2fs_sb_info *, unsigned int);
void write_meta_page(struct f2fs_sb_info *, struct page *);
-void write_node_page(struct f2fs_sb_info *, struct page *, unsigned int,
- block_t, block_t *);
+void write_node_page(struct f2fs_sb_info *, struct page *,
+ struct f2fs_io_info *, unsigned int, block_t, block_t *);
void write_data_page(struct page *, struct dnode_of_data *, block_t *,
struct f2fs_io_info *);
void rewrite_data_page(struct page *, block_t, struct f2fs_io_info *);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 775f200..5211f54 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -124,7 +124,7 @@ int f2fs_sync_file(struct file *file, int datasync)
int ret = 0;
bool need_cp = false;
struct writeback_control wbc = {
- .sync_mode = WB_SYNC_ALL,
+ .sync_mode = WB_SYNC_NONE,
.nr_to_write = LONG_MAX,
.for_reclaim = 0,
};
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 8d7b3fb..d3c8c4c 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1194,6 +1194,10 @@ static int f2fs_write_node_page(struct page *page,
nid_t nid;
block_t new_addr;
struct node_info ni;
+ struct f2fs_io_info fio = {
+ .type = NODE,
+ .rw = (wbc->sync_mode == WB_SYNC_ALL) ? WRITE_SYNC: WRITE,
+ };
if (unlikely(sbi->por_doing))
goto redirty_out;
@@ -1218,7 +1222,7 @@ static int f2fs_write_node_page(struct page *page,
mutex_lock(&sbi->node_write);
set_page_writeback(page);
- write_node_page(sbi, page, nid, ni.blk_addr, &new_addr);
+ write_node_page(sbi, page, &fio, nid, ni.blk_addr, &new_addr);
set_node_addr(sbi, &ni, new_addr);
dec_page_count(sbi, F2FS_DIRTY_NODES);
mutex_unlock(&sbi->node_write);
@@ -1253,6 +1257,7 @@ static int f2fs_write_node_pages(struct address_space *mapping,
/* if mounting is failed, skip writing node pages */
wbc->nr_to_write = 3 * max_hw_blocks(sbi);
+ wbc->sync_mode = WB_SYNC_NONE;
sync_node_pages(sbi, 0, wbc);
wbc->nr_to_write = nr_to_write - (3 * max_hw_blocks(sbi) -
wbc->nr_to_write);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 555ae76..5f84639 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)
}
void write_node_page(struct f2fs_sb_info *sbi, struct page *page,
+ struct f2fs_io_info *fio,
unsigned int nid, block_t old_blkaddr, block_t *new_blkaddr)
{
struct f2fs_summary sum;
- struct f2fs_io_info fio = {
- .type = NODE,
- .rw = WRITE_SYNC,
- };
-
set_summary(&sum, nid, 0, 0);
- do_write_page(sbi, page, old_blkaddr, new_blkaddr, &sum, &fio);
+ do_write_page(sbi, page, old_blkaddr, new_blkaddr, &sum, fio);
}
void write_data_page(struct page *page, struct dnode_of_data *dn,