f2fs: fix to account cp stats correctly
authorChao Yu <chao@kernel.org>
Tue, 8 Aug 2023 00:59:49 +0000 (08:59 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Mon, 14 Aug 2023 20:42:05 +0000 (13:42 -0700)
cp_foreground_calls sysfs entry shows total CP call count rather than
foreground CP call count, fix it.

Fixes: fc7100ea2a52 ("f2fs: Add f2fs stats to sysfs")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/checkpoint.c
fs/f2fs/debug.c
fs/f2fs/f2fs.h
fs/f2fs/gc.c
fs/f2fs/recovery.c
fs/f2fs/segment.c
fs/f2fs/super.c
fs/f2fs/sysfs.c

index 8fd3b7f9fb88ef741803b29db90aff61852d6aee..b0597a539fc54842922714c74f893452296164e2 100644 (file)
@@ -1701,9 +1701,9 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
        }
 
        f2fs_restore_inmem_curseg(sbi);
+       stat_inc_cp_count(sbi);
 stop:
        unblock_operations(sbi);
-       stat_inc_cp_count(sbi->stat_info);
 
        if (cpc->reason & CP_RECOVERY)
                f2fs_notice(sbi, "checkpoint: version = %llx", ckpt_ver);
index c7cf453dce8385c7318c55de444ad9c6e8e28805..fdbf994f12718c566ef03d22fae9a7050a2ba5ee 100644 (file)
@@ -215,6 +215,9 @@ static void update_general_status(struct f2fs_sb_info *sbi)
                si->valid_blks[type] += blks;
        }
 
+       for (i = 0; i < MAX_CALL_TYPE; i++)
+               si->cp_call_count[i] = atomic_read(&sbi->cp_call_count[i]);
+
        for (i = 0; i < 2; i++) {
                si->segment_count[i] = sbi->segment_count[i];
                si->block_count[i] = sbi->block_count[i];
@@ -497,7 +500,9 @@ static int stat_show(struct seq_file *s, void *v)
                seq_printf(s, "  - Prefree: %d\n  - Free: %d (%d)\n\n",
                           si->prefree_count, si->free_segs, si->free_secs);
                seq_printf(s, "CP calls: %d (BG: %d)\n",
-                               si->cp_count, si->bg_cp_count);
+                          si->cp_call_count[TOTAL_CALL],
+                          si->cp_call_count[BACKGROUND]);
+               seq_printf(s, "CP count: %d\n", si->cp_count);
                seq_printf(s, "  - cp blocks : %u\n", si->meta_count[META_CP]);
                seq_printf(s, "  - sit blocks : %u\n",
                                si->meta_count[META_SIT]);
@@ -699,6 +704,8 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi)
        atomic_set(&sbi->inplace_count, 0);
        for (i = META_CP; i < META_MAX; i++)
                atomic_set(&sbi->meta_count[i], 0);
+       for (i = 0; i < MAX_CALL_TYPE; i++)
+               atomic_set(&sbi->cp_call_count[i], 0);
 
        atomic_set(&sbi->max_aw_cnt, 0);
 
index 6114babbb26a0e2f742116c13ce66d8947b590d9..c602ff2403b679fbe759c941ffc3f69e7bacc2df 100644 (file)
@@ -1383,6 +1383,13 @@ enum errors_option {
        MOUNT_ERRORS_PANIC,     /* panic on errors */
 };
 
+enum {
+       BACKGROUND,
+       FOREGROUND,
+       MAX_CALL_TYPE,
+       TOTAL_CALL = FOREGROUND,
+};
+
 static inline int f2fs_test_bit(unsigned int nr, char *addr);
 static inline void f2fs_set_bit(unsigned int nr, char *addr);
 static inline void f2fs_clear_bit(unsigned int nr, char *addr);
