From: liujinbao1 <[email protected]> Add the undiscard_blks_bysize node to classify undiscard_blks into three categories: [0,15], [15,511], and 512+, and count the number of blocks in each category as undiscard_small_blks, undiscard_middle_blks, and undiscard_large_blks, respectively, in order to better understand the size distribution of undiscard_blks. e.g. when the undiscard_blks value is 794, the undiscard_blks_bysize node shows the number of undiscard_blks in each range as: small: 424, middle: 370, large: 0.
Signed-off-by: Sheng Yong <[email protected]> Signed-off-by: liujinbao1 <[email protected]> --- Documentation/ABI/testing/sysfs-fs-f2fs | 8 ++++++ fs/f2fs/f2fs.h | 3 +++ fs/f2fs/segment.c | 34 +++++++++++++++++++++++++ fs/f2fs/sysfs.c | 13 ++++++++++ 4 files changed, 58 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 770470e0598b..23247030e27c 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -516,6 +516,14 @@ Date: December 2023 Contact: "Zhiguo Niu" <[email protected]> Description: Shows the total number of undiscard blocks. +What: /sys/fs/f2fs/<disk>/stat/undiscard_blks_bysize +Date: Feb 2026 +Contact: "Jinbao Liu" <[email protected]> +Description: Show undiscard block counts by size category. + Three block count ranges: small (0-15 blocks), + middle (16-511 blocks), large (512+ blocks). + Format: "small: %u, middle: %u, large: %u\n" + What: /sys/fs/f2fs/<disk>/ckpt_thread_ioprio Date: January 2021 Contact: "Daeho Jeong" <[email protected]> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a90a62cfe617..033666f2f368 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -501,6 +501,9 @@ struct discard_cmd_control { unsigned int max_ordered_discard; /* maximum discard granularity issued by lba order */ unsigned int discard_io_aware; /* io_aware policy */ unsigned int undiscard_blks; /* # of undiscard blocks */ + unsigned int undiscard_small_blks; /* # of undiscard blocks range in [0, 15] */ + unsigned int undiscard_middle_blks; /* # of undiscard blocks range in [16, 511]*/ + unsigned int undiscard_large_blks; /* # of undiscard blocks range > 511*/ unsigned int next_pos; /* next discard position */ atomic_t issued_discard; /* # of issued discard */ atomic_t queued_discard; /* # of queued discard */ diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index c26424f47686..c354a0f49802 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -962,6 +962,26 @@ static unsigned int get_free_segment(struct f2fs_sb_info *sbi) return NULL_SEGNO; } +static void __stat_undiscard_blks(struct discard_cmd_control *dcc, + block_t len, bool inc) +{ + if (inc) { + if (len < DEFAULT_DISCARD_GRANULARITY) + dcc->undiscard_small_blks += len; + else if (len < MAX_PLIST_NUM) + dcc->undiscard_middle_blks += len; + else + dcc->undiscard_large_blks += len; + } else { + if (len < DEFAULT_DISCARD_GRANULARITY) + dcc->undiscard_small_blks -= len; + else if (len < MAX_PLIST_NUM) + dcc->undiscard_middle_blks -= len; + else + dcc->undiscard_large_blks -= len; + } +} + static struct discard_cmd *__create_discard_cmd(struct f2fs_sb_info *sbi, struct block_device *bdev, block_t lstart, block_t start, block_t len) @@ -990,6 +1010,7 @@ static struct discard_cmd *__create_discard_cmd(struct f2fs_sb_info *sbi, dc->bio_ref = 0; atomic_inc(&dcc->discard_cmd_cnt); dcc->undiscard_blks += len; + __stat_undiscard_blks(dcc, len, true); return dc; } @@ -1108,6 +1129,7 @@ static void __detach_discard_cmd(struct discard_cmd_control *dcc, list_del(&dc->list); rb_erase_cached(&dc->rb_node, &dcc->root); dcc->undiscard_blks -= dc->di.len; + __stat_undiscard_blks(dcc, dc->di.len, false); kmem_cache_free(discard_cmd_slab, dc); @@ -1393,6 +1415,8 @@ static int __submit_discard_cmd(struct f2fs_sb_info *sbi, } if (!err && len) { + __stat_undiscard_blks(dcc, (dc->di.len + len), false); + __stat_undiscard_blks(dcc, dc->di.len, true); dcc->undiscard_blks -= len; __update_discard_tree_range(sbi, bdev, lstart, start, len); } @@ -1450,10 +1474,12 @@ static void __punch_discard_cmd(struct f2fs_sb_info *sbi, } dcc->undiscard_blks -= di.len; + __stat_undiscard_blks(dcc, di.len, false); if (blkaddr > di.lstart) { dc->di.len = blkaddr - dc->di.lstart; dcc->undiscard_blks += dc->di.len; + __stat_undiscard_blks(dcc, dc->di.len, true); __relocate_discard_cmd(dcc, dc); modified = true; } @@ -1468,6 +1494,7 @@ static void __punch_discard_cmd(struct f2fs_sb_info *sbi, dc->di.len--; dc->di.start++; dcc->undiscard_blks += dc->di.len; + __stat_undiscard_blks(dcc, dc->di.len, true); __relocate_discard_cmd(dcc, dc); } } @@ -1524,8 +1551,10 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi, prev_dc->bdev == bdev && __is_discard_back_mergeable(&di, &prev_dc->di, max_discard_blocks)) { + __stat_undiscard_blks(dcc, prev_dc->di.len, false); prev_dc->di.len += di.len; dcc->undiscard_blks += di.len; + __stat_undiscard_blks(dcc, prev_dc->di.len, true); __relocate_discard_cmd(dcc, prev_dc); di = prev_dc->di; tdc = prev_dc; @@ -1536,10 +1565,12 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi, next_dc->bdev == bdev && __is_discard_front_mergeable(&di, &next_dc->di, max_discard_blocks)) { + __stat_undiscard_blks(dcc, next_dc->di.len, false); next_dc->di.lstart = di.lstart; next_dc->di.len += di.len; next_dc->di.start = di.start; dcc->undiscard_blks += di.len; + __stat_undiscard_blks(dcc, next_dc->di.len, true); __relocate_discard_cmd(dcc, next_dc); if (tdc) __remove_discard_cmd(sbi, tdc); @@ -2349,6 +2380,9 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi) dcc->max_discard_issue_time = DEF_MAX_DISCARD_ISSUE_TIME; dcc->discard_urgent_util = DEF_DISCARD_URGENT_UTIL; dcc->undiscard_blks = 0; + dcc->undiscard_small_blks = 0; + dcc->undiscard_middle_blks = 0; + dcc->undiscard_large_blks = 0; dcc->next_pos = 0; dcc->root = RB_ROOT_CACHED; dcc->rbtree_check = false; diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index c42f4f979d13..9b11a490c8d0 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -176,6 +176,17 @@ static ssize_t undiscard_blks_show(struct f2fs_attr *a, SM_I(sbi)->dcc_info->undiscard_blks); } +static ssize_t undiscard_blks_bysize_show(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, char *buf) +{ + if (!SM_I(sbi)->dcc_info) + return -EINVAL; + return sysfs_emit(buf, "small: %u, middle: %u, large: %u\n", + SM_I(sbi)->dcc_info->undiscard_small_blks, + SM_I(sbi)->dcc_info->undiscard_middle_blks, + SM_I(sbi)->dcc_info->undiscard_large_blks); +} + static ssize_t atgc_enabled_show(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf) { @@ -1471,6 +1482,7 @@ F2FS_GENERAL_RO_ATTR(cp_status); F2FS_GENERAL_RO_ATTR(issued_discard); F2FS_GENERAL_RO_ATTR(queued_discard); F2FS_GENERAL_RO_ATTR(undiscard_blks); +F2FS_GENERAL_RO_ATTR(undiscard_blks_bysize); static struct attribute *f2fs_stat_attrs[] = { ATTR_LIST(sb_status), @@ -1478,6 +1490,7 @@ static struct attribute *f2fs_stat_attrs[] = { ATTR_LIST(issued_discard), ATTR_LIST(queued_discard), ATTR_LIST(undiscard_blks), + ATTR_LIST(undiscard_blks_bysize), NULL, }; ATTRIBUTE_GROUPS(f2fs_stat); -- 2.25.1 _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
