aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2014-03-22 02:57:23 -0400
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2014-04-01 05:53:41 -0400
commitdf0f8dc0e154de13e3a54846f384b674dd557c85 (patch)
tree9465da562d6136bd8a49d55b834f3713af880c5f
parent3bb5e2c8fe2296ddd9d864dcfb5ee1b77135f3ec (diff)
f2fs: avoid unnecessary bio submit when wait page writeback
This patch introduce is_merged_page() to check whether current page is merged in f2fs bio cache. When page is not in cache, we can avoid submitting bio cache, resulting in having more chance to merge pages. Signed-off-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
-rw-r--r--fs/f2fs/data.c8
-rw-r--r--fs/f2fs/f2fs.h2
-rw-r--r--fs/f2fs/segment.c28
-rw-r--r--fs/f2fs/super.c4
4 files changed, 34 insertions, 8 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index b0c923aef229..598bfa617a7e 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -134,7 +134,7 @@ void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
134 134
135 io = is_read_io(rw) ? &sbi->read_io : &sbi->write_io[btype]; 135 io = is_read_io(rw) ? &sbi->read_io : &sbi->write_io[btype];
136 136
137 mutex_lock(&io->io_mutex); 137 down_write(&io->io_rwsem);
138 138
139 /* change META to META_FLUSH in the checkpoint procedure */ 139 /* change META to META_FLUSH in the checkpoint procedure */
140 if (type >= META_FLUSH) { 140 if (type >= META_FLUSH) {
@@ -142,7 +142,7 @@ void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
142 io->fio.rw = WRITE_FLUSH_FUA | REQ_META | REQ_PRIO; 142 io->fio.rw = WRITE_FLUSH_FUA | REQ_META | REQ_PRIO;
143 } 143 }
144 __submit_merged_bio(io); 144 __submit_merged_bio(io);
145 mutex_unlock(&io->io_mutex); 145 up_write(&io->io_rwsem);
146} 146}
147 147
148/* 148/*
@@ -180,7 +180,7 @@ void f2fs_submit_page_mbio(struct f2fs_sb_info *sbi, struct page *page,
180 180
181 verify_block_addr(sbi, blk_addr); 181 verify_block_addr(sbi, blk_addr);
182 182
183 mutex_lock(&io->io_mutex); 183 down_write(&io->io_rwsem);
184 184
185 if (!is_read) 185 if (!is_read)
186 inc_page_count(sbi, F2FS_WRITEBACK); 186 inc_page_count(sbi, F2FS_WRITEBACK);
@@ -204,7 +204,7 @@ alloc_new:
204 204
205 io->last_block_in_bio = blk_addr; 205 io->last_block_in_bio = blk_addr;
206 206
207 mutex_unlock(&io->io_mutex); 207 up_write(&io->io_rwsem);
208 trace_f2fs_submit_page_mbio(page, fio->rw, fio->type, blk_addr); 208 trace_f2fs_submit_page_mbio(page, fio->rw, fio->type, blk_addr);
209} 209}
210 210
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index f83433e4b043..1e3d869b60cd 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -394,7 +394,7 @@ struct f2fs_bio_info {
394 struct bio *bio; /* bios to merge */ 394 struct bio *bio; /* bios to merge */
395 sector_t last_block_in_bio; /* last block number */ 395 sector_t last_block_in_bio; /* last block number */
396 struct f2fs_io_info fio; /* store buffered io info. */ 396 struct f2fs_io_info fio; /* store buffered io info. */
397 struct mutex io_mutex; /* mutex for bio */ 397 struct rw_semaphore io_rwsem; /* blocking op for bio */
398}; 398};
399 399
400struct f2fs_sb_info { 400struct f2fs_sb_info {
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index e7ff23a536a4..570ab9a084c5 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1046,12 +1046,38 @@ void rewrite_node_page(struct f2fs_sb_info *sbi,
1046 mutex_unlock(&curseg->curseg_mutex); 1046 mutex_unlock(&curseg->curseg_mutex);
1047} 1047}
1048 1048
1049static inline bool is_merged_page(struct f2fs_sb_info *sbi,
1050 struct page *page, enum page_type type)
1051{
1052 enum page_type btype = PAGE_TYPE_OF_BIO(type);
1053 struct f2fs_bio_info *io = &sbi->write_io[btype];
1054 struct bio *bio = io->bio;
1055 struct bio_vec *bvec;
1056 int i;
1057
1058 down_read(&io->io_rwsem);
1059 if (!bio)
1060 goto out;
1061
1062 bio_for_each_segment_all(bvec, bio, i) {
1063 if (page == bvec->bv_page) {
1064 up_read(&io->io_rwsem);
1065 return true;
1066 }
1067 }
1068
1069out:
1070 up_read(&io->io_rwsem);
1071 return false;
1072}
1073
1049void f2fs_wait_on_page_writeback(struct page *page, 1074void f2fs_wait_on_page_writeback(struct page *page,
1050 enum page_type type) 1075 enum page_type type)
1051{ 1076{
1052 struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb); 1077 struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb);
1053 if (PageWriteback(page)) { 1078 if (PageWriteback(page)) {
1054 f2fs_submit_merged_bio(sbi, type, WRITE); 1079 if (is_merged_page(sbi, page, type))
1080 f2fs_submit_merged_bio(sbi, type, WRITE);
1055 wait_on_page_writeback(page); 1081 wait_on_page_writeback(page);
1056 } 1082 }
1057} 1083}
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 89ea046c846d..959834066d60 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -920,11 +920,11 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
920 sbi->por_doing = false; 920 sbi->por_doing = false;
921 spin_lock_init(&sbi->stat_lock); 921 spin_lock_init(&sbi->stat_lock);
922 922
923 mutex_init(&sbi->read_io.io_mutex); 923 init_rwsem(&sbi->read_io.io_rwsem);
924 sbi->read_io.sbi = sbi; 924 sbi->read_io.sbi = sbi;
925 sbi->read_io.bio = NULL; 925 sbi->read_io.bio = NULL;
926 for (i = 0; i < NR_PAGE_TYPE; i++) { 926 for (i = 0; i < NR_PAGE_TYPE; i++) {
927 mutex_init(&sbi->write_io[i].io_mutex); 927 init_rwsem(&sbi->write_io[i].io_rwsem);
928 sbi->write_io[i].sbi = sbi; 928 sbi->write_io[i].sbi = sbi;
929 sbi->write_io[i].bio = NULL; 929 sbi->write_io[i].bio = NULL;
930 } 930 }