Skip to content

Commit 2d56b4e

Browse files
chaseyuJaegeuk Kim
authored andcommitted
f2fs: multidevice: add stats in debugfs
This patch adds per-device stats in debugfs, the examples are as below: mkfs.f2fs -f -c /dev/vdc /dev/vdb mount /dev/vdb /mnt/f2fs/ cat /sys/kernel/debug/f2fs/status Multidevice stats: [seg: inuse dirty full free prefree] #0 5 0 0 4007 0 #1 1 0 0 8191 0 mkfs.f2fs -f -s 2 -c /dev/vdc /dev/vdb mount /dev/vdb /mnt/f2fs cat /sys/kernel/debug/f2fs/status Multidevice stats: [seg: inuse dirty full free prefree] [sec: inuse dirty full free prefree] #0 5 0 0 4005 0 5 0 0 2000 0 #1 1 0 0 8191 0 1 0 0 4095 0 Signed-off-by: Chao Yu <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]>
1 parent 6babe00 commit 2d56b4e

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed

fs/f2fs/debug.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,70 @@ void f2fs_update_sit_info(struct f2fs_sb_info *sbi)
6060
}
6161

6262
#ifdef CONFIG_DEBUG_FS
63+
static void update_multidevice_stats(struct f2fs_sb_info *sbi)
64+
{
65+
struct f2fs_stat_info *si = F2FS_STAT(sbi);
66+
struct f2fs_dev_stats *dev_stats = si->dev_stats;
67+
int i, j;
68+
69+
if (!f2fs_is_multi_device(sbi))
70+
return;
71+
72+
memset(dev_stats, 0, sizeof(struct f2fs_dev_stats) * sbi->s_ndevs);
73+
for (i = 0; i < sbi->s_ndevs; i++) {
74+
unsigned int start_segno, end_segno;
75+
block_t start_blk, end_blk;
76+
77+
if (i == 0) {
78+
start_blk = MAIN_BLKADDR(sbi);
79+
end_blk = FDEV(i).end_blk + 1 - SEG0_BLKADDR(sbi);
80+
} else {
81+
start_blk = FDEV(i).start_blk;
82+
end_blk = FDEV(i).end_blk + 1;
83+
}
84+
85+
start_segno = GET_SEGNO(sbi, start_blk);
86+
end_segno = GET_SEGNO(sbi, end_blk);
87+
88+
for (j = start_segno; j < end_segno; j++) {
89+
unsigned int seg_blks, sec_blks;
90+
91+
seg_blks = get_seg_entry(sbi, j)->valid_blocks;
92+
93+
/* update segment stats */
94+
if (IS_CURSEG(sbi, j))
95+
dev_stats[i].devstats[0][DEVSTAT_INUSE]++;
96+
else if (seg_blks == BLKS_PER_SEG(sbi))
97+
dev_stats[i].devstats[0][DEVSTAT_FULL]++;
98+
else if (seg_blks != 0)
99+
dev_stats[i].devstats[0][DEVSTAT_DIRTY]++;
100+
else if (!test_bit(j, FREE_I(sbi)->free_segmap))
101+
dev_stats[i].devstats[0][DEVSTAT_FREE]++;
102+
else
103+
dev_stats[i].devstats[0][DEVSTAT_PREFREE]++;
104+
105+
if (!__is_large_section(sbi) ||
106+
(j % SEGS_PER_SEC(sbi)) != 0)
107+
continue;
108+
109+
sec_blks = get_sec_entry(sbi, j)->valid_blocks;
110+
111+
/* update section stats */
112+
if (IS_CURSEC(sbi, GET_SEC_FROM_SEG(sbi, j)))
113+
dev_stats[i].devstats[1][DEVSTAT_INUSE]++;
114+
else if (sec_blks == BLKS_PER_SEC(sbi))
115+
dev_stats[i].devstats[1][DEVSTAT_FULL]++;
116+
else if (sec_blks != 0)
117+
dev_stats[i].devstats[1][DEVSTAT_DIRTY]++;
118+
else if (!test_bit(GET_SEC_FROM_SEG(sbi, j),
119+
FREE_I(sbi)->free_secmap))
120+
dev_stats[i].devstats[1][DEVSTAT_FREE]++;
121+
else
122+
dev_stats[i].devstats[1][DEVSTAT_PREFREE]++;
123+
}
124+
}
125+
}
126+
63127
static void update_general_status(struct f2fs_sb_info *sbi)
64128
{
65129
struct f2fs_stat_info *si = F2FS_STAT(sbi);
@@ -214,6 +278,8 @@ static void update_general_status(struct f2fs_sb_info *sbi)
214278
si->valid_blks[type] += blks;
215279
}
216280

281+
update_multidevice_stats(sbi);
282+
217283
for (i = 0; i < MAX_CALL_TYPE; i++)
218284
si->cp_call_count[i] = atomic_read(&sbi->cp_call_count[i]);
219285

