f2fs: clean up flush/discard command namings
Subsystems (3)
Jaegeuk Kim
maintainerPATCH 1/6 f2fs: clean up flush/discard command namings
This patch simply cleans up the names for flush/discard commands.
--- fs/f2fs/debug.c | 2 +- fs/f2fs/f2fs.h | 20 +++++------- fs/f2fs/segment.c | 98 +++++++++++++++++++++++++++---------------------------- 3 files changed, 59 insertions(+), 61 deletions(-)
fs/f2fs/debug.c +1 -1
@@ -194,7 +194,7 @@ static void update_mem_info(struct f2fs_sb_info *sbi) si->cache_mem +=sizeof (struct f2fs_gc_kthread );/* build merge flush thread */ -if (SM_I (sbi)->cmd_control_info) +if (SM_I (sbi)->fcc_info) si->cache_mem +=sizeof (struct flush_cmd_control );/* free nids */
fs/f2fs/f2fs.h +9 -11
@@ -181,13 +181,12 @@ struct discard_entry {int len;/* # of consecutive blocks of the discard */ }; -struct bio_entry { -struct list_head list; -block_t lstart; -block_t len; -struct bio *bio; -struct completion event; -int error; +struct discard_cmd { +struct list_head list;/* command list */ +struct completion wait;/* compleation */ +block_t lstart;/* logical start address */ +block_t len;/* length */ +struct bio *bio;/* bio */ };/* for the list of fsync inodes, used only during recovery */
@@ -634,8 +633,8 @@ struct f2fs_sm_info {unsigned int rec_prefree_segments;/* for small discard management */ -struct list_head discard_list;/* 4KB discard list */ -struct list_head wait_list;/* linked with issued discard bio */ +struct list_head discard_entry_list;/* 4KB discard entry list */ +struct list_head discard_cmd_list;/* discard cmd list */ int nr_discards;/* # of discards in the list */ int max_discards;/* max. discards to be issued */
@@ -649,8 +648,7 @@ struct f2fs_sm_info {unsigned int min_fsync_blocks;/* threshold for fsync */ /* for flush command control */ -struct flush_cmd_control *cmd_control_info; - +struct flush_cmd_control *fcc_info; };/*
fs/f2fs/segment.c +49 -49
235 lines not on this page · raw message
Signature · 1 line
2.11.0
Jaegeuk Kim
maintainerPATCH 2/6 f2fs: reorganize stat information
This patch modifies stat information more clearly.
--- fs/f2fs/debug.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/f2fs/debug.c +4 -4
@@ -258,8 +258,6 @@ static int stat_show(struct seq_file *s, void *v) si->inline_dir);seq_printf (s," - Orphan Inode: %u\n" , si->orphans); -seq_printf (s," - Atomic write count: %4d (Max. %4d)\n" , - si->aw_cnt, si->max_aw_cnt);seq_printf (s,"\nMain area: %d segs, %d secs %d zones\n" , si->main_area_segs, si->main_area_sections, si->main_area_zones);
@@ -318,8 +316,10 @@ static int stat_show(struct seq_file *s, void *v)seq_printf (s," - Inner Struct Count: tree: %d(%d), node: %d\n" , si->ext_tree, si->zombie_tree, si->ext_node);seq_puts (s,"\nBalancing F2FS Async:\n" ); -seq_printf (s," - inmem: %4d, wb_cp_data: %4d, wb_data: %4d\n" , - si->inmem_pages, si->nr_wb_cp_data, si->nr_wb_data); +seq_printf (s," - IO (CP: %4d, Data: %4d)\n" , + si->nr_wb_cp_data, si->nr_wb_data); +seq_printf (s," - inmem: %4d, atomic IO: %4d (Max. %4d)\n" , + si->inmem_pages, si->aw_cnt, si->max_aw_cnt);seq_printf (s," - nodes: %4d in %4d\n" , si->ndirty_node, si->node_pages); seq_printf(s, " - dents: %4d in dirs:%4d (%4d)\n",
Signature · 1 line
2.11.0
Re: [f2fs-dev] [PATCH 2/6] f2fs: reorganize stat information
Quoted 3 lines · Jaegeuk Kim
This patch modifies stat information more clearly.
Signed-off-by Jaegeuk Kim <[email protected]>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Jaegeuk Kim
maintainerPATCH 3/6 f2fs: remove batched discard in f2fs_trim_fs
In reply to Jaegeuk KimWe don't need to do multiple checkpoints, since we don't actually wait for completion of discard commands during checkpoint.
Instead, we still need to avoid very big discard commands, since that large discard can interfere block allocation.
--- Documentation/ABI/testing/sysfs-fs-f2fs | 6 ------ fs/f2fs/f2fs.h | 9 +------- fs/f2fs/segment.c | 38 +++++++++++---------------------- fs/f2fs/super.c | 2 -- 4 files changed, 14 insertions(+), 41 deletions(-)
Documentation/ABI/testing/sysfs-fs-f2fs +0 -6
@@ -75,12 +75,6 @@ Contact: "Jaegeuk Kim" <[email protected]> Description: Controls the memory footprint used by f2fs. -What: /sys/fs/f2fs/<disk>/trim_sections -Date: February 2015 -Contact: "Jaegeuk Kim" <[email protected]> -Description: - Controls the trimming rate in batch mode. - What: /sys/fs/f2fs/<disk>/cp_interval Date: October 2015 Contact: "Jaegeuk Kim" <[email protected]>
fs/f2fs/f2fs.h +1 -8
@@ -128,11 +128,7 @@ enum { CP_DISCARD, }; -#define DEF_BATCHED_TRIM_SECTIONS 2 -#define BATCHED_TRIM_SEGMENTS (sbi) \ - (SM_I(sbi)->trim_sections * (sbi)->segs_per_sec) -#define BATCHED_TRIM_BLOCKS (sbi) \ - (BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg) +#define MAX_DISCARD_BLOCKS (sbi) (1 << (sbi)->log_blocks_per_seg)#define DEF_CP_INTERVAL 60/* 60 secs */ #define DEF_IDLE_INTERVAL 5/* 5 secs */
@@ -638,9 +634,6 @@ struct f2fs_sm_info {int nr_discards;/* # of discards in the list */ int max_discards;/* max. discards to be issued */ -/* for batched trimming */ -unsigned int trim_sections;/* # of sections to trim */ -struct list_head sit_entry_set;/* sit entry set list */ unsigned int ipu_policy;/* in-place-update policy */
fs/f2fs/segment.c +13 -25
@@ -823,7 +823,8 @@ static void __add_discard_entry(struct f2fs_sb_info *sbi,if (!list_empty (head)) { last = list_last_entry(head, struct discard_entry, list);if (START_BLOCK (sbi, cpc->trim_start) + start == - last->blkaddr + last->len) { + last->blkaddr + last->len && + last->len <=MAX_DISCARD_BLOCKS (sbi)) { last->len += end - start; goto done; }
@@ -1513,36 +1514,25 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) "Found FS corruption, run fsck to fix."); goto out; } +if (sbi->discard_blks ==0 ) + goto out;/* start/end segment number in main_area */ start_segno = (start <=MAIN_BLKADDR (sbi)) ?0 :GET_SEGNO (sbi, start); end_segno = (end >=MAX_BLKADDR (sbi)) ?MAIN_SEGS (sbi) -1 :GET_SEGNO (sbi, end); +/* +* do checkpoint to issue discard commands safely since we now can +* use async discard. +*/ cpc.reason =CP_DISCARD ; cpc.trim_minlen =max_t (__u64,1 ,F2FS_BYTES_TO_BLK (range->minlen)); + cpc.trim_start = start_segno; + cpc.trim_end = end_segno; -/* do checkpoint to issue discard commands safely */ -for (; start_segno <= end_segno; start_segno = cpc.trim_end +1 ) { - cpc.trim_start = start_segno; - -if (sbi->discard_blks ==0 ) -break ; -else if (sbi->discard_blks <BATCHED_TRIM_BLOCKS (sbi)) - cpc.trim_end = end_segno; -else - cpc.trim_end = min_t(unsigned int, -rounddown (start_segno + -BATCHED_TRIM_SEGMENTS (sbi), - sbi->segs_per_sec) -1 , end_segno); - -mutex_lock (&sbi->gc_mutex); - err =write_checkpoint (sbi, &cpc); -mutex_unlock (&sbi->gc_mutex); -if (err) -break ; - -schedule (); - } +mutex_lock (&sbi->gc_mutex); + err =write_checkpoint (sbi, &cpc); +mutex_unlock (&sbi->gc_mutex); out: range->len =F2FS_BLK_TO_BYTES (cpc.trimmed);return err;
@@ -2708,8 +2698,6 @@ int build_segment_manager(struct f2fs_sb_info *sbi) sm_info->nr_discards =0 ; sm_info->max_discards =0 ; - sm_info->trim_sections =DEF_BATCHED_TRIM_SECTIONS ; -INIT_LIST_HEAD (&sm_info->sit_entry_set);if (test_opt (sbi,FLUSH_MERGE ) && !f2fs_readonly (sbi->sb)) {
fs/f2fs/super.c +0 -2
@@ -284,7 +284,6 @@ F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_idle, gc_idle);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, reclaim_segments, rec_prefree_segments);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, max_small_discards, max_discards); -F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, batched_trim_sections, trim_sections);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, ipu_policy, ipu_policy);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, min_ipu_util, min_ipu_util);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);
@@ -309,7 +308,6 @@ static struct attribute *f2fs_attrs[] = {ATTR_LIST (gc_idle),ATTR_LIST (reclaim_segments),ATTR_LIST (max_small_discards), -ATTR_LIST (batched_trim_sections),ATTR_LIST (ipu_policy),ATTR_LIST (min_ipu_util), ATTR_LIST(min_fsync_blocks),
Signature · 9 lines
2.11.0 ------------------------------------------------------------------------------ Developer Access Program for Intel Xeon Phi Processors Access to Intel Xeon Phi processor-based developer platforms. With one year of Intel Parallel Studio XE. Training and support from Colfax. Order your platform today. http://sdm.link/xeonphi
Re: [PATCH 3/6] f2fs: remove batched discard in f2fs_trim_fs
Quoted 4 lines · Jaegeuk Kim
We don't need to do multiple checkpoints, since we don't actually wait for completion of discard commands during checkpoint.
Instead, we still need to avoid very big discard commands, since that large discard can interfere block allocation.
I hope we can keep this functionality and related sysfs interface, the main concern is that: for 16T size fragmented partition, at most there will be ~sizeof(u32)/2 4K blocks which could be invalid and needed to be discarded. After removal of in-batch discard, we have to handle billions of discard message with gc_mutex & cp_rwsem held, which will freeze f2fs for very long time.
So I suggest we just set trim_sections to 512 segments (covers one GB) by default. How do you think?
Thanks,
Quoted 138 lines
Signed-off-by Jaegeuk Kim <[email protected]>--- Documentation/ABI/testing/sysfs-fs-f2fs | 6 ------ fs/f2fs/f2fs.h | 9 +------- fs/f2fs/segment.c | 38 +++++++++++---------------------- fs/f2fs/super.c | 2 -- 4 files changed, 14 insertions(+), 41 deletions(-)Documentation/ABI/testing/sysfs-fs-f2fs +0
-6@@ -75,12 +75,6 @@ Contact: "Jaegeuk Kim" <[email protected]> Description: Controls the memory footprint used by f2fs. -What: /sys/fs/f2fs/<disk>/trim_sections -Date: February 2015 -Contact: "Jaegeuk Kim" <[email protected]> -Description: - Controls the trimming rate in batch mode. - What: /sys/fs/f2fs/<disk>/cp_interval Date: October 2015 Contact: "Jaegeuk Kim" <[email protected]>fs/f2fs/f2fs.h +1
-8@@ -128,11 +128,7 @@ enum { CP_DISCARD, }; -#define DEF_BATCHED_TRIM_SECTIONS 2 -#define BATCHED_TRIM_SEGMENTS (sbi) \ - (SM_I(sbi)->trim_sections * (sbi)->segs_per_sec) -#define BATCHED_TRIM_BLOCKS (sbi) \ - (BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg) +#define MAX_DISCARD_BLOCKS (sbi) (1 << (sbi)->log_blocks_per_seg)#define DEF_CP_INTERVAL 60/* 60 secs */ #define DEF_IDLE_INTERVAL 5/* 5 secs */ @@ -638,9 +634,6 @@ struct f2fs_sm_info {int nr_discards;/* # of discards in the list */ int max_discards;/* max. discards to be issued */ -/* for batched trimming */ -unsigned int trim_sections;/* # of sections to trim */ -struct list_head sit_entry_set;/* sit entry set list */ unsigned int ipu_policy;/* in-place-update policy */ fs/f2fs/segment.c +13
-25@@ -823,7 +823,8 @@ static void __add_discard_entry(struct f2fs_sb_info *sbi,if (!list_empty (head)) { last = list_last_entry(head, struct discard_entry, list);if (START_BLOCK (sbi, cpc->trim_start) + start == - last->blkaddr + last->len) { + last->blkaddr + last->len && + last->len <=MAX_DISCARD_BLOCKS (sbi)) { last->len += end - start; goto done; }@@ -1513,36 +1514,25 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) "Found FS corruption, run fsck to fix."); goto out; } +if (sbi->discard_blks ==0 ) + goto out;/* start/end segment number in main_area */ start_segno = (start <=MAIN_BLKADDR (sbi)) ?0 :GET_SEGNO (sbi, start); end_segno = (end >=MAX_BLKADDR (sbi)) ?MAIN_SEGS (sbi) -1 :GET_SEGNO (sbi, end); +/* +* do checkpoint to issue discard commands safely since we now can +* use async discard. +*/ cpc.reason =CP_DISCARD ; cpc.trim_minlen =max_t (__u64,1 ,F2FS_BYTES_TO_BLK (range->minlen)); + cpc.trim_start = start_segno; + cpc.trim_end = end_segno; -/* do checkpoint to issue discard commands safely */ -for (; start_segno <= end_segno; start_segno = cpc.trim_end +1 ) { - cpc.trim_start = start_segno; - -if (sbi->discard_blks ==0 ) -break ; -else if (sbi->discard_blks <BATCHED_TRIM_BLOCKS (sbi)) - cpc.trim_end = end_segno; -else - cpc.trim_end = min_t(unsigned int, -rounddown (start_segno + -BATCHED_TRIM_SEGMENTS (sbi), - sbi->segs_per_sec) -1 , end_segno); - -mutex_lock (&sbi->gc_mutex); - err =write_checkpoint (sbi, &cpc); -mutex_unlock (&sbi->gc_mutex); -if (err) -break ; - -schedule (); - } +mutex_lock (&sbi->gc_mutex); + err =write_checkpoint (sbi, &cpc); +mutex_unlock (&sbi->gc_mutex); out: range->len =F2FS_BLK_TO_BYTES (cpc.trimmed);return err;@@ -2708,8 +2698,6 @@ int build_segment_manager(struct f2fs_sb_info *sbi) sm_info->nr_discards =0 ; sm_info->max_discards =0 ; - sm_info->trim_sections =DEF_BATCHED_TRIM_SECTIONS ; -INIT_LIST_HEAD (&sm_info->sit_entry_set);if (test_opt (sbi,FLUSH_MERGE ) && !f2fs_readonly (sbi->sb)) {fs/f2fs/super.c +0
-1@@ -284,7 +284,6 @@ F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_idle, gc_idle);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, reclaim_segments, rec_prefree_segments);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, max_small_discards, max_discards); -F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, batched_trim_sections, trim_sections);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, ipu_policy, ipu_policy);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, min_ipu_util, min_ipu_util);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);
fs/f2fs/super.c static struct attribute *f2fs_attrs[] = { · line 313
Quoted 7 lines
fs/f2fs/super.c +0
-1@@ -309,7 +308,6 @@ static struct attribute *f2fs_attrs[] = {ATTR_LIST (gc_idle),ATTR_LIST (reclaim_segments),ATTR_LIST (max_small_discards), -ATTR_LIST (batched_trim_sections),ATTR_LIST (ipu_policy),ATTR_LIST (min_ipu_util), ATTR_LIST(min_fsync_blocks),
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Jaegeuk Kim
maintainerRe: [f2fs-dev] [PATCH 3/6] f2fs: remove batched discard in f2fs_trim_fs
Quoted 11 lines · Chao Yu
Quoted 4 lines · Jaegeuk Kim
We don't need to do multiple checkpoints, since we don't actually wait for completion of discard commands during checkpoint.
Instead, we still need to avoid very big discard commands, since that large discard can interfere block allocation.I hope we can keep this functionality and related sysfs interface, the main concern is that: for 16T size fragmented partition, at most there will be ~sizeof(u32)/2 4K blocks which could be invalid and needed to be discarded. After removal of in-batch discard, we have to handle billions of discard message with
gc_mutex&cp_rwsemheld, which will freeze f2fs for very long time.
The baseline of this patch is that we have a kernel thread to issue discard commands asynchronously. So, I don't expect such the huge latency anymore.
Thanks,
Quoted 160 lines
So I suggest we just set
trim_sectionsto 512 segments (covers one GB) by default. How do you think?Thanks,
Quoted 138 lines
Signed-off-by Jaegeuk Kim <[email protected]>--- Documentation/ABI/testing/sysfs-fs-f2fs | 6 ------ fs/f2fs/f2fs.h | 9 +------- fs/f2fs/segment.c | 38 +++++++++++---------------------- fs/f2fs/super.c | 2 -- 4 files changed, 14 insertions(+), 41 deletions(-)Documentation/ABI/testing/sysfs-fs-f2fs +0
-6@@ -75,12 +75,6 @@ Contact: "Jaegeuk Kim" <[email protected]> Description: Controls the memory footprint used by f2fs. -What: /sys/fs/f2fs/<disk>/trim_sections -Date: February 2015 -Contact: "Jaegeuk Kim" <[email protected]> -Description: - Controls the trimming rate in batch mode. - What: /sys/fs/f2fs/<disk>/cp_interval Date: October 2015 Contact: "Jaegeuk Kim" <[email protected]>fs/f2fs/f2fs.h +1
-8@@ -128,11 +128,7 @@ enum { CP_DISCARD, }; -#define DEF_BATCHED_TRIM_SECTIONS 2 -#define BATCHED_TRIM_SEGMENTS (sbi) \ - (SM_I(sbi)->trim_sections * (sbi)->segs_per_sec) -#define BATCHED_TRIM_BLOCKS (sbi) \ - (BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg) +#define MAX_DISCARD_BLOCKS (sbi) (1 << (sbi)->log_blocks_per_seg)#define DEF_CP_INTERVAL 60/* 60 secs */ #define DEF_IDLE_INTERVAL 5/* 5 secs */ @@ -638,9 +634,6 @@ struct f2fs_sm_info {int nr_discards;/* # of discards in the list */ int max_discards;/* max. discards to be issued */ -/* for batched trimming */ -unsigned int trim_sections;/* # of sections to trim */ -struct list_head sit_entry_set;/* sit entry set list */ unsigned int ipu_policy;/* in-place-update policy */ fs/f2fs/segment.c +13
-25@@ -823,7 +823,8 @@ static void __add_discard_entry(struct f2fs_sb_info *sbi,if (!list_empty (head)) { last = list_last_entry(head, struct discard_entry, list);if (START_BLOCK (sbi, cpc->trim_start) + start == - last->blkaddr + last->len) { + last->blkaddr + last->len && + last->len <=MAX_DISCARD_BLOCKS (sbi)) { last->len += end - start; goto done; }@@ -1513,36 +1514,25 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) "Found FS corruption, run fsck to fix."); goto out; } +if (sbi->discard_blks ==0 ) + goto out;/* start/end segment number in main_area */ start_segno = (start <=MAIN_BLKADDR (sbi)) ?0 :GET_SEGNO (sbi, start); end_segno = (end >=MAX_BLKADDR (sbi)) ?MAIN_SEGS (sbi) -1 :GET_SEGNO (sbi, end); +/* +* do checkpoint to issue discard commands safely since we now can +* use async discard. +*/ cpc.reason =CP_DISCARD ; cpc.trim_minlen =max_t (__u64,1 ,F2FS_BYTES_TO_BLK (range->minlen)); + cpc.trim_start = start_segno; + cpc.trim_end = end_segno; -/* do checkpoint to issue discard commands safely */ -for (; start_segno <= end_segno; start_segno = cpc.trim_end +1 ) { - cpc.trim_start = start_segno; - -if (sbi->discard_blks ==0 ) -break ; -else if (sbi->discard_blks <BATCHED_TRIM_BLOCKS (sbi)) - cpc.trim_end = end_segno; -else - cpc.trim_end = min_t(unsigned int, -rounddown (start_segno + -BATCHED_TRIM_SEGMENTS (sbi), - sbi->segs_per_sec) -1 , end_segno); - -mutex_lock (&sbi->gc_mutex); - err =write_checkpoint (sbi, &cpc); -mutex_unlock (&sbi->gc_mutex); -if (err) -break ; - -schedule (); - } +mutex_lock (&sbi->gc_mutex); + err =write_checkpoint (sbi, &cpc); +mutex_unlock (&sbi->gc_mutex); out: range->len =F2FS_BLK_TO_BYTES (cpc.trimmed);return err;@@ -2708,8 +2698,6 @@ int build_segment_manager(struct f2fs_sb_info *sbi) sm_info->nr_discards =0 ; sm_info->max_discards =0 ; - sm_info->trim_sections =DEF_BATCHED_TRIM_SECTIONS ; -INIT_LIST_HEAD (&sm_info->sit_entry_set);if (test_opt (sbi,FLUSH_MERGE ) && !f2fs_readonly (sbi->sb)) {fs/f2fs/super.c +0
-1@@ -284,7 +284,6 @@ F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_idle, gc_idle);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, reclaim_segments, rec_prefree_segments);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, max_small_discards, max_discards); -F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, batched_trim_sections, trim_sections);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, ipu_policy, ipu_policy);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, min_ipu_util, min_ipu_util);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);fs/f2fs/super.c static struct attribute *f2fs_attrs[] = { · line 313
Quoted 7 lines
fs/f2fs/super.c +0
-1@@ -309,7 +308,6 @@ static struct attribute *f2fs_attrs[] = {ATTR_LIST (gc_idle),ATTR_LIST (reclaim_segments),ATTR_LIST (max_small_discards), -ATTR_LIST (batched_trim_sections),ATTR_LIST (ipu_policy),ATTR_LIST (min_ipu_util), ATTR_LIST(min_fsync_blocks),------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Linux-f2fs-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 3/6] f2fs: remove batched discard in f2fs_trim_fs
Quoted 7 lines · Jaegeuk Kim
Quoted 6 lines · Chao Yu
Quoted 4 lines · Jaegeuk Kim
We don't need to do multiple checkpoints, since we don't actually wait for completion of discard commands during checkpoint.
Instead, we still need to avoid very big discard commands, since that large discard can interfere block allocation.
Quoted 8 lines
Quoted 5 lines
I hope we can keep this functionality and related sysfs interface, the main concern is that: for 16T size fragmented partition, at most there will be ~sizeof(u32)/2 4K blocks which could be invalid and needed to be discarded. After removal of in-batch discard, we have to handle billions of discard message with
gc_mutex&cp_rwsemheld, which will freeze f2fs for very long time.The baseline of this patch is that we have a kernel thread to issue discard commands asynchronously. So, I don't expect such the huge latency anymore.
Yes, I know async kernel thread was already introduced, and we can expect such implementation can help to reduce huge handling latency. But still in checkpoint we need to check region of invalid block and send the pending discard entries to kernel thread, so what I concern is that in scenario of there is huge number of discard messages, we will still face long latency with cp lock held.
Thanks,
Quoted 164 lines
Thanks,
Quoted 153 lines
So I suggest we just set
trim_sectionsto 512 segments (covers one GB) by default. How do you think?Thanks,
Quoted 138 lines
Signed-off-by Jaegeuk Kim <[email protected]>--- Documentation/ABI/testing/sysfs-fs-f2fs | 6 ------ fs/f2fs/f2fs.h | 9 +------- fs/f2fs/segment.c | 38 +++++++++++---------------------- fs/f2fs/super.c | 2 -- 4 files changed, 14 insertions(+), 41 deletions(-)Documentation/ABI/testing/sysfs-fs-f2fs +0
-6@@ -75,12 +75,6 @@ Contact: "Jaegeuk Kim" <[email protected]> Description: Controls the memory footprint used by f2fs. -What: /sys/fs/f2fs/<disk>/trim_sections -Date: February 2015 -Contact: "Jaegeuk Kim" <[email protected]> -Description: - Controls the trimming rate in batch mode. - What: /sys/fs/f2fs/<disk>/cp_interval Date: October 2015 Contact: "Jaegeuk Kim" <[email protected]>fs/f2fs/f2fs.h +1
-8@@ -128,11 +128,7 @@ enum { CP_DISCARD, }; -#define DEF_BATCHED_TRIM_SECTIONS 2 -#define BATCHED_TRIM_SEGMENTS (sbi) \ - (SM_I(sbi)->trim_sections * (sbi)->segs_per_sec) -#define BATCHED_TRIM_BLOCKS (sbi) \ - (BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg) +#define MAX_DISCARD_BLOCKS (sbi) (1 << (sbi)->log_blocks_per_seg)#define DEF_CP_INTERVAL 60/* 60 secs */ #define DEF_IDLE_INTERVAL 5/* 5 secs */ @@ -638,9 +634,6 @@ struct f2fs_sm_info {int nr_discards;/* # of discards in the list */ int max_discards;/* max. discards to be issued */ -/* for batched trimming */ -unsigned int trim_sections;/* # of sections to trim */ -struct list_head sit_entry_set;/* sit entry set list */ unsigned int ipu_policy;/* in-place-update policy */ fs/f2fs/segment.c +13
-25@@ -823,7 +823,8 @@ static void __add_discard_entry(struct f2fs_sb_info *sbi,if (!list_empty (head)) { last = list_last_entry(head, struct discard_entry, list);if (START_BLOCK (sbi, cpc->trim_start) + start == - last->blkaddr + last->len) { + last->blkaddr + last->len && + last->len <=MAX_DISCARD_BLOCKS (sbi)) { last->len += end - start; goto done; }@@ -1513,36 +1514,25 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) "Found FS corruption, run fsck to fix."); goto out; } +if (sbi->discard_blks ==0 ) + goto out;/* start/end segment number in main_area */ start_segno = (start <=MAIN_BLKADDR (sbi)) ?0 :GET_SEGNO (sbi, start); end_segno = (end >=MAX_BLKADDR (sbi)) ?MAIN_SEGS (sbi) -1 :GET_SEGNO (sbi, end); +/* +* do checkpoint to issue discard commands safely since we now can +* use async discard. +*/ cpc.reason =CP_DISCARD ; cpc.trim_minlen =max_t (__u64,1 ,F2FS_BYTES_TO_BLK (range->minlen)); + cpc.trim_start = start_segno; + cpc.trim_end = end_segno; -/* do checkpoint to issue discard commands safely */ -for (; start_segno <= end_segno; start_segno = cpc.trim_end +1 ) { - cpc.trim_start = start_segno; - -if (sbi->discard_blks ==0 ) -break ; -else if (sbi->discard_blks <BATCHED_TRIM_BLOCKS (sbi)) - cpc.trim_end = end_segno; -else - cpc.trim_end = min_t(unsigned int, -rounddown (start_segno + -BATCHED_TRIM_SEGMENTS (sbi), - sbi->segs_per_sec) -1 , end_segno); - -mutex_lock (&sbi->gc_mutex); - err =write_checkpoint (sbi, &cpc); -mutex_unlock (&sbi->gc_mutex); -if (err) -break ; - -schedule (); - } +mutex_lock (&sbi->gc_mutex); + err =write_checkpoint (sbi, &cpc); +mutex_unlock (&sbi->gc_mutex); out: range->len =F2FS_BLK_TO_BYTES (cpc.trimmed);return err;@@ -2708,8 +2698,6 @@ int build_segment_manager(struct f2fs_sb_info *sbi) sm_info->nr_discards =0 ; sm_info->max_discards =0 ; - sm_info->trim_sections =DEF_BATCHED_TRIM_SECTIONS ; -INIT_LIST_HEAD (&sm_info->sit_entry_set);if (test_opt (sbi,FLUSH_MERGE ) && !f2fs_readonly (sbi->sb)) {fs/f2fs/super.c +0
-1@@ -284,7 +284,6 @@ F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_idle, gc_idle);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, reclaim_segments, rec_prefree_segments);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, max_small_discards, max_discards); -F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, batched_trim_sections, trim_sections);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, ipu_policy, ipu_policy);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, min_ipu_util, min_ipu_util);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);fs/f2fs/super.c static struct attribute *f2fs_attrs[] = { · line 313
Quoted 7 lines
fs/f2fs/super.c +0
-1@@ -309,7 +308,6 @@ static struct attribute *f2fs_attrs[] = {ATTR_LIST (gc_idle),ATTR_LIST (reclaim_segments),ATTR_LIST (max_small_discards), -ATTR_LIST (batched_trim_sections),ATTR_LIST (ipu_policy),ATTR_LIST (min_ipu_util), ATTR_LIST(min_fsync_blocks),Quoted 7 lines
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Linux-f2fs-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Quoted 2 lines
.
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Jaegeuk Kim
maintainerRe: [f2fs-dev] [PATCH 3/6] f2fs: remove batched discard in f2fs_trim_fs
Quoted 14 lines · Chao Yu
Quoted 13 lines · Jaegeuk Kim
Quoted 11 lines · Chao Yu
Quoted 4 lines · Jaegeuk Kim
We don't need to do multiple checkpoints, since we don't actually wait for completion of discard commands during checkpoint.
Instead, we still need to avoid very big discard commands, since that large discard can interfere block allocation.I hope we can keep this functionality and related sysfs interface, the main concern is that: for 16T size fragmented partition, at most there will be ~sizeof(u32)/2 4K blocks which could be invalid and needed to be discarded. After removal of in-batch discard, we have to handle billions of discard message with
gc_mutex&cp_rwsemheld, which will freeze f2fs for very long time.
Quoted 8 lines
Quoted 2 lines
The baseline of this patch is that we have a kernel thread to issue discard commands asynchronously. So, I don't expect such the huge latency anymore.
Yes, I know async kernel thread was already introduced, and we can expect such implementation can help to reduce huge handling latency. But still in checkpoint we need to check region of invalid block and send the pending discard entries to kernel thread, so what I concern is that in scenario of there is huge number of discard messages, we will still face long latency with cp lock held.
Okay, I removed the below patch now, and changed 4GB range by default. ;)
Thanks,
Quoted 171 lines
Thanks,
Quoted 164 lines
Thanks,
Quoted 153 lines
So I suggest we just set
trim_sectionsto 512 segments (covers one GB) by default. How do you think?Thanks,
Quoted 138 lines
Signed-off-by Jaegeuk Kim <[email protected]>--- Documentation/ABI/testing/sysfs-fs-f2fs | 6 ------ fs/f2fs/f2fs.h | 9 +------- fs/f2fs/segment.c | 38 +++++++++++---------------------- fs/f2fs/super.c | 2 -- 4 files changed, 14 insertions(+), 41 deletions(-)Documentation/ABI/testing/sysfs-fs-f2fs +0
-6@@ -75,12 +75,6 @@ Contact: "Jaegeuk Kim" <[email protected]> Description: Controls the memory footprint used by f2fs. -What: /sys/fs/f2fs/<disk>/trim_sections -Date: February 2015 -Contact: "Jaegeuk Kim" <[email protected]> -Description: - Controls the trimming rate in batch mode. - What: /sys/fs/f2fs/<disk>/cp_interval Date: October 2015 Contact: "Jaegeuk Kim" <[email protected]>fs/f2fs/f2fs.h +1
-8@@ -128,11 +128,7 @@ enum { CP_DISCARD, }; -#define DEF_BATCHED_TRIM_SECTIONS 2 -#define BATCHED_TRIM_SEGMENTS (sbi) \ - (SM_I(sbi)->trim_sections * (sbi)->segs_per_sec) -#define BATCHED_TRIM_BLOCKS (sbi) \ - (BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg) +#define MAX_DISCARD_BLOCKS (sbi) (1 << (sbi)->log_blocks_per_seg)#define DEF_CP_INTERVAL 60/* 60 secs */ #define DEF_IDLE_INTERVAL 5/* 5 secs */ @@ -638,9 +634,6 @@ struct f2fs_sm_info {int nr_discards;/* # of discards in the list */ int max_discards;/* max. discards to be issued */ -/* for batched trimming */ -unsigned int trim_sections;/* # of sections to trim */ -struct list_head sit_entry_set;/* sit entry set list */ unsigned int ipu_policy;/* in-place-update policy */ fs/f2fs/segment.c +13
-25@@ -823,7 +823,8 @@ static void __add_discard_entry(struct f2fs_sb_info *sbi,if (!list_empty (head)) { last = list_last_entry(head, struct discard_entry, list);if (START_BLOCK (sbi, cpc->trim_start) + start == - last->blkaddr + last->len) { + last->blkaddr + last->len && + last->len <=MAX_DISCARD_BLOCKS (sbi)) { last->len += end - start; goto done; }@@ -1513,36 +1514,25 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) "Found FS corruption, run fsck to fix."); goto out; } +if (sbi->discard_blks ==0 ) + goto out;/* start/end segment number in main_area */ start_segno = (start <=MAIN_BLKADDR (sbi)) ?0 :GET_SEGNO (sbi, start); end_segno = (end >=MAX_BLKADDR (sbi)) ?MAIN_SEGS (sbi) -1 :GET_SEGNO (sbi, end); +/* +* do checkpoint to issue discard commands safely since we now can +* use async discard. +*/ cpc.reason =CP_DISCARD ; cpc.trim_minlen =max_t (__u64,1 ,F2FS_BYTES_TO_BLK (range->minlen)); + cpc.trim_start = start_segno; + cpc.trim_end = end_segno; -/* do checkpoint to issue discard commands safely */ -for (; start_segno <= end_segno; start_segno = cpc.trim_end +1 ) { - cpc.trim_start = start_segno; - -if (sbi->discard_blks ==0 ) -break ; -else if (sbi->discard_blks <BATCHED_TRIM_BLOCKS (sbi)) - cpc.trim_end = end_segno; -else - cpc.trim_end = min_t(unsigned int, -rounddown (start_segno + -BATCHED_TRIM_SEGMENTS (sbi), - sbi->segs_per_sec) -1 , end_segno); - -mutex_lock (&sbi->gc_mutex); - err =write_checkpoint (sbi, &cpc); -mutex_unlock (&sbi->gc_mutex); -if (err) -break ; - -schedule (); - } +mutex_lock (&sbi->gc_mutex); + err =write_checkpoint (sbi, &cpc); +mutex_unlock (&sbi->gc_mutex); out: range->len =F2FS_BLK_TO_BYTES (cpc.trimmed);return err;@@ -2708,8 +2698,6 @@ int build_segment_manager(struct f2fs_sb_info *sbi) sm_info->nr_discards =0 ; sm_info->max_discards =0 ; - sm_info->trim_sections =DEF_BATCHED_TRIM_SECTIONS ; -INIT_LIST_HEAD (&sm_info->sit_entry_set);if (test_opt (sbi,FLUSH_MERGE ) && !f2fs_readonly (sbi->sb)) {fs/f2fs/super.c +0
-1@@ -284,7 +284,6 @@ F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_idle, gc_idle);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, reclaim_segments, rec_prefree_segments);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, max_small_discards, max_discards); -F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, batched_trim_sections, trim_sections);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, ipu_policy, ipu_policy);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, min_ipu_util, min_ipu_util);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);fs/f2fs/super.c static struct attribute *f2fs_attrs[] = { · line 313
Quoted 7 lines
fs/f2fs/super.c +0
-1@@ -309,7 +308,6 @@ static struct attribute *f2fs_attrs[] = {ATTR_LIST (gc_idle),ATTR_LIST (reclaim_segments),ATTR_LIST (max_small_discards), -ATTR_LIST (batched_trim_sections),ATTR_LIST (ipu_policy),ATTR_LIST (min_ipu_util), ATTR_LIST(min_fsync_blocks),Quoted 7 lines
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Linux-f2fs-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-develQuoted 2 lines
.
Quoted 7 lines
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Linux-f2fs-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Jaegeuk Kim
maintainerPATCH 4/6 f2fs: factor out discard command info into discard_cmd_control
In reply to Jaegeuk KimThis patch adds discard_cmd_control with the existing discarding controls.
--- fs/f2fs/debug.c | 2 ++ fs/f2fs/f2fs.h | 16 ++++++++----- fs/f2fs/segment.c | 68 +++++++++++++++++++++++++++++++++++++++++++------------ fs/f2fs/super.c | 5 +++- 4 files changed, 69 insertions(+), 22 deletions(-)
fs/f2fs/debug.c +2 -0
@@ -196,6 +196,8 @@ static void update_mem_info(struct f2fs_sb_info *sbi)/* build merge flush thread */ if (SM_I (sbi)->fcc_info) si->cache_mem +=sizeof (struct flush_cmd_control ); +if (SM_I (sbi)->dcc_info) + si->cache_mem +=sizeof (struct discard_cmd_control );/* free nids */ si->cache_mem += (NM_I(sbi)->nid_cnt[FREE_NID_LIST] +
fs/f2fs/f2fs.h +10 -6
@@ -185,6 +185,13 @@ struct discard_cmd {struct bio *bio;/* bio */ }; +struct discard_cmd_control { +struct list_head discard_entry_list;/* 4KB discard entry list */ +int nr_discards;/* # of discards in the list */ +struct list_head discard_cmd_list;/* discard cmd list */ +int max_discards;/* max. discards to be issued */ +}; +/* for the list of fsync inodes, used only during recovery */ struct fsync_inode_entry {struct list_head list;/* list head */
@@ -628,12 +635,6 @@ struct f2fs_sm_info {/* a threshold to reclaim prefree segments */ unsigned int rec_prefree_segments; -/* for small discard management */ -struct list_head discard_entry_list;/* 4KB discard entry list */ -struct list_head discard_cmd_list;/* discard cmd list */ -int nr_discards;/* # of discards in the list */ -int max_discards;/* max. discards to be issued */ -struct list_head sit_entry_set;/* sit entry set list */ unsigned int ipu_policy;/* in-place-update policy */
@@ -642,6 +643,9 @@ struct f2fs_sm_info {/* for flush command control */ struct flush_cmd_control *fcc_info; + +/* for discard command control */ +struct discard_cmd_control *dcc_info; };/*
fs/f2fs/segment.c +53 -15
152 lines not on this page · raw message
fs/f2fs/super.c +4 -1
@@ -145,6 +145,7 @@ static match_table_t f2fs_tokens = {enum {GC_THREAD ,/* struct f2fs_gc_thread */ SM_INFO ,/* struct f2fs_sm_info */ +DCC_INFO ,/* struct discard_cmd_control */ NM_INFO ,/* struct f2fs_nm_info */ F2FS_SBI ,/* struct f2fs_sb_info */ #ifdef CONFIG_F2FS_FAULT_INJECTION
@@ -168,6 +169,8 @@ static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type)return (unsigned char *)sbi->gc_thread; else if (struct_type == SM_INFO) return (unsigned char *)SM_I(sbi); + else if (struct_type == DCC_INFO) + return (unsigned char *)SM_I(sbi)->dcc_info; else if (struct_type == NM_INFO) return (unsigned char *)NM_I(sbi); else if (struct_type == F2FS_SBI)
@@ -283,7 +286,7 @@ F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_idle, gc_idle);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, reclaim_segments, rec_prefree_segments); -F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, max_small_discards, max_discards); +F2FS_RW_ATTR (DCC_INFO , discard_cmd_control, max_small_discards, max_discards);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, ipu_policy, ipu_policy);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, min_ipu_util, min_ipu_util);F2FS_RW_ATTR (SM_INFO , f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);
Signature · 1 line
2.11.0
Re: [PATCH 4/6] f2fs: factor out discard command info into discard_cmd_control
Quoted 3 lines · Jaegeuk Kim
This patch adds
discard_cmd_controlwith the existing discarding controls.Signed-off-by Jaegeuk Kim <[email protected]>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Jaegeuk Kim
maintainerPATCH 5/6 f2fs: add a kernel thread to issue discard commands asynchronously
In reply to Jaegeuk KimThis patch adds a kernel thread to issue discard commands.
It proposes three states, D_PREP, D_SUBMIT, and D_DONE to identify current bio status.
--- fs/f2fs/f2fs.h | 11 +++++ fs/f2fs/segment.c | 128 +++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 108 insertions(+), 31 deletions(-)
fs/f2fs/f2fs.h +11 -0
@@ -129,6 +129,7 @@ enum { };#define MAX_DISCARD_BLOCKS (sbi) (1 << (sbi)->log_blocks_per_seg) +#define DISCARD_ISSUE_RATE 8#define DEF_CP_INTERVAL 60/* 60 secs */ #define DEF_IDLE_INTERVAL 5/* 5 secs */
@@ -177,18 +178,28 @@ struct discard_entry {int len;/* # of consecutive blocks of the discard */ }; +enum { +D_PREP , +D_SUBMIT , +D_DONE , +}; +struct discard_cmd {struct list_head list;/* command list */ struct completion wait;/* compleation */ block_t lstart;/* logical start address */ block_t len;/* length */ struct bio *bio;/* bio */ +int state;/* state */ };struct discard_cmd_control { +struct task_struct *f2fs_issue_discard;/* discard thread */ struct list_head discard_entry_list;/* 4KB discard entry list */ int nr_discards;/* # of discards in the list */ struct list_head discard_cmd_list;/* discard cmd list */ +wait_queue_head_t discard_wait_queue;/* waiting queue for wake-up */ +struct mutex cmd_lock;int max_discards;/* max. discards to be issued */ };
fs/f2fs/segment.c +97 -31
211 lines not on this page · raw message
Signature · 1 line
2.11.0
Re: [PATCH 5/6] f2fs: add a kernel thread to issue discard commands asynchronously
Quoted 3 lines · Jaegeuk Kim
This patch adds a kernel thread to issue discard commands.
It proposes three states,D_PREP,D_SUBMIT, andD_DONEto identify current bio status.
Why? Instead of creating the complexity of a thread you should look into issuing the discard bios asynchronously, which should help to simplify a lot of the discard logic in f2fs.
Jaegeuk Kim
maintainerRe: [PATCH 5/6] f2fs: add a kernel thread to issue discard commands asynchronously
Quoted 8 lines · Christoph Hellwig
Quoted 3 lines · Jaegeuk Kim
This patch adds a kernel thread to issue discard commands.
It proposes three states,D_PREP,D_SUBMIT, andD_DONEto identify current bio status.Why? Instead of creating the complexity of a thread you should look into issuing the discard bios asynchronously, which should help to simplify a lot of the discard logic in f2fs.
Previously, I've done to issue discard bios asynchronously. But the problem that I've got is that was not enough. When testing nvme SSD with noop IO scheduler, submit_bio() was blocked at every 8 async discard bios, resulting in very slow checkpoint process which blocks most of other FS operations.
Thanks,
Re: [PATCH 5/6] f2fs: add a kernel thread to issue discard commands asynchronously
Quoted 4 lines · Jaegeuk Kim
Previously, I've done to issue discard bios asynchronously. But the problem that I've got is that was not enough. When testing nvme SSD with noop IO scheduler,
submit_bio()was blocked at every 8 async discard bios, resulting in very slow checkpoint process which blocks most of other FS operations.
Where does it block? Are you running out of request? What driver is this on top of?
Re: [PATCH 5/6] f2fs: add a kernel thread to issue discard commands asynchronously
Quoted 8 lines · Christoph Hellwig
Quoted 4 lines · Jaegeuk Kim
Previously, I've done to issue discard bios asynchronously. But the problem that I've got is that was not enough. When testing nvme SSD with noop IO scheduler,
submit_bio()was blocked at every 8 async discard bios, resulting in very slow checkpoint process which blocks most of other FS operations.Where does it block? Are you running out of request? What driver is this on top of?
Ping? I'm currently spending a lot of effort on fs and block dіscard code, and I'd like to make sure we get common infrastructure instead of local hacks.
Jaegeuk Kim
maintainerRe: [PATCH 5/6] f2fs: add a kernel thread to issue discard commands asynchronously
Quoted 7 lines · Christoph Hellwig
Quoted 6 lines · Christoph Hellwig
Quoted 4 lines · Jaegeuk Kim
Previously, I've done to issue discard bios asynchronously. But the problem that I've got is that was not enough. When testing nvme SSD with noop IO scheduler,
submit_bio()was blocked at every 8 async discard bios, resulting in very slow checkpoint process which blocks most of other FS operations.
Quoted 6 lines
Quoted 2 lines
Where does it block? Are you running out of request? What driver is this on top of?
Ping? I'm currently spending a lot of effort on fs and block dіscard code, and I'd like to make sure we get common infrastructure instead of local hacks.
Sorry for the late response due to the travel.
When doing fstrim with a fresh f2fs image fomatted on Intel NVMe SSD whose model name is SSDPE2MW012T4, I've got the following trace.
...
fstrim-12620 [000] .... 334572.907534: f2fs_issue_discard: dev = (259,1), blkstart = 0x902900, blklen = 0x400 fstrim-12620 [000] .... 334572.907535: block_bio_remap: 259,0 D 75583488 + 8192 <- (259,1) 75581440 fstrim-12620 [000] .... 334572.907535: block_bio_queue: 259,0 D 75583488 + 8192 [fstrim] fstrim-12620 [000] .... 334572.907535: block_getrq: 259,0 D 75583488 + 8192 [fstrim] fstrim-12620 [000] .... 334572.907536: block_unplug: [fstrim] 1
fstrim-12620 [000] .... 334572.907536: block_rq_insert: 259,0 D 0 () 75583488 + 8192 [fstrim] fstrim-12620 [000] .... 334572.907536: block_rq_issue: 259,0 D 0 () 75583488 + 8192 [fstrim]
< repeat 6 times >
fstrim-12620 [000] .... 334572.907620: f2fs_issue_discard: dev = (259,1), blkstart = 0x904500, blklen = 0x400 fstrim-12620 [000] .... 334572.907620: block_bio_remap: 259,0 D 75640832 + 8192 <- (259,1) 75638784 fstrim-12620 [000] .... 334572.907620: block_bio_queue: 259,0 D 75640832 + 8192 [fstrim] fstrim-12620 [000] .... 334572.907621: block_getrq: 259,0 D 75640832 + 8192 [fstrim]
<idle>-0 [000] d.h. 334572.907723: block_rq_complete: 259,0 D () 67260416 + 8192 [0] <idle>-0 [000] d.h. 334572.907942: block_rq_complete: 259,0 D () 67268608 + 8192 [0] <idle>-0 [000] d.h. 334572.908155: block_rq_complete: 259,0 D () 67276800 + 8192 [0] <idle>-0 [000] d.h. 334572.908374: block_rq_complete: 259,0 D () 67284992 + 8192 [0] <idle>-0 [000] d.h. 334572.908597: block_rq_complete: 259,0 D () 67293184 + 8192 [0] <idle>-0 [000] d.h. 334572.908823: block_rq_complete: 259,0 D () 67301376 + 8192 [0] <idle>-0 [000] d.h. 334572.909033: block_rq_complete: 259,0 D () 67309568 + 8192 [0] <idle>-0 [000] d.h. 334572.909216: block_rq_complete: 259,0 D () 67317760 + 8192 [0]
fstrim-12620 [000] .... 334572.909222: block_unplug: [fstrim] 1
fstrim-12620 [000] .... 334572.909223: block_rq_insert: 259,0 D 0 () 75640832 + 8192 [fstrim] fstrim-12620 [000] .... 334572.909224: block_rq_issue: 259,0 D 0 () 75640832 + 8192 [fstrim] fstrim-12620 [000] .... 334572.909240: f2fs_issue_discard: dev = (259,1), blkstart = 0x904900, blklen = 0x400 fstrim-12620 [000] .... 334572.909241: block_bio_remap: 259,0 D 75649024 + 8192 <- (259,1) 75646976 fstrim-12620 [000] .... 334572.909241: block_bio_queue: 259,0 D 75649024 + 8192 [fstrim] fstrim-12620 [000] .... 334572.909241: block_getrq: 259,0 D 75649024 + 8192 [fstrim] fstrim-12620 [000] .... 334572.909242: block_unplug: [fstrim] 1
fstrim-12620 [000] .... 334572.909242: block_rq_insert: 259,0 D 0 () 75649024 + 8192 [fstrim] fstrim-12620 [000] .... 334572.909242: block_rq_issue: 259,0 D 0 () 75649024 + 8192 [fstrim]
< repeat >
So, I investigated why block_rq_complete() happened in more detail.
The root-caused call path looks like:
- submit_bio
- generic_make_request
- q->make_request_fn
- blk_mq_make_request
- blk_mq_map_request
- blk_mq_alloc_request
- blk_mq_get_tag
- __blk_mq_get_tag
- bt_get
- blk_mq_run_hw_queue
- finish_wait
--> this waits for pending 8 discard bios!
It seems the problem comes from the storage processing discard commands too slowly comparing to normal read/write IOs.
Any thoughts?
Thanks,
Re: [PATCH 5/6] f2fs: add a kernel thread to issue discard commands asynchronously
Quoted 4 lines · Jaegeuk Kim
Sorry for the late response due to the travel.
When doing fstrim with a fresh f2fs image fomatted on Intel NVMe SSD whose model name is SSDPE2MW012T4, I've got the following trace.
<snip>
Quoted 15 lines
So, I investigated why
block_rq_complete()happened in more detail.The root-caused call path looks like:
-submit_bio
-generic_make_request
-q->make_request_fn
-blk_mq_make_request
-blk_mq_map_request
-blk_mq_alloc_request
-blk_mq_get_tag
-__blk_mq_get_tag
-bt_get
-blk_mq_run_hw_queue
-finish_wait
--> this waits for pending 8 discard bios!
You're blocking on tag allocation. How many tags per queue does your device have?, e.g. do a
cat /sys/block/nvme0n1/mq/0/nr_tags
Quoted 4 lines
It seems the problem comes from the storage processing discard commands too slowly comparing to normal read/write IOs.
Any thoughts?
Deallocate is always going to be an exception path compared to normal read/write? but just how much slower is going to be device dependent.
One option would be to reuse the number of discards, for that can you try the series here to support vectored discards:
http://git.infradead.org/users/hch/block.git/shortlog/refs/heads/vectored-discard-for-axboe
Jaegeuk Kim
maintainerRe: [PATCH 5/6] f2fs: add a kernel thread to issue discard commands asynchronously
Quoted 24 lines · Christoph Hellwig
Quoted 4 lines · Jaegeuk Kim
Sorry for the late response due to the travel.
When doing fstrim with a fresh f2fs image fomatted on Intel NVMe SSD whose model name is SSDPE2MW012T4, I've got the following trace.
<snip>
Quoted 15 lines
So, I investigated why
block_rq_complete()happened in more detail.The root-caused call path looks like:
-submit_bio
-generic_make_request
-q->make_request_fn
-blk_mq_make_request
-blk_mq_map_request
-blk_mq_alloc_request
-blk_mq_get_tag
-__blk_mq_get_tag
-bt_get
-blk_mq_run_hw_queue
-finish_wait
--> this waits for pending 8 discard bios!
Quoted 4 lines
You're blocking on tag allocation. How many tags per queue does your device have?, e.g. do a
cat
/sys/block/nvme0n1/mq/0/nr_tags
It shows 1023.
Quoted 5 lines
Quoted 4 lines
It seems the problem comes from the storage processing discard commands too slowly comparing to normal read/write IOs.
Any thoughts?
Quoted 8 lines
Deallocate is always going to be an exception path compared to normal read/write… but just how much slower is going to be device dependent.
One option would be to reuse the number of discards, for that can you try the series here to support vectored discards:
http://git.infradead.org/users/hch/block.git/shortlog/refs/heads/vectored-discard-for-axboe
I tried this, but couldn't see any difference.
Thanks,
Re: [PATCH 5/6] f2fs: add a kernel thread to issue discard commands asynchronously
In reply to Jaegeuk KimQuoted 5 lines · Jaegeuk Kim
This patch adds a kernel thread to issue discard commands.
It proposes three states,D_PREP,D_SUBMIT, andD_DONEto identify current bio status.Signed-off-by Jaegeuk Kim <[email protected]>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Jaegeuk Kim
maintainerPATCH 6/6 f2fs: show # of on-going flush and discard bios
In reply to Jaegeuk KimThis patch adds stat information for flush and discard commands.
--- fs/f2fs/debug.c | 7 +++++-- fs/f2fs/f2fs.h | 3 ++- fs/f2fs/segment.c | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-)
fs/f2fs/debug.c +5 -2
@@ -54,6 +54,8 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->max_aw_cnt =atomic_read (&sbi->max_aw_cnt); si->nr_wb_cp_data =get_pages (sbi,F2FS_WB_CP_DATA ); si->nr_wb_data =get_pages (sbi,F2FS_WB_DATA ); + si->nr_flush =atomic_read (&SM_I (sbi)->fcc_info->submit_flush); + si->nr_discard =atomic_read (&SM_I (sbi)->dcc_info->submit_discard); si->total_count = (int )sbi->user_block_count / sbi->blocks_per_seg; si->rsvd_segs =reserved_segments (sbi); si->overp_segs =overprovision_segments (sbi);
@@ -318,8 +320,9 @@ static int stat_show(struct seq_file *s, void *v)seq_printf (s," - Inner Struct Count: tree: %d(%d), node: %d\n" , si->ext_tree, si->zombie_tree, si->ext_node);seq_puts (s,"\nBalancing F2FS Async:\n" ); -seq_printf (s," - IO (CP: %4d, Data: %4d)\n" , - si->nr_wb_cp_data, si->nr_wb_data); +seq_printf (s," - IO (CP: %4d, Data: %4d, Flush: %4d, Discard: %4d)\n" , + si->nr_wb_cp_data, si->nr_wb_data, + si->nr_flush, si->nr_discard);seq_printf (s," - inmem: %4d, atomic IO: %4d (Max. %4d)\n" , si->inmem_pages, si->aw_cnt, si->max_aw_cnt); seq_printf(s, " - nodes: %4d in %4d\n",
fs/f2fs/f2fs.h +2 -1
@@ -201,6 +201,7 @@ struct discard_cmd_control {wait_queue_head_t discard_wait_queue;/* waiting queue for wake-up */ struct mutex cmd_lock;int max_discards;/* max. discards to be issued */ +atomic_t submit_discard;/* # of issued discard */ };/* for the list of fsync inodes, used only during recovery */
@@ -2254,7 +2255,7 @@ struct f2fs_stat_info {unsigned int ndirty_dirs, ndirty_files, ndirty_all;int nats, dirty_nats, sits, dirty_sits, free_nids, alloc_nids;int total_count, utilization; -int bg_gc, nr_wb_cp_data, nr_wb_data; +int bg_gc, nr_wb_cp_data, nr_wb_data, nr_flush, nr_discard;int inline_xattr, inline_inode, inline_dir, orphans;int aw_cnt, max_aw_cnt;unsigned int valid_count, valid_node_count, valid_inode_count, discard_blks;
fs/f2fs/segment.c +4 -0
@@ -653,6 +653,8 @@ static void __remove_discard_cmd(struct f2fs_sb_info *sbi, struct discard_cmd *d {int err = dc->bio->bi_error; +atomic_dec (&(SM_I (sbi)->dcc_info->submit_discard)); +if (err == -EOPNOTSUPP ) err =0 ;
@@ -678,6 +680,7 @@ void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr)if (dc->state ==D_PREP ) { dc->state =D_SUBMIT ;submit_bio (dc->bio); +atomic_inc (&dcc->submit_discard); }wait_for_completion_io (&dc->wait);
@@ -723,6 +726,7 @@ static int issue_discard_thread(void *data)if (dc->state ==D_PREP ) { dc->state =D_SUBMIT ;submit_bio (dc->bio); +atomic_inc (&dcc->submit_discard);if (iter++ >DISCARD_ISSUE_RATE )break ; }else if (dc->state ==D_DONE ) {
Signature · 1 line
2.11.0
Re: [f2fs-dev] [PATCH 6/6] f2fs: show # of on-going flush and discard bios
Hi Jaegeuk Kim,
Quoted 39 lines · Jaegeuk Kim
This patch adds stat information for flush and discard commands.
Signed-off-by Jaegeuk Kim <[email protected]>--- fs/f2fs/debug.c | 7 +++++-- fs/f2fs/f2fs.h | 3 ++- fs/f2fs/segment.c | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-)fs/f2fs/debug.c +5
-2@@ -54,6 +54,8 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->max_aw_cnt =atomic_read (&sbi->max_aw_cnt); si->nr_wb_cp_data =get_pages (sbi,F2FS_WB_CP_DATA ); si->nr_wb_data =get_pages (sbi,F2FS_WB_DATA ); + si->nr_flush =atomic_read (&SM_I (sbi)->fcc_info->submit_flush); + si->nr_discard =atomic_read (&SM_I (sbi)->dcc_info->submit_discard); si->total_count = (int )sbi->user_block_count / sbi->blocks_per_seg; si->rsvd_segs =reserved_segments (sbi); si->overp_segs =overprovision_segments (sbi);@@ -318,8 +320,9 @@ static int stat_show(struct seq_file *s, void *v)seq_printf (s," - Inner Struct Count: tree: %d(%d), node: %d\n" , si->ext_tree, si->zombie_tree, si->ext_node);seq_puts (s,"\nBalancing F2FS Async:\n" ); -seq_printf (s," - IO (CP: %4d, Data: %4d)\n" , - si->nr_wb_cp_data, si->nr_wb_data); +seq_printf (s," - IO (CP: %4d, Data: %4d, Flush: %4d, Discard: %4d)\n" , + si->nr_wb_cp_data, si->nr_wb_data, + si->nr_flush, si->nr_discard);seq_printf (s," - inmem: %4d, atomic IO: %4d (Max. %4d)\n" , si->inmem_pages, si->aw_cnt, si->max_aw_cnt); seq_printf(s, " - nodes: %4d in %4d\n",fs/f2fs/f2fs.h +0
-0
fs/f2fs/f2fs.h struct discard_cmd_control { · line 205
Quoted 5 lines
fs/f2fs/f2fs.h +1
-0@@ -201,6 +201,7 @@ struct discard_cmd_control {wait_queue_head_t discard_wait_queue;/* waiting queue for wake-up */ struct mutex cmd_lock;int max_discards;/* max. discards to be issued */ +atomic_t submit_discard;/* # of issued discard */ };
Here, we need to initialize submit_discard.
Thanks.
Quoted 34 lines
fs/f2fs/f2fs.h +1
-1/* for the list of fsync inodes, used only during recovery */ @@ -2254,7 +2255,7 @@ struct f2fs_stat_info {unsigned int ndirty_dirs, ndirty_files, ndirty_all;int nats, dirty_nats, sits, dirty_sits, free_nids, alloc_nids;int total_count, utilization; -int bg_gc, nr_wb_cp_data, nr_wb_data; +int bg_gc, nr_wb_cp_data, nr_wb_data, nr_flush, nr_discard;int inline_xattr, inline_inode, inline_dir, orphans;int aw_cnt, max_aw_cnt;unsigned int valid_count, valid_node_count, valid_inode_count, discard_blks;fs/f2fs/segment.c +3
-0@@ -653,6 +653,8 @@ static void __remove_discard_cmd(struct f2fs_sb_info *sbi, struct discard_cmd *d {int err = dc->bio->bi_error; +atomic_dec (&(SM_I (sbi)->dcc_info->submit_discard)); +if (err == -EOPNOTSUPP ) err =0 ;@@ -678,6 +680,7 @@ void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr)if (dc->state ==D_PREP ) { dc->state =D_SUBMIT ;submit_bio (dc->bio); +atomic_inc (&dcc->submit_discard); }wait_for_completion_io (&dc->wait);
fs/f2fs/segment.c static int issue_discard_thread(void *data) · line 732
Quoted 7 lines
fs/f2fs/segment.c +1
-0@@ -723,6 +726,7 @@ static int issue_discard_thread(void *data)if (dc->state ==D_PREP ) { dc->state =D_SUBMIT ;submit_bio (dc->bio); +atomic_inc (&dcc->submit_discard);if (iter++ >DISCARD_ISSUE_RATE )break ; }else if (dc->state ==D_DONE ) {
------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors Access to Intel Xeon Phi processor-based developer platforms. With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi
Re: [f2fs-dev] [PATCH 6/6] f2fs: show # of on-going flush and discard bios
In reply to Jaegeuk KimHi Jaegeuk,
Quoted 60 lines · Jaegeuk Kim
This patch adds stat information for flush and discard commands.
Signed-off-by Jaegeuk Kim <[email protected]>--- fs/f2fs/debug.c | 7 +++++-- fs/f2fs/f2fs.h | 3 ++- fs/f2fs/segment.c | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-)fs/f2fs/debug.c +5
-2@@ -54,6 +54,8 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->max_aw_cnt =atomic_read (&sbi->max_aw_cnt); si->nr_wb_cp_data =get_pages (sbi,F2FS_WB_CP_DATA ); si->nr_wb_data =get_pages (sbi,F2FS_WB_DATA ); + si->nr_flush =atomic_read (&SM_I (sbi)->fcc_info->submit_flush); + si->nr_discard =atomic_read (&SM_I (sbi)->dcc_info->submit_discard); si->total_count = (int )sbi->user_block_count / sbi->blocks_per_seg; si->rsvd_segs =reserved_segments (sbi); si->overp_segs =overprovision_segments (sbi);@@ -318,8 +320,9 @@ static int stat_show(struct seq_file *s, void *v)seq_printf (s," - Inner Struct Count: tree: %d(%d), node: %d\n" , si->ext_tree, si->zombie_tree, si->ext_node);seq_puts (s,"\nBalancing F2FS Async:\n" ); -seq_printf (s," - IO (CP: %4d, Data: %4d)\n" , - si->nr_wb_cp_data, si->nr_wb_data); +seq_printf (s," - IO (CP: %4d, Data: %4d, Flush: %4d, Discard: %4d)\n" , + si->nr_wb_cp_data, si->nr_wb_data, + si->nr_flush, si->nr_discard);seq_printf (s," - inmem: %4d, atomic IO: %4d (Max. %4d)\n" , si->inmem_pages, si->aw_cnt, si->max_aw_cnt); seq_printf(s, " - nodes: %4d in %4d\n",fs/f2fs/f2fs.h +2
-1@@ -201,6 +201,7 @@ struct discard_cmd_control {wait_queue_head_t discard_wait_queue;/* waiting queue for wake-up */ struct mutex cmd_lock;int max_discards;/* max. discards to be issued */ +atomic_t submit_discard;/* # of issued discard */ };/* for the list of fsync inodes, used only during recovery */ @@ -2254,7 +2255,7 @@ struct f2fs_stat_info {unsigned int ndirty_dirs, ndirty_files, ndirty_all;int nats, dirty_nats, sits, dirty_sits, free_nids, alloc_nids;int total_count, utilization; -int bg_gc, nr_wb_cp_data, nr_wb_data; +int bg_gc, nr_wb_cp_data, nr_wb_data, nr_flush, nr_discard;int inline_xattr, inline_inode, inline_dir, orphans;int aw_cnt, max_aw_cnt;unsigned int valid_count, valid_node_count, valid_inode_count, discard_blks;fs/f2fs/segment.c +0
-0
fs/f2fs/segment.c static void __remove_discard_cmd(struct f2fs_sb_info *sbi, struct discard_cmd *d · line 656
Quoted 4 lines
fs/f2fs/segment.c +1
-0@@ -653,6 +653,8 @@ static void __remove_discard_cmd(struct f2fs_sb_info *sbi, struct discard_cmd *d {int err = dc->bio->bi_error; +atomic_dec (&(SM_I (sbi)->dcc_info->submit_discard));
Here submit_discard decrease will include discard command without bio submit.
Thanks.
Quoted 21 lines
fs/f2fs/segment.c +3
-0+if (err == -EOPNOTSUPP ) err =0 ;@@ -678,6 +680,7 @@ void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr)if (dc->state ==D_PREP ) { dc->state =D_SUBMIT ;submit_bio (dc->bio); +atomic_inc (&dcc->submit_discard); }wait_for_completion_io (&dc->wait);@@ -723,6 +726,7 @@ static int issue_discard_thread(void *data)if (dc->state ==D_PREP ) { dc->state =D_SUBMIT ;submit_bio (dc->bio); +atomic_inc (&dcc->submit_discard);if (iter++ >DISCARD_ISSUE_RATE )break ; }else if (dc->state ==D_DONE ) {
Jaegeuk Kim
maintainerRe: [PATCH 6/6 v2] f2fs: show # of on-going flush and discard bios
In reply to Jaegeuk KimChange log from v1:
- Fix missing path pointed by Yunlei
Quoted 1 line
From
5d86527e4c70aeb8482dac24059624da720a0807Mon Sep 17 00:00:00 2001
From: Jaegeuk Kim <[email protected]>
Date: Wed, 11 Jan 2017 10:20:04 -0800
Subject: [PATCH] f2fs: show # of on-going flush and discard bios
This patch adds stat information for flush and discard commands.
--- fs/f2fs/debug.c | 11 +++++++++-- fs/f2fs/f2fs.h | 3 ++- fs/f2fs/segment.c | 6 ++++++ 3 files changed, 17 insertions(+), 3 deletions(-)
fs/f2fs/debug.c +9 -2
@@ -54,6 +54,12 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->max_aw_cnt =atomic_read (&sbi->max_aw_cnt); si->nr_wb_cp_data =get_pages (sbi,F2FS_WB_CP_DATA ); si->nr_wb_data =get_pages (sbi,F2FS_WB_DATA ); +if (SM_I (sbi) &&SM_I (sbi)->fcc_info) + si->nr_flush = +atomic_read (&SM_I (sbi)->fcc_info->submit_flush); +if (SM_I (sbi) &&SM_I (sbi)->dcc_info) + si->nr_discard = +atomic_read (&SM_I (sbi)->dcc_info->submit_discard); si->total_count = (int )sbi->user_block_count / sbi->blocks_per_seg; si->rsvd_segs =reserved_segments (sbi); si->overp_segs =overprovision_segments (sbi);
@@ -318,8 +324,9 @@ static int stat_show(struct seq_file *s, void *v)seq_printf (s," - Inner Struct Count: tree: %d(%d), node: %d\n" , si->ext_tree, si->zombie_tree, si->ext_node);seq_puts (s,"\nBalancing F2FS Async:\n" ); -seq_printf (s," - IO (CP: %4d, Data: %4d)\n" , - si->nr_wb_cp_data, si->nr_wb_data); +seq_printf (s," - IO (CP: %4d, Data: %4d, Flush: %4d, Discard: %4d)\n" , + si->nr_wb_cp_data, si->nr_wb_data, + si->nr_flush, si->nr_discard);seq_printf (s," - inmem: %4d, atomic IO: %4d (Max. %4d)\n" , si->inmem_pages, si->aw_cnt, si->max_aw_cnt); seq_printf(s, " - nodes: %4d in %4d\n",
fs/f2fs/f2fs.h +2 -1
@@ -201,6 +201,7 @@ struct discard_cmd_control {wait_queue_head_t discard_wait_queue;/* waiting queue for wake-up */ struct mutex cmd_lock;int max_discards;/* max. discards to be issued */ +atomic_t submit_discard;/* # of issued discard */ };/* for the list of fsync inodes, used only during recovery */
@@ -2254,7 +2255,7 @@ struct f2fs_stat_info {unsigned int ndirty_dirs, ndirty_files, ndirty_all;int nats, dirty_nats, sits, dirty_sits, free_nids, alloc_nids;int total_count, utilization; -int bg_gc, nr_wb_cp_data, nr_wb_data; +int bg_gc, nr_wb_cp_data, nr_wb_data, nr_flush, nr_discard;int inline_xattr, inline_inode, inline_dir, orphans;int aw_cnt, max_aw_cnt;unsigned int valid_count, valid_node_count, valid_inode_count, discard_blks;
fs/f2fs/segment.c +6 -0
@@ -653,6 +653,9 @@ static void __remove_discard_cmd(struct f2fs_sb_info *sbi, struct discard_cmd *d {int err = dc->bio->bi_error; +if (dc->state ==D_DONE ) +atomic_dec (&(SM_I (sbi)->dcc_info->submit_discard)); +if (err == -EOPNOTSUPP ) err =0 ;
@@ -678,6 +681,7 @@ void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr)if (dc->state ==D_PREP ) { dc->state =D_SUBMIT ;submit_bio (dc->bio); +atomic_inc (&dcc->submit_discard); }wait_for_completion_io (&dc->wait);
@@ -723,6 +727,7 @@ static int issue_discard_thread(void *data)if (dc->state ==D_PREP ) { dc->state =D_SUBMIT ;submit_bio (dc->bio); +atomic_inc (&dcc->submit_discard);if (iter++ >DISCARD_ISSUE_RATE )break ; }else if (dc->state ==D_DONE ) {
@@ -1050,6 +1055,7 @@ int create_discard_cmd_control(struct f2fs_sb_info *sbi)INIT_LIST_HEAD (&dcc->discard_entry_list);INIT_LIST_HEAD (&dcc->discard_cmd_list);mutex_init (&dcc->cmd_lock); +atomic_set (&dcc->submit_discard,0 ); dcc->nr_discards =0 ; dcc->max_discards =0 ;
Signature · 1 line
2.11.0
Re: [f2fs-dev] [PATCH 6/6] f2fs: show # of on-going flush and discard bios
In reply to Jaegeuk KimQuoted 1 line · Jaegeuk Kim
This patch adds stat information for flush and discard commands.
Need initialization of atomical variable?
Quoted 2 lines
Signed-off-by Jaegeuk Kim <[email protected]>
Thanks,
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Quoted 3 lines · Jaegeuk Kim
This patch simply cleans up the names for flush/discard commands.
Signed-off-by Jaegeuk Kim <[email protected]>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot