OSDN Git Service

f2fs: allocate memory in batch in build_sit_info()
authorChao Yu <yuchao0@huawei.com>
Fri, 26 Jul 2019 07:41:20 +0000 (15:41 +0800)
committer0ranko0P <ranko0p@outlook.com>
Tue, 24 Dec 2019 20:42:25 +0000 (04:42 +0800)
build_sit_info() allocate all bitmaps for each segment one by one,
it's quite low efficiency, this pach changes to allocate large
continuous memory at a time, and divide it and assign for each bitmaps
of segment. For large size image, it can expect improving its mount
speed.

Signed-off-by: Chen Gong <gongchen4@huawei.com>
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/segment.c
fs/f2fs/segment.h

index 2b7795c..930dc0a 100644 (file)
@@ -4023,7 +4023,7 @@ static int build_sit_info(struct f2fs_sb_info *sbi)
        struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
        struct sit_info *sit_i;
        unsigned int sit_segs, start;
-       char *src_bitmap;
+       char *src_bitmap, *bitmap;
        unsigned int bitmap_size;
 
        /* allocate memory for SIT information */
@@ -4046,27 +4046,31 @@ static int build_sit_info(struct f2fs_sb_info *sbi)
        if (!sit_i->dirty_sentries_bitmap)
                return -ENOMEM;
 
+#ifdef CONFIG_F2FS_CHECK_FS
+       bitmap_size = MAIN_SEGS(sbi) * SIT_VBLOCK_MAP_SIZE * 4;
+#else
+       bitmap_size = MAIN_SEGS(sbi) * SIT_VBLOCK_MAP_SIZE * 3;
+#endif
+       sit_i->bitmap = f2fs_kvzalloc(sbi, bitmap_size, GFP_KERNEL);
+       if (!sit_i->bitmap)
+               return -ENOMEM;
+
+       bitmap = sit_i->bitmap;
+
        for (start = 0; start < MAIN_SEGS(sbi); start++) {
-               sit_i->sentries[start].cur_valid_map
-                       = f2fs_kzalloc(sbi, SIT_VBLOCK_MAP_SIZE, GFP_KERNEL);
-               sit_i->sentries[start].ckpt_valid_map
-                       = f2fs_kzalloc(sbi, SIT_VBLOCK_MAP_SIZE, GFP_KERNEL);
-               if (!sit_i->sentries[start].cur_valid_map ||
-                               !sit_i->sentries[start].ckpt_valid_map)
-                       return -ENOMEM;
+               sit_i->sentries[start].cur_valid_map = bitmap;
+               bitmap += SIT_VBLOCK_MAP_SIZE;
+
+               sit_i->sentries[start].ckpt_valid_map = bitmap;
+               bitmap += SIT_VBLOCK_MAP_SIZE;
 
 #ifdef CONFIG_F2FS_CHECK_FS
-               sit_i->sentries[start].cur_valid_map_mir
-                       = f2fs_kzalloc(sbi, SIT_VBLOCK_MAP_SIZE, GFP_KERNEL);
-               if (!sit_i->sentries[start].cur_valid_map_mir)
-                       return -ENOMEM;
+               sit_i->sentries[start].cur_valid_map_mir = bitmap;
+               bitmap += SIT_VBLOCK_MAP_SIZE;
 #endif
 
-               sit_i->sentries[start].discard_map
-                       = f2fs_kzalloc(sbi, SIT_VBLOCK_MAP_SIZE,
-                                                       GFP_KERNEL);
-               if (!sit_i->sentries[start].discard_map)
-                       return -ENOMEM;
+               sit_i->sentries[start].discard_map = bitmap;
+               bitmap += SIT_VBLOCK_MAP_SIZE;
        }
 
        sit_i->tmp_map = f2fs_kzalloc(sbi, SIT_VBLOCK_MAP_SIZE, GFP_KERNEL);
@@ -4572,21 +4576,12 @@ static void destroy_free_segmap(struct f2fs_sb_info *sbi)
 static void destroy_sit_info(struct f2fs_sb_info *sbi)
 {
        struct sit_info *sit_i = SIT_I(sbi);
-       unsigned int start;
 
        if (!sit_i)
                return;
 
-       if (sit_i->sentries) {
-               for (start = 0; start < MAIN_SEGS(sbi); start++) {
-                       kvfree(sit_i->sentries[start].cur_valid_map);
-#ifdef CONFIG_F2FS_CHECK_FS
-                       kvfree(sit_i->sentries[start].cur_valid_map_mir);
-#endif
-                       kvfree(sit_i->sentries[start].ckpt_valid_map);
-                       kvfree(sit_i->sentries[start].discard_map);
-               }
-       }
+       if (sit_i->sentries)
+               kvfree(sit_i->bitmap);
        kvfree(sit_i->tmp_map);
 
        kvfree(sit_i->sentries);
index b746028..ec4d568 100644 (file)
@@ -226,6 +226,7 @@ struct sit_info {
        block_t sit_base_addr;          /* start block address of SIT area */
        block_t sit_blocks;             /* # of blocks used by SIT area */
        block_t written_valid_blocks;   /* # of valid blocks in main area */
+       char *bitmap;                   /* all bitmaps pointer */
        char *sit_bitmap;               /* SIT bitmap pointer */
 #ifdef CONFIG_F2FS_CHECK_FS
        char *sit_bitmap_mir;           /* SIT bitmap mirror */