@@ -498,6 +564,36 @@ static int stat_show(struct seq_file *s, void *v)
498564
si->dirty_count);
499565
seq_printf(s, " - Prefree: %d\n - Free: %d (%d)\n\n",
500566
si->prefree_count, si->free_segs, si->free_secs);
567+
if (f2fs_is_multi_device(sbi)) {
568+
seq_puts(s, "Multidevice stats:\n");
569+
seq_printf(s, " [seg: %8s %8s %8s %8s %8s]",
570+
"inuse", "dirty", "full", "free", "prefree");
571+
if (__is_large_section(sbi))
572+
seq_printf(s, " [sec: %8s %8s %8s %8s %8s]\n",
573+
"inuse", "dirty", "full", "free", "prefree");
574+
else
575+
seq_puts(s, "\n");
576+
577+
for (i = 0; i < sbi->s_ndevs; i++) {
578+
seq_printf(s, " #%-2d %8u %8u %8u %8u %8u", i,
579+
si->dev_stats[i].devstats[0][DEVSTAT_INUSE],
580+
si->dev_stats[i].devstats[0][DEVSTAT_DIRTY],
581+
si->dev_stats[i].devstats[0][DEVSTAT_FULL],
582+
si->dev_stats[i].devstats[0][DEVSTAT_FREE],
583+
si->dev_stats[i].devstats[0][DEVSTAT_PREFREE]);
584+
if (!__is_large_section(sbi)) {
585+
seq_puts(s, "\n");
586+
continue;
587+
}
588+
seq_printf(s, " %8u %8u %8u %8u %8u\n",
589+
si->dev_stats[i].devstats[1][DEVSTAT_INUSE],
590+
si->dev_stats[i].devstats[1][DEVSTAT_DIRTY],
591+
si->dev_stats[i].devstats[1][DEVSTAT_FULL],
592+
si->dev_stats[i].devstats[1][DEVSTAT_FREE],
593+
si->dev_stats[i].devstats[1][DEVSTAT_PREFREE]);
594+
}
595+
seq_puts(s, "\n");
596+
}
501597
seq_printf(s, "CP calls: %d (BG: %d)\n",
502598
si->cp_call_count[TOTAL_CALL],
503599
si->cp_call_count[BACKGROUND]);
@@ -665,13 +761,23 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi)
665761
{
666762
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
667763
struct f2fs_stat_info *si;
764+
struct f2fs_dev_stats *dev_stats;
668765
unsigned long flags;
669766
int i;
670767

671768
si = f2fs_kzalloc(sbi, sizeof(struct f2fs_stat_info), GFP_KERNEL);
672769
if (!si)
673770
return -ENOMEM;
674771

772+
dev_stats = f2fs_kzalloc(sbi, sizeof(struct f2fs_dev_stats) *
773+
sbi->s_ndevs, GFP_KERNEL);
774+
if (!dev_stats) {
775+
kfree(si);
776+
return -ENOMEM;
777+
}
778+
779+
si->dev_stats = dev_stats;
780+
675781
si->all_area_segs = le32_to_cpu(raw_super->segment_count);
676782
si->sit_area_segs = le32_to_cpu(raw_super->segment_count_sit);
677783
si->nat_area_segs = le32_to_cpu(raw_super->segment_count_nat);
@@ -724,6 +830,7 @@ void f2fs_destroy_stats(struct f2fs_sb_info *sbi)
724830
list_del(&si->stat_list);
725831
raw_spin_unlock_irqrestore(&f2fs_stat_lock, flags);
726832

833+
kfree(si->dev_stats);
727834
kfree(si);
728835
}
729836

fs/f2fs/f2fs.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3937,6 +3937,19 @@ void f2fs_destroy_recovery_cache(void);
39373937
* debug.c
39383938
*/
39393939
#ifdef CONFIG_F2FS_STAT_FS
3940+
enum {
3941+
DEVSTAT_INUSE,
3942+
DEVSTAT_DIRTY,
3943+
DEVSTAT_FULL,
3944+
DEVSTAT_FREE,
3945+
DEVSTAT_PREFREE,
3946+
DEVSTAT_MAX,
3947+
};
3948+
3949+
struct f2fs_dev_stats {
3950+
unsigned int devstats[2][DEVSTAT_MAX]; /* 0: segs, 1: secs */
3951+
};
3952+
39403953
struct f2fs_stat_info {
39413954
struct list_head stat_list;
39423955
struct f2fs_sb_info *sbi;
@@ -4000,6 +4013,7 @@ struct f2fs_stat_info {
40004013
unsigned int block_count[2];
40014014
unsigned int inplace_count;
40024015
unsigned long long base_mem, cache_mem, page_mem;
4016+
struct f2fs_dev_stats *dev_stats;
40034017
};
40044018

40054019
static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)

0 commit comments

Comments
 (0)