Re: [f2fs-dev] [PATCH] f2fs: refactor bio-related operations
Hi, 2013-12-02 (월), 12:47 +0800, Chao Yu: > Hi, > > Some comments as following. > > > -Original Message- > > From: Jaegeuk Kim [mailto:jaegeuk@samsung.com] > > Sent: Saturday, November 30, 2013 2:26 PM > > Cc: linux-fsde...@vger.kernel.org; linux-ker...@vger.kernel.org; > > linux-f2fs-devel@lists.sourceforge.net > > Subject: [f2fs-dev] [PATCH] f2fs: refactor bio-related operations > > > > [snip] > > > +void f2fs_submit_page_mbio(struct f2fs_sb_info *sbi, struct page *page, > > + block_t blk_addr, enum page_type type, int rw) > > +{ > > + enum page_type btype = PAGE_TYPE_OF_BIO(type); > > + struct block_device *bdev = sbi->sb->s_bdev; > > + struct f2fs_bio_info *io; > > + int bio_blocks; > > + > > + io = is_read_io(rw) ? &sbi->read_io : &sbi->write_io[btype]; > > + > > + verify_block_addr(sbi, blk_addr); > > + > > + mutex_lock(&io->io_mutex); > > + > > + if (!is_read_io(rw)) > > + inc_page_count(sbi, F2FS_WRITEBACK); > > + > > + if (io->bio && io->last_block_in_bio != blk_addr - 1) > > + __submit_merged_bio(sbi, io, type, true, rw); > > +alloc_new: > > + if (io->bio == NULL) { > > + bio_blocks = MAX_BIO_BLOCKS(max_hw_blocks(sbi)); > > + io->bio = __bio_alloc(bdev, bio_blocks); > > + io->bio->bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr); > > + io->bio->bi_end_io = is_read_io(rw) ? f2fs_read_end_io : > > + f2fs_write_end_io; > > + /* > > +* The end_io will be assigned at the sumbission phase. > > +* Until then, let bio_add_page() merge consecutive IOs as much > > +* as possible. > > +*/ > > + } > > + > > + if (bio_add_page(io->bio, page, PAGE_CACHE_SIZE, 0) < > > + PAGE_CACHE_SIZE) { > > + __submit_merged_bio(sbi, io, type, true, rw); > > + io->bio = NULL; > > We should remove the redundant code " io->bio = NULL;" here, > because __submit_merged_bio does the same job. Agreed. > > [snip] > > > /* > > * data.c > > */ > > +void f2fs_submit_merged_bio(struct f2fs_sb_info *, enum page_type, bool, > > int); > > +int f2fs_submit_page_bio(struct f2fs_sb_info *, struct page *, block_t, > > int); > > Redundant to the following code. Ah, agreed. Thank you for the review. :) -- Jaegeuk Kim Samsung -- Rapidly troubleshoot problems before they affect your business. Most IT organizations don't have a clear picture of how application performance affects their revenue. With AppDynamics, you get 100% visibility into your Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! http://pubads.g.doubleclick.net/gampad/clk?id=84349351&iu=/4140/ostg.clktrk ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH] f2fs: refactor bio-related operations
Hi, Some comments as following. > -Original Message- > From: Jaegeuk Kim [mailto:jaegeuk@samsung.com] > Sent: Saturday, November 30, 2013 2:26 PM > Cc: linux-fsde...@vger.kernel.org; linux-ker...@vger.kernel.org; > linux-f2fs-devel@lists.sourceforge.net > Subject: [f2fs-dev] [PATCH] f2fs: refactor bio-related operations > [snip] > +void f2fs_submit_page_mbio(struct f2fs_sb_info *sbi, struct page *page, > + block_t blk_addr, enum page_type type, int rw) > +{ > + enum page_type btype = PAGE_TYPE_OF_BIO(type); > + struct block_device *bdev = sbi->sb->s_bdev; > + struct f2fs_bio_info *io; > + int bio_blocks; > + > + io = is_read_io(rw) ? &sbi->read_io : &sbi->write_io[btype]; > + > + verify_block_addr(sbi, blk_addr); > + > + mutex_lock(&io->io_mutex); > + > + if (!is_read_io(rw)) > + inc_page_count(sbi, F2FS_WRITEBACK); > + > + if (io->bio && io->last_block_in_bio != blk_addr - 1) > + __submit_merged_bio(sbi, io, type, true, rw); > +alloc_new: > + if (io->bio == NULL) { > + bio_blocks = MAX_BIO_BLOCKS(max_hw_blocks(sbi)); > + io->bio = __bio_alloc(bdev, bio_blocks); > + io->bio->bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr); > + io->bio->bi_end_io = is_read_io(rw) ? f2fs_read_end_io : > + f2fs_write_end_io; > + /* > + * The end_io will be assigned at the sumbission phase. > + * Until then, let bio_add_page() merge consecutive IOs as much > + * as possible. > + */ > + } > + > + if (bio_add_page(io->bio, page, PAGE_CACHE_SIZE, 0) < > + PAGE_CACHE_SIZE) { > + __submit_merged_bio(sbi, io, type, true, rw); > + io->bio = NULL; We should remove the redundant code " io->bio = NULL;" here, because __submit_merged_bio does the same job. [snip] > /* > * data.c > */ > +void f2fs_submit_merged_bio(struct f2fs_sb_info *, enum page_type, bool, > int); > +int f2fs_submit_page_bio(struct f2fs_sb_info *, struct page *, block_t, int); Redundant to the following code. > +void f2fs_submit_page_mbio(struct f2fs_sb_info *, struct page *, block_t, > + enum page_type, int); > int reserve_new_block(struct dnode_of_data *); > int f2fs_reserve_block(struct dnode_of_data *, pgoff_t); > void update_extent_cache(block_t, struct dnode_of_data *); > struct page *find_data_page(struct inode *, pgoff_t, bool); > struct page *get_lock_data_page(struct inode *, pgoff_t); > struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool); > -int f2fs_readpage(struct f2fs_sb_info *, struct page *, block_t, int); > -void f2fs_submit_read_bio(struct f2fs_sb_info *, int); > -void submit_read_page(struct f2fs_sb_info *, struct page *, block_t, int); > +int f2fs_submit_page_bio(struct f2fs_sb_info *, struct page *, block_t, int); Here. [snip] -- Rapidly troubleshoot problems before they affect your business. Most IT organizations don't have a clear picture of how application performance affects their revenue. With AppDynamics, you get 100% visibility into your Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! http://pubads.g.doubleclick.net/gampad/clk?id=84349351&iu=/4140/ostg.clktrk ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH] f2fs: refactor bio-related operations
On 11/30/2013 02:25 PM, Jaegeuk Kim wrote: > This patch integrates redundant bio operations on read and write IOs. > > 1. Move bio-related codes to the top of data.c. > 2. Replace f2fs_submit_bio with f2fs_submit_merged_bio, which handles read >bios additionally. > 3. Introduce __submit_merged_bio to submit the merged bio. > 4. Change f2fs_readpage to f2fs_submit_page_bio. > 5. Introduce f2fs_submit_page_mbio to integrate previous submit_read_page and >submit_write_page. > > Signed-off-by: Jaegeuk Kim Reviewed-by: Gu Zheng > --- > fs/f2fs/checkpoint.c| 14 +- > fs/f2fs/data.c | 317 > +--- > fs/f2fs/f2fs.h | 13 +- > fs/f2fs/gc.c| 2 +- > fs/f2fs/node.c | 14 +- > fs/f2fs/recovery.c | 4 +- > fs/f2fs/segment.c | 164 +++ > include/trace/events/f2fs.h | 30 ++--- > 8 files changed, 259 insertions(+), 299 deletions(-) > > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c > index 40eea42..38f4a224 100644 > --- a/fs/f2fs/checkpoint.c > +++ b/fs/f2fs/checkpoint.c > @@ -61,7 +61,8 @@ repeat: > if (PageUptodate(page)) > goto out; > > - if (f2fs_readpage(sbi, page, index, READ_SYNC | REQ_META | REQ_PRIO)) > + if (f2fs_submit_page_bio(sbi, page, index, > + READ_SYNC | REQ_META | REQ_PRIO)) > goto repeat; > > lock_page(page); > @@ -157,7 +158,8 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum > page_type type, > } > > if (nwritten) > - f2fs_submit_bio(sbi, type, nr_to_write == LONG_MAX); > + f2fs_submit_merged_bio(sbi, type, nr_to_write == LONG_MAX, > + WRITE); > > return nwritten; > } > @@ -590,7 +592,7 @@ retry: >* We should submit bio, since it exists several >* wribacking dentry pages in the freeing inode. >*/ > - f2fs_submit_bio(sbi, DATA, true); > + f2fs_submit_merged_bio(sbi, DATA, true, WRITE); > } > goto retry; > } > @@ -796,9 +798,9 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool > is_umount) > > trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish block_ops"); > > - f2fs_submit_bio(sbi, DATA, true); > - f2fs_submit_bio(sbi, NODE, true); > - f2fs_submit_bio(sbi, META, true); > + f2fs_submit_merged_bio(sbi, DATA, true, WRITE); > + f2fs_submit_merged_bio(sbi, NODE, true, WRITE); > + f2fs_submit_merged_bio(sbi, META, true, WRITE); > > /* >* update checkpoint pack index > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c > index c9a76f8..53e3bbb 100644 > --- a/fs/f2fs/data.c > +++ b/fs/f2fs/data.c > @@ -25,6 +25,205 @@ > #include > > /* > + * Low-level block read/write IO operations. > + */ > +static struct bio *__bio_alloc(struct block_device *bdev, int npages) > +{ > + struct bio *bio; > + > + /* No failure on bio allocation */ > + bio = bio_alloc(GFP_NOIO, npages); > + bio->bi_bdev = bdev; > + bio->bi_private = NULL; > + return bio; > +} > + > +static void f2fs_read_end_io(struct bio *bio, int err) > +{ > + const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); > + struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; > + > + do { > + struct page *page = bvec->bv_page; > + > + if (--bvec >= bio->bi_io_vec) > + prefetchw(&bvec->bv_page->flags); > + > + if (uptodate) { > + SetPageUptodate(page); > + } else { > + ClearPageUptodate(page); > + SetPageError(page); > + } > + unlock_page(page); > + } while (bvec >= bio->bi_io_vec); > + > + bio_put(bio); > +} > + > +static void f2fs_write_end_io(struct bio *bio, int err) > +{ > + const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); > + struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; > + struct f2fs_sb_info *sbi = F2FS_SB(bvec->bv_page->mapping->host->i_sb); > + > + do { > + struct page *page = bvec->bv_page; > + > + if (--bvec >= bio->bi_io_vec) > + prefetchw(&bvec->bv_page->flags); > + > + if (!uptodate) { > + SetPageError(page); > + set_bit(AS_EIO, &page->mapping->flags); > + set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG); > + sbi->sb->s_flags |= MS_RDONLY; > + } > + end_page_writeback(page); > + dec_page_count(sbi, F2FS_WRITEBACK); > + } while (bvec >= bio->bi_io_vec); > + > + if (bio->bi_private) > + complete(bio->bi_private); > + > + if (!get_pages(sbi, F2FS_WRITEBACK) && > + !list_empty(&sbi->cp_wait.task_list))