Commit df0f8dc0e154de13e3a54846f384b674dd557c85

Authored by Chao Yu
Committed by Jaegeuk Kim
1 parent 3bb5e2c8fe

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>

Showing 4 changed files with 34 additions and 8 deletions Side-by-side Diff

... ... @@ -134,7 +134,7 @@
134 134  
135 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 139 /* change META to META_FLUSH in the checkpoint procedure */
140 140 if (type >= META_FLUSH) {
... ... @@ -142,7 +142,7 @@
142 142 io->fio.rw = WRITE_FLUSH_FUA | REQ_META | REQ_PRIO;
143 143 }
144 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 @@
180 180  
181 181 verify_block_addr(sbi, blk_addr);
182 182  
183   - mutex_lock(&io->io_mutex);
  183 + down_write(&io->io_rwsem);
184 184  
185 185 if (!is_read)
186 186 inc_page_count(sbi, F2FS_WRITEBACK);
... ... @@ -204,7 +204,7 @@
204 204  
205 205 io->last_block_in_bio = blk_addr;
206 206  
207   - mutex_unlock(&io->io_mutex);
  207 + up_write(&io->io_rwsem);
208 208 trace_f2fs_submit_page_mbio(page, fio->rw, fio->type, blk_addr);
209 209 }
210 210  
... ... @@ -394,7 +394,7 @@
394 394 struct bio *bio; /* bios to merge */
395 395 sector_t last_block_in_bio; /* last block number */
396 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  
400 400 struct f2fs_sb_info {
... ... @@ -1046,12 +1046,38 @@
1046 1046 mutex_unlock(&curseg->curseg_mutex);
1047 1047 }
1048 1048  
  1049 +static 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 +
  1069 +out:
  1070 + up_read(&io->io_rwsem);
  1071 + return false;
  1072 +}
  1073 +
1049 1074 void f2fs_wait_on_page_writeback(struct page *page,
1050 1075 enum page_type type)
1051 1076 {
1052 1077 struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb);
1053 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 1081 wait_on_page_writeback(page);
1056 1082 }
1057 1083 }
... ... @@ -920,11 +920,11 @@
920 920 sbi->por_doing = false;
921 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 924 sbi->read_io.sbi = sbi;
925 925 sbi->read_io.bio = NULL;
926 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 928 sbi->write_io[i].sbi = sbi;
929 929 sbi->write_io[i].bio = NULL;
930 930 }