@@ -1695,6 +1702,7 @@ struct f2fs_sb_info {
        unsigned int io_skip_bggc;              /* skip background gc for in-flight IO */
        unsigned int other_skip_bggc;           /* skip background gc for other reasons */
        unsigned int ndirty_inode[NR_INODE_TYPE];       /* # of dirty inodes */
+       atomic_t cp_call_count[MAX_CALL_TYPE];  /* # of cp call */
 #endif
        spinlock_t stat_lock;                   /* lock for stat operations */
 
@@ -3860,12 +3868,6 @@ void f2fs_destroy_recovery_cache(void);
 /*
  * debug.c
  */
-enum {
-       BACKGROUND,
-       FOREGROUND,
-       MAX_CALL_TYPE
-};
-
 #ifdef CONFIG_F2FS_STAT_FS
 struct f2fs_stat_info {
        struct list_head stat_list;
@@ -3912,7 +3914,7 @@ struct f2fs_stat_info {
        int dirty_count, node_pages, meta_pages, compress_pages;
        int compress_page_hit;
        int prefree_count, free_segs, free_secs;
-       int cp_count, bg_cp_count;
+       int cp_call_count[MAX_CALL_TYPE], cp_count;
        int gc_call_count[MAX_CALL_TYPE];
        int gc_segs[2][2];
        int gc_secs[2][2];
@@ -3937,8 +3939,9 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
        return (struct f2fs_stat_info *)sbi->stat_info;
 }
 
-#define stat_inc_cp_count(si)          ((si)->cp_count++)
-#define stat_inc_bg_cp_count(si)       ((si)->bg_cp_count++)
+#define stat_inc_cp_call_count(sbi, foreground)                                \
+               atomic_inc(&sbi->cp_call_count[(foreground)])
+#define stat_inc_cp_count(si)          (F2FS_STAT(sbi)->cp_count++)
 #define stat_io_skip_bggc_count(sbi)   ((sbi)->io_skip_bggc++)
 #define stat_other_skip_bggc_count(sbi)        ((sbi)->other_skip_bggc++)
 #define stat_inc_dirty_inode(sbi, type)        ((sbi)->ndirty_inode[type]++)
@@ -4055,8 +4058,8 @@ void __init f2fs_create_root_stats(void);
 void f2fs_destroy_root_stats(void);
 void f2fs_update_sit_info(struct f2fs_sb_info *sbi);
 #else
-#define stat_inc_cp_count(si)                          do { } while (0)
-#define stat_inc_bg_cp_count(si)                       do { } while (0)
+#define stat_inc_cp_call_count(sbi, foreground)                do { } while (0)
+#define stat_inc_cp_count(sbi)                         do { } while (0)
 #define stat_io_skip_bggc_count(sbi)                   do { } while (0)
 #define stat_other_skip_bggc_count(sbi)                        do { } while (0)
 #define stat_inc_dirty_inode(sbi, type)                        do { } while (0)
index 68c3250fb3d230646a22438ace46d55bd54e41c2..6690323fff83bdb2ffe90ac38491fd50cf02d765 100644 (file)
@@ -1840,6 +1840,7 @@ gc_more:
                 * secure free segments which doesn't need fggc any more.
                 */
                if (prefree_segments(sbi)) {
+                       stat_inc_cp_call_count(sbi, TOTAL_CALL);
                        ret = f2fs_write_checkpoint(sbi, &cpc);
                        if (ret)
                                goto stop;
@@ -1888,6 +1889,7 @@ retry:
                round++;
                if (skipped_round > MAX_SKIP_GC_COUNT &&
                                skipped_round * 2 >= round) {
+                       stat_inc_cp_call_count(sbi, TOTAL_CALL);
                        ret = f2fs_write_checkpoint(sbi, &cpc);
                        goto stop;
                }
@@ -1903,6 +1905,7 @@ retry:
         */
        if (free_sections(sbi) <= upper_secs + NR_GC_CHECKPOINT_SECS &&
                                prefree_segments(sbi)) {
+               stat_inc_cp_call_count(sbi, TOTAL_CALL);
                ret = f2fs_write_checkpoint(sbi, &cpc);
                if (ret)
                        goto stop;
@@ -2030,6 +2033,7 @@ static int free_segment_range(struct f2fs_sb_info *sbi,
        if (gc_only)
                goto out;
 
+       stat_inc_cp_call_count(sbi, TOTAL_CALL);
        err = f2fs_write_checkpoint(sbi, &cpc);
        if (err)
                goto out;
@@ -2222,6 +2226,7 @@ out_drop_write:
        clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
        set_sbi_flag(sbi, SBI_IS_DIRTY);
 
+       stat_inc_cp_call_count(sbi, TOTAL_CALL);
        err = f2fs_write_checkpoint(sbi, &cpc);
        if (err) {
                update_fs_metadata(sbi, secs);
index 4e7d4ceeb084c52240cae21eb697632224695f20..e91f4619aa5bb6fa34353189a55e70df171d89fc 100644 (file)
@@ -924,6 +924,7 @@ skip:
                        struct cp_control cpc = {
                                .reason = CP_RECOVERY,
                        };
+                       stat_inc_cp_call_count(sbi, TOTAL_CALL);
                        err = f2fs_write_checkpoint(sbi, &cpc);
                }
        }
index d07e32e82aa9dee3622a41aa6a22401a33b2cce1..35d1e1dd849fdff521d8ce986dec5b5ac384cf27 100644 (file)
@@ -513,8 +513,8 @@ do_sync:
 
                mutex_unlock(&sbi->flush_lock);
        }
+       stat_inc_cp_call_count(sbi, BACKGROUND);
        f2fs_sync_fs(sbi->sb, 1);
-       stat_inc_bg_cp_count(sbi->stat_info);
 }
 
 static int __submit_flush_wait(struct f2fs_sb_info *sbi,
@@ -3248,6 +3248,7 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
                goto out;
 
        f2fs_down_write(&sbi->gc_lock);
+       stat_inc_cp_call_count(sbi, TOTAL_CALL);
        err = f2fs_write_checkpoint(sbi, &cpc);
        f2fs_up_write(&sbi->gc_lock);
        if (err)
index 2bbef48bc5a3adf8199df932e59101cc5a63ce26..a067466a694c981d6c17930191edd4e29f08c140 100644 (file)
@@ -1601,6 +1601,7 @@ static void f2fs_put_super(struct super_block *sb)
                struct cp_control cpc = {
                        .reason = CP_UMOUNT,
                };
+               stat_inc_cp_call_count(sbi, TOTAL_CALL);
                err = f2fs_write_checkpoint(sbi, &cpc);
        }
 
@@ -1610,6 +1611,7 @@ static void f2fs_put_super(struct super_block *sb)
                struct cp_control cpc = {
                        .reason = CP_UMOUNT | CP_TRIMMED,
                };
+               stat_inc_cp_call_count(sbi, TOTAL_CALL);
                err = f2fs_write_checkpoint(sbi, &cpc);
        }
 
@@ -1706,8 +1708,10 @@ int f2fs_sync_fs(struct super_block *sb, int sync)
        if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
                return -EAGAIN;
 
-       if (sync)
+       if (sync) {
+               stat_inc_cp_call_count(sbi, TOTAL_CALL);
                err = f2fs_issue_checkpoint(sbi);
+       }
 
        return err;
 }
