aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChao Yu <yuchao0@huawei.com>2016-08-26 12:14:31 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2016-09-07 20:27:34 -0400
commit7ea984b0604ac37e806ddc34baf950230bfdaadd (patch)
treef2043df1efd1082a0349e700dab44c43a6b24192
parent74fa5f3d43bca87257e9da7da95be8735ffa2b96 (diff)
f2fs: do in batch synchronously readahead during GC
In order to enhance performance, we try to readahead node page during GC, but before loading node page we should get block address of node page which is stored in NAT table, so synchronously read of single NAT page block our readahead flow. f2fs_submit_page_bio: dev = (251,0), ino = 2, page_index = 0xa1e, oldaddr = 0xa1e, newaddr = 0xa1e, rw = READ_SYNC(MP), type = META f2fs_submit_page_bio: dev = (251,0), ino = 1, page_index = 0x35e9, oldaddr = 0x72d7a, newaddr = 0x72d7a, rw = READAHEAD ^H, type = NODE f2fs_submit_page_bio: dev = (251,0), ino = 2, page_index = 0xc1f, oldaddr = 0xc1f, newaddr = 0xc1f, rw = READ_SYNC(MP), type = META f2fs_submit_page_bio: dev = (251,0), ino = 1, page_index = 0x389d, oldaddr = 0x72d7d, newaddr = 0x72d7d, rw = READAHEAD ^H, type = NODE f2fs_submit_page_bio: dev = (251,0), ino = 1, page_index = 0x3a82, oldaddr = 0x72d7f, newaddr = 0x72d7f, rw = READAHEAD ^H, type = NODE f2fs_submit_page_bio: dev = (251,0), ino = 1, page_index = 0x3bfa, oldaddr = 0x72d86, newaddr = 0x72d86, rw = READAHEAD ^H, type = NODE This patch adds one phase that do readahead NAT pages in batch before readahead node page for more effeciently. f2fs_submit_page_bio: dev = (251,0), ino = 2, page_index = 0x1952, oldaddr = 0x1952, newaddr = 0x1952, rw = READ_SYNC(MP), type = META f2fs_submit_page_mbio: dev = (251,0), ino = 2, page_index = 0xc34, oldaddr = 0xc34, newaddr = 0xc34, rw = READ_SYNC(MP), type = META f2fs_submit_page_mbio: dev = (251,0), ino = 2, page_index = 0xa33, oldaddr = 0xa33, newaddr = 0xa33, rw = READ_SYNC(MP), type = META f2fs_submit_page_mbio: dev = (251,0), ino = 2, page_index = 0xc30, oldaddr = 0xc30, newaddr = 0xc30, rw = READ_SYNC(MP), type = META f2fs_submit_page_mbio: dev = (251,0), ino = 2, page_index = 0xc32, oldaddr = 0xc32, newaddr = 0xc32, rw = READ_SYNC(MP), type = META f2fs_submit_page_mbio: dev = (251,0), ino = 2, page_index = 0xc26, oldaddr = 0xc26, newaddr = 0xc26, rw = READ_SYNC(MP), type = META f2fs_submit_page_mbio: dev = (251,0), ino = 2, page_index = 0xa2b, oldaddr = 0xa2b, newaddr = 0xa2b, rw = READ_SYNC(MP), type = META f2fs_submit_page_mbio: dev = (251,0), ino = 2, page_index = 0xc23, oldaddr = 0xc23, newaddr = 0xc23, rw = READ_SYNC(MP), type = META f2fs_submit_page_mbio: dev = (251,0), ino = 2, page_index = 0xc24, oldaddr = 0xc24, newaddr = 0xc24, rw = READ_SYNC(MP), type = META f2fs_submit_page_mbio: dev = (251,0), ino = 2, page_index = 0xa10, oldaddr = 0xa10, newaddr = 0xa10, rw = READ_SYNC(MP), type = META f2fs_submit_page_mbio: dev = (251,0), ino = 2, page_index = 0xc2c, oldaddr = 0xc2c, newaddr = 0xc2c, rw = READ_SYNC(MP), type = META f2fs_submit_page_bio: dev = (251,0), ino = 1, page_index = 0x5db7, oldaddr = 0x6be00, newaddr = 0x6be00, rw = READAHEAD ^H, type = NODE f2fs_submit_page_bio: dev = (251,0), ino = 1, page_index = 0x5db9, oldaddr = 0x6be17, newaddr = 0x6be17, rw = READAHEAD ^H, type = NODE f2fs_submit_page_bio: dev = (251,0), ino = 1, page_index = 0x5dbc, oldaddr = 0x6be1a, newaddr = 0x6be1a, rw = READAHEAD ^H, type = NODE f2fs_submit_page_bio: dev = (251,0), ino = 1, page_index = 0x5dc3, oldaddr = 0x6be20, newaddr = 0x6be20, rw = READAHEAD ^H, type = NODE f2fs_submit_page_bio: dev = (251,0), ino = 1, page_index = 0x5dc7, oldaddr = 0x6be24, newaddr = 0x6be24, rw = READAHEAD ^H, type = NODE f2fs_submit_page_bio: dev = (251,0), ino = 1, page_index = 0x5dc9, oldaddr = 0x6be25, newaddr = 0x6be25, rw = READAHEAD ^H, type = NODE Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fs/f2fs/gc.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index c1599b48859b..cdc44a67485f 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -423,10 +423,10 @@ static int check_valid_map(struct f2fs_sb_info *sbi,
423static void gc_node_segment(struct f2fs_sb_info *sbi, 423static void gc_node_segment(struct f2fs_sb_info *sbi,
424 struct f2fs_summary *sum, unsigned int segno, int gc_type) 424 struct f2fs_summary *sum, unsigned int segno, int gc_type)
425{ 425{
426 bool initial = true;
427 struct f2fs_summary *entry; 426 struct f2fs_summary *entry;
428 block_t start_addr; 427 block_t start_addr;
429 int off; 428 int off;
429 int phase = 0;
430 430
431 start_addr = START_BLOCK(sbi, segno); 431 start_addr = START_BLOCK(sbi, segno);
432 432
@@ -445,10 +445,18 @@ next_step:
445 if (check_valid_map(sbi, segno, off) == 0) 445 if (check_valid_map(sbi, segno, off) == 0)
446 continue; 446 continue;
447 447
448 if (initial) { 448 if (phase == 0) {
449 ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1,
450 META_NAT, true);
451 continue;
452 }
453
454 if (phase == 1) {
449 ra_node_page(sbi, nid); 455 ra_node_page(sbi, nid);
450 continue; 456 continue;
451 } 457 }
458
459 /* phase == 2 */
452 node_page = get_node_page(sbi, nid); 460 node_page = get_node_page(sbi, nid);
453 if (IS_ERR(node_page)) 461 if (IS_ERR(node_page))
454 continue; 462 continue;
@@ -469,10 +477,8 @@ next_step:
469 stat_inc_node_blk_count(sbi, 1, gc_type); 477 stat_inc_node_blk_count(sbi, 1, gc_type);
470 } 478 }
471 479
472 if (initial) { 480 if (++phase < 3)
473 initial = false;
474 goto next_step; 481 goto next_step;
475 }
476} 482}
477 483
478/* 484/*
@@ -706,6 +712,7 @@ next_step:
706 struct node_info dni; /* dnode info for the data */ 712 struct node_info dni; /* dnode info for the data */
707 unsigned int ofs_in_node, nofs; 713 unsigned int ofs_in_node, nofs;
708 block_t start_bidx; 714 block_t start_bidx;
715 nid_t nid = le32_to_cpu(entry->nid);
709 716
710 /* stop BG_GC if there is not enough free sections. */ 717 /* stop BG_GC if there is not enough free sections. */
711 if (gc_type == BG_GC && has_not_enough_free_secs(sbi, 0)) 718 if (gc_type == BG_GC && has_not_enough_free_secs(sbi, 0))
@@ -715,7 +722,13 @@ next_step:
715 continue; 722 continue;
716 723
717 if (phase == 0) { 724 if (phase == 0) {
718 ra_node_page(sbi, le32_to_cpu(entry->nid)); 725 ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1,
726 META_NAT, true);
727 continue;
728 }
729
730 if (phase == 1) {
731 ra_node_page(sbi, nid);
719 continue; 732 continue;
720 } 733 }
721 734
@@ -723,14 +736,14 @@ next_step:
723 if (!is_alive(sbi, entry, &dni, start_addr + off, &nofs)) 736 if (!is_alive(sbi, entry, &dni, start_addr + off, &nofs))
724 continue; 737 continue;
725 738
726 if (phase == 1) { 739 if (phase == 2) {
727 ra_node_page(sbi, dni.ino); 740 ra_node_page(sbi, dni.ino);
728 continue; 741 continue;
729 } 742 }
730 743
731 ofs_in_node = le16_to_cpu(entry->ofs_in_node); 744 ofs_in_node = le16_to_cpu(entry->ofs_in_node);
732 745
733 if (phase == 2) { 746 if (phase == 3) {
734 inode = f2fs_iget(sb, dni.ino); 747 inode = f2fs_iget(sb, dni.ino);
735 if (IS_ERR(inode) || is_bad_inode(inode)) 748 if (IS_ERR(inode) || is_bad_inode(inode))
736 continue; 749 continue;
@@ -756,7 +769,7 @@ next_step:
756 continue; 769 continue;
757 } 770 }
758 771
759 /* phase 3 */ 772 /* phase 4 */
760 inode = find_gc_inode(gc_list, dni.ino); 773 inode = find_gc_inode(gc_list, dni.ino);
761 if (inode) { 774 if (inode) {
762 struct f2fs_inode_info *fi = F2FS_I(inode); 775 struct f2fs_inode_info *fi = F2FS_I(inode);
@@ -789,7 +802,7 @@ next_step:
789 } 802 }
790 } 803 }
791 804
792 if (++phase < 4) 805 if (++phase < 5)
793 goto next_step; 806 goto next_step;
794} 807}
795 808