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=84349351iu=/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 jaegeuk@samsung.com Reviewed-by: Gu Zheng guz.f...@cn.fujitsu.com --- 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 trace/events/f2fs.h /* + * 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)) + wake_up(sbi-cp_wait); + + bio_put(bio); +} + +static void __submit_merged_bio(struct
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=84349351iu=/4140/ostg.clktrk ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH] f2fs: refactor bio-related operations
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 jaegeuk@samsung.com --- 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 trace/events/f2fs.h /* + * 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)) + wake_up(sbi-cp_wait); + + bio_put(bio); +} + +static void __submit_merged_bio(struct f2fs_sb_info *sbi, + struct f2fs_bio_info *io, +