@@ -2232,6 +2236,7 @@ skip_gc:
        f2fs_down_write(&sbi->gc_lock);
        cpc.reason = CP_PAUSE;
        set_sbi_flag(sbi, SBI_CP_DISABLED);
+       stat_inc_cp_call_count(sbi, TOTAL_CALL);
        err = f2fs_write_checkpoint(sbi, &cpc);
        if (err)
                goto out_unlock;
@@ -4868,6 +4873,7 @@ static void kill_f2fs_super(struct super_block *sb)
                        struct cp_control cpc = {
                                .reason = CP_UMOUNT,
                        };
+                       stat_inc_cp_call_count(sbi, TOTAL_CALL);
                        f2fs_write_checkpoint(sbi, &cpc);
                }
 
index 95a301581b9159614ce1808df7ca9fe300a7d25d..417fae96890f67bdded952838c43c3d3b799adb1 100644 (file)
@@ -356,6 +356,16 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
        if (!strcmp(a->attr.name, "revoked_atomic_block"))
                return sysfs_emit(buf, "%llu\n", sbi->revoked_atomic_block);
 
+#ifdef CONFIG_F2FS_STAT_FS
+       if (!strcmp(a->attr.name, "cp_foreground_calls"))
+               return sysfs_emit(buf, "%d\n",
+                               atomic_read(&sbi->cp_call_count[TOTAL_CALL]) -
+                               atomic_read(&sbi->cp_call_count[BACKGROUND]));
+       if (!strcmp(a->attr.name, "cp_background_calls"))
+               return sysfs_emit(buf, "%d\n",
+                               atomic_read(&sbi->cp_call_count[BACKGROUND]));
+#endif
+
        ui = (unsigned int *)(ptr + a->offset);
 
        return sysfs_emit(buf, "%u\n", *ui);
@@ -972,8 +982,8 @@ F2FS_SBI_GENERAL_RO_ATTR(unusable_blocks_per_sec);
 
 /* STAT_INFO ATTR */
 #ifdef CONFIG_F2FS_STAT_FS
-STAT_INFO_RO_ATTR(cp_foreground_calls, cp_count);
-STAT_INFO_RO_ATTR(cp_background_calls, bg_cp_count);
+STAT_INFO_RO_ATTR(cp_foreground_calls, cp_call_count[FOREGROUND]);
+STAT_INFO_RO_ATTR(cp_background_calls, cp_call_count[BACKGROUND]);
 STAT_INFO_RO_ATTR(gc_foreground_calls, gc_call_count[FOREGROUND]);
 STAT_INFO_RO_ATTR(gc_background_calls, gc_call_count[BACKGROUND]);
 #endif