162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * f2fs debugging statistics
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2012 Samsung Electronics Co., Ltd.
662306a36Sopenharmony_ci *             http://www.samsung.com/
762306a36Sopenharmony_ci * Copyright (c) 2012 Linux Foundation
862306a36Sopenharmony_ci * Copyright (c) 2012 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/fs.h>
1262306a36Sopenharmony_ci#include <linux/backing-dev.h>
1362306a36Sopenharmony_ci#include <linux/f2fs_fs.h>
1462306a36Sopenharmony_ci#include <linux/blkdev.h>
1562306a36Sopenharmony_ci#include <linux/debugfs.h>
1662306a36Sopenharmony_ci#include <linux/seq_file.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#include "f2fs.h"
1962306a36Sopenharmony_ci#include "node.h"
2062306a36Sopenharmony_ci#include "segment.h"
2162306a36Sopenharmony_ci#include "gc.h"
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cistatic LIST_HEAD(f2fs_stat_list);
2462306a36Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(f2fs_stat_lock);
2562306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
2662306a36Sopenharmony_cistatic struct dentry *f2fs_debugfs_root;
2762306a36Sopenharmony_ci#endif
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/*
3062306a36Sopenharmony_ci * This function calculates BDF of every segments
3162306a36Sopenharmony_ci */
3262306a36Sopenharmony_civoid f2fs_update_sit_info(struct f2fs_sb_info *sbi)
3362306a36Sopenharmony_ci{
3462306a36Sopenharmony_ci	struct f2fs_stat_info *si = F2FS_STAT(sbi);
3562306a36Sopenharmony_ci	unsigned long long blks_per_sec, hblks_per_sec, total_vblocks;
3662306a36Sopenharmony_ci	unsigned long long bimodal, dist;
3762306a36Sopenharmony_ci	unsigned int segno, vblocks;
3862306a36Sopenharmony_ci	int ndirty = 0;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	bimodal = 0;
4162306a36Sopenharmony_ci	total_vblocks = 0;
4262306a36Sopenharmony_ci	blks_per_sec = CAP_BLKS_PER_SEC(sbi);
4362306a36Sopenharmony_ci	hblks_per_sec = blks_per_sec / 2;
4462306a36Sopenharmony_ci	for (segno = 0; segno < MAIN_SEGS(sbi); segno += sbi->segs_per_sec) {
4562306a36Sopenharmony_ci		vblocks = get_valid_blocks(sbi, segno, true);
4662306a36Sopenharmony_ci		dist = abs(vblocks - hblks_per_sec);
4762306a36Sopenharmony_ci		bimodal += dist * dist;
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci		if (vblocks > 0 && vblocks < blks_per_sec) {
5062306a36Sopenharmony_ci			total_vblocks += vblocks;
5162306a36Sopenharmony_ci			ndirty++;
5262306a36Sopenharmony_ci		}
5362306a36Sopenharmony_ci	}
5462306a36Sopenharmony_ci	dist = div_u64(MAIN_SECS(sbi) * hblks_per_sec * hblks_per_sec, 100);
5562306a36Sopenharmony_ci	si->bimodal = div64_u64(bimodal, dist);
5662306a36Sopenharmony_ci	if (si->dirty_count)
5762306a36Sopenharmony_ci		si->avg_vblocks = div_u64(total_vblocks, ndirty);
5862306a36Sopenharmony_ci	else
5962306a36Sopenharmony_ci		si->avg_vblocks = 0;
6062306a36Sopenharmony_ci}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
6362306a36Sopenharmony_cistatic void update_general_status(struct f2fs_sb_info *sbi)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	struct f2fs_stat_info *si = F2FS_STAT(sbi);
6662306a36Sopenharmony_ci	struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
6762306a36Sopenharmony_ci	int i;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	/* these will be changed if online resize is done */
7062306a36Sopenharmony_ci	si->main_area_segs = le32_to_cpu(raw_super->segment_count_main);
7162306a36Sopenharmony_ci	si->main_area_sections = le32_to_cpu(raw_super->section_count);
7262306a36Sopenharmony_ci	si->main_area_zones = si->main_area_sections /
7362306a36Sopenharmony_ci				le32_to_cpu(raw_super->secs_per_zone);
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	/* general extent cache stats */
7662306a36Sopenharmony_ci	for (i = 0; i < NR_EXTENT_CACHES; i++) {
7762306a36Sopenharmony_ci		struct extent_tree_info *eti = &sbi->extent_tree[i];
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci		si->hit_cached[i] = atomic64_read(&sbi->read_hit_cached[i]);
8062306a36Sopenharmony_ci		si->hit_rbtree[i] = atomic64_read(&sbi->read_hit_rbtree[i]);
8162306a36Sopenharmony_ci		si->total_ext[i] = atomic64_read(&sbi->total_hit_ext[i]);
8262306a36Sopenharmony_ci		si->hit_total[i] = si->hit_cached[i] + si->hit_rbtree[i];
8362306a36Sopenharmony_ci		si->ext_tree[i] = atomic_read(&eti->total_ext_tree);
8462306a36Sopenharmony_ci		si->zombie_tree[i] = atomic_read(&eti->total_zombie_tree);
8562306a36Sopenharmony_ci		si->ext_node[i] = atomic_read(&eti->total_ext_node);
8662306a36Sopenharmony_ci	}
8762306a36Sopenharmony_ci	/* read extent_cache only */
8862306a36Sopenharmony_ci	si->hit_largest = atomic64_read(&sbi->read_hit_largest);
8962306a36Sopenharmony_ci	si->hit_total[EX_READ] += si->hit_largest;
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	/* block age extent_cache only */
9262306a36Sopenharmony_ci	si->allocated_data_blocks = atomic64_read(&sbi->allocated_data_blocks);
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	/* validation check of the segment numbers */
9562306a36Sopenharmony_ci	si->ndirty_node = get_pages(sbi, F2FS_DIRTY_NODES);
9662306a36Sopenharmony_ci	si->ndirty_dent = get_pages(sbi, F2FS_DIRTY_DENTS);
9762306a36Sopenharmony_ci	si->ndirty_meta = get_pages(sbi, F2FS_DIRTY_META);
9862306a36Sopenharmony_ci	si->ndirty_data = get_pages(sbi, F2FS_DIRTY_DATA);
9962306a36Sopenharmony_ci	si->ndirty_qdata = get_pages(sbi, F2FS_DIRTY_QDATA);
10062306a36Sopenharmony_ci	si->ndirty_imeta = get_pages(sbi, F2FS_DIRTY_IMETA);
10162306a36Sopenharmony_ci	si->ndirty_dirs = sbi->ndirty_inode[DIR_INODE];
10262306a36Sopenharmony_ci	si->ndirty_files = sbi->ndirty_inode[FILE_INODE];
10362306a36Sopenharmony_ci	si->nquota_files = sbi->nquota_files;
10462306a36Sopenharmony_ci	si->ndirty_all = sbi->ndirty_inode[DIRTY_META];
10562306a36Sopenharmony_ci	si->aw_cnt = atomic_read(&sbi->atomic_files);
10662306a36Sopenharmony_ci	si->max_aw_cnt = atomic_read(&sbi->max_aw_cnt);
10762306a36Sopenharmony_ci	si->nr_dio_read = get_pages(sbi, F2FS_DIO_READ);
10862306a36Sopenharmony_ci	si->nr_dio_write = get_pages(sbi, F2FS_DIO_WRITE);
10962306a36Sopenharmony_ci	si->nr_wb_cp_data = get_pages(sbi, F2FS_WB_CP_DATA);
11062306a36Sopenharmony_ci	si->nr_wb_data = get_pages(sbi, F2FS_WB_DATA);
11162306a36Sopenharmony_ci	si->nr_rd_data = get_pages(sbi, F2FS_RD_DATA);
11262306a36Sopenharmony_ci	si->nr_rd_node = get_pages(sbi, F2FS_RD_NODE);
11362306a36Sopenharmony_ci	si->nr_rd_meta = get_pages(sbi, F2FS_RD_META);
11462306a36Sopenharmony_ci	if (SM_I(sbi)->fcc_info) {
11562306a36Sopenharmony_ci		si->nr_flushed =
11662306a36Sopenharmony_ci			atomic_read(&SM_I(sbi)->fcc_info->issued_flush);
11762306a36Sopenharmony_ci		si->nr_flushing =
11862306a36Sopenharmony_ci			atomic_read(&SM_I(sbi)->fcc_info->queued_flush);
11962306a36Sopenharmony_ci		si->flush_list_empty =
12062306a36Sopenharmony_ci			llist_empty(&SM_I(sbi)->fcc_info->issue_list);
12162306a36Sopenharmony_ci	}
12262306a36Sopenharmony_ci	if (SM_I(sbi)->dcc_info) {
12362306a36Sopenharmony_ci		si->nr_discarded =
12462306a36Sopenharmony_ci			atomic_read(&SM_I(sbi)->dcc_info->issued_discard);
12562306a36Sopenharmony_ci		si->nr_discarding =
12662306a36Sopenharmony_ci			atomic_read(&SM_I(sbi)->dcc_info->queued_discard);
12762306a36Sopenharmony_ci		si->nr_discard_cmd =
12862306a36Sopenharmony_ci			atomic_read(&SM_I(sbi)->dcc_info->discard_cmd_cnt);
12962306a36Sopenharmony_ci		si->undiscard_blks = SM_I(sbi)->dcc_info->undiscard_blks;
13062306a36Sopenharmony_ci	}
13162306a36Sopenharmony_ci	si->nr_issued_ckpt = atomic_read(&sbi->cprc_info.issued_ckpt);
13262306a36Sopenharmony_ci	si->nr_total_ckpt = atomic_read(&sbi->cprc_info.total_ckpt);
13362306a36Sopenharmony_ci	si->nr_queued_ckpt = atomic_read(&sbi->cprc_info.queued_ckpt);
13462306a36Sopenharmony_ci	spin_lock(&sbi->cprc_info.stat_lock);
13562306a36Sopenharmony_ci	si->cur_ckpt_time = sbi->cprc_info.cur_time;
13662306a36Sopenharmony_ci	si->peak_ckpt_time = sbi->cprc_info.peak_time;
13762306a36Sopenharmony_ci	spin_unlock(&sbi->cprc_info.stat_lock);
13862306a36Sopenharmony_ci	si->total_count = (int)sbi->user_block_count / sbi->blocks_per_seg;
13962306a36Sopenharmony_ci	si->rsvd_segs = reserved_segments(sbi);
14062306a36Sopenharmony_ci	si->overp_segs = overprovision_segments(sbi);
14162306a36Sopenharmony_ci	si->valid_count = valid_user_blocks(sbi);
14262306a36Sopenharmony_ci	si->discard_blks = discard_blocks(sbi);
14362306a36Sopenharmony_ci	si->valid_node_count = valid_node_count(sbi);
14462306a36Sopenharmony_ci	si->valid_inode_count = valid_inode_count(sbi);
14562306a36Sopenharmony_ci	si->inline_xattr = atomic_read(&sbi->inline_xattr);
14662306a36Sopenharmony_ci	si->inline_inode = atomic_read(&sbi->inline_inode);
14762306a36Sopenharmony_ci	si->inline_dir = atomic_read(&sbi->inline_dir);
14862306a36Sopenharmony_ci	si->compr_inode = atomic_read(&sbi->compr_inode);
14962306a36Sopenharmony_ci	si->swapfile_inode = atomic_read(&sbi->swapfile_inode);
15062306a36Sopenharmony_ci	si->compr_blocks = atomic64_read(&sbi->compr_blocks);
15162306a36Sopenharmony_ci	si->append = sbi->im[APPEND_INO].ino_num;
15262306a36Sopenharmony_ci	si->update = sbi->im[UPDATE_INO].ino_num;
15362306a36Sopenharmony_ci	si->orphans = sbi->im[ORPHAN_INO].ino_num;
15462306a36Sopenharmony_ci	si->utilization = utilization(sbi);
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	si->free_segs = free_segments(sbi);
15762306a36Sopenharmony_ci	si->free_secs = free_sections(sbi);
15862306a36Sopenharmony_ci	si->prefree_count = prefree_segments(sbi);
15962306a36Sopenharmony_ci	si->dirty_count = dirty_segments(sbi);
16062306a36Sopenharmony_ci	if (sbi->node_inode)
16162306a36Sopenharmony_ci		si->node_pages = NODE_MAPPING(sbi)->nrpages;
16262306a36Sopenharmony_ci	if (sbi->meta_inode)
16362306a36Sopenharmony_ci		si->meta_pages = META_MAPPING(sbi)->nrpages;
16462306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
16562306a36Sopenharmony_ci	if (sbi->compress_inode) {
16662306a36Sopenharmony_ci		si->compress_pages = COMPRESS_MAPPING(sbi)->nrpages;
16762306a36Sopenharmony_ci		si->compress_page_hit = atomic_read(&sbi->compress_page_hit);
16862306a36Sopenharmony_ci	}
16962306a36Sopenharmony_ci#endif
17062306a36Sopenharmony_ci	si->nats = NM_I(sbi)->nat_cnt[TOTAL_NAT];
17162306a36Sopenharmony_ci	si->dirty_nats = NM_I(sbi)->nat_cnt[DIRTY_NAT];
17262306a36Sopenharmony_ci	si->sits = MAIN_SEGS(sbi);
17362306a36Sopenharmony_ci	si->dirty_sits = SIT_I(sbi)->dirty_sentries;
17462306a36Sopenharmony_ci	si->free_nids = NM_I(sbi)->nid_cnt[FREE_NID];
17562306a36Sopenharmony_ci	si->avail_nids = NM_I(sbi)->available_nids;
17662306a36Sopenharmony_ci	si->alloc_nids = NM_I(sbi)->nid_cnt[PREALLOC_NID];
17762306a36Sopenharmony_ci	si->io_skip_bggc = sbi->io_skip_bggc;
17862306a36Sopenharmony_ci	si->other_skip_bggc = sbi->other_skip_bggc;
17962306a36Sopenharmony_ci	si->util_free = (int)(free_user_blocks(sbi) >> sbi->log_blocks_per_seg)
18062306a36Sopenharmony_ci		* 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
18162306a36Sopenharmony_ci		/ 2;
18262306a36Sopenharmony_ci	si->util_valid = (int)(written_block_count(sbi) >>
18362306a36Sopenharmony_ci						sbi->log_blocks_per_seg)
18462306a36Sopenharmony_ci		* 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
18562306a36Sopenharmony_ci		/ 2;
18662306a36Sopenharmony_ci	si->util_invalid = 50 - si->util_free - si->util_valid;
18762306a36Sopenharmony_ci	for (i = CURSEG_HOT_DATA; i < NO_CHECK_TYPE; i++) {
18862306a36Sopenharmony_ci		struct curseg_info *curseg = CURSEG_I(sbi, i);
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci		si->curseg[i] = curseg->segno;
19162306a36Sopenharmony_ci		si->cursec[i] = GET_SEC_FROM_SEG(sbi, curseg->segno);
19262306a36Sopenharmony_ci		si->curzone[i] = GET_ZONE_FROM_SEC(sbi, si->cursec[i]);
19362306a36Sopenharmony_ci	}
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	for (i = META_CP; i < META_MAX; i++)
19662306a36Sopenharmony_ci		si->meta_count[i] = atomic_read(&sbi->meta_count[i]);
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	for (i = 0; i < NO_CHECK_TYPE; i++) {
19962306a36Sopenharmony_ci		si->dirty_seg[i] = 0;
20062306a36Sopenharmony_ci		si->full_seg[i] = 0;
20162306a36Sopenharmony_ci		si->valid_blks[i] = 0;
20262306a36Sopenharmony_ci	}
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	for (i = 0; i < MAIN_SEGS(sbi); i++) {
20562306a36Sopenharmony_ci		int blks = get_seg_entry(sbi, i)->valid_blocks;
20662306a36Sopenharmony_ci		int type = get_seg_entry(sbi, i)->type;
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci		if (!blks)
20962306a36Sopenharmony_ci			continue;
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci		if (blks == sbi->blocks_per_seg)
21262306a36Sopenharmony_ci			si->full_seg[type]++;
21362306a36Sopenharmony_ci		else
21462306a36Sopenharmony_ci			si->dirty_seg[type]++;
21562306a36Sopenharmony_ci		si->valid_blks[type] += blks;
21662306a36Sopenharmony_ci	}
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	for (i = 0; i < MAX_CALL_TYPE; i++)
21962306a36Sopenharmony_ci		si->cp_call_count[i] = atomic_read(&sbi->cp_call_count[i]);
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	for (i = 0; i < 2; i++) {
22262306a36Sopenharmony_ci		si->segment_count[i] = sbi->segment_count[i];
22362306a36Sopenharmony_ci		si->block_count[i] = sbi->block_count[i];
22462306a36Sopenharmony_ci	}
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	si->inplace_count = atomic_read(&sbi->inplace_count);
22762306a36Sopenharmony_ci}
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci/*
23062306a36Sopenharmony_ci * This function calculates memory footprint.
23162306a36Sopenharmony_ci */
23262306a36Sopenharmony_cistatic void update_mem_info(struct f2fs_sb_info *sbi)
23362306a36Sopenharmony_ci{
23462306a36Sopenharmony_ci	struct f2fs_stat_info *si = F2FS_STAT(sbi);
23562306a36Sopenharmony_ci	int i;
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	if (si->base_mem)
23862306a36Sopenharmony_ci		goto get_cache;
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	/* build stat */
24162306a36Sopenharmony_ci	si->base_mem = sizeof(struct f2fs_stat_info);
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci	/* build superblock */
24462306a36Sopenharmony_ci	si->base_mem += sizeof(struct f2fs_sb_info) + sbi->sb->s_blocksize;
24562306a36Sopenharmony_ci	si->base_mem += 2 * sizeof(struct f2fs_inode_info);
24662306a36Sopenharmony_ci	si->base_mem += sizeof(*sbi->ckpt);
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	/* build sm */
24962306a36Sopenharmony_ci	si->base_mem += sizeof(struct f2fs_sm_info);
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	/* build sit */
25262306a36Sopenharmony_ci	si->base_mem += sizeof(struct sit_info);
25362306a36Sopenharmony_ci	si->base_mem += MAIN_SEGS(sbi) * sizeof(struct seg_entry);
25462306a36Sopenharmony_ci	si->base_mem += f2fs_bitmap_size(MAIN_SEGS(sbi));
25562306a36Sopenharmony_ci	si->base_mem += 2 * SIT_VBLOCK_MAP_SIZE * MAIN_SEGS(sbi);
25662306a36Sopenharmony_ci	si->base_mem += SIT_VBLOCK_MAP_SIZE * MAIN_SEGS(sbi);
25762306a36Sopenharmony_ci	si->base_mem += SIT_VBLOCK_MAP_SIZE;
25862306a36Sopenharmony_ci	if (__is_large_section(sbi))
25962306a36Sopenharmony_ci		si->base_mem += MAIN_SECS(sbi) * sizeof(struct sec_entry);
26062306a36Sopenharmony_ci	si->base_mem += __bitmap_size(sbi, SIT_BITMAP);
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci	/* build free segmap */
26362306a36Sopenharmony_ci	si->base_mem += sizeof(struct free_segmap_info);
26462306a36Sopenharmony_ci	si->base_mem += f2fs_bitmap_size(MAIN_SEGS(sbi));
26562306a36Sopenharmony_ci	si->base_mem += f2fs_bitmap_size(MAIN_SECS(sbi));
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	/* build curseg */
26862306a36Sopenharmony_ci	si->base_mem += sizeof(struct curseg_info) * NR_CURSEG_TYPE;
26962306a36Sopenharmony_ci	si->base_mem += PAGE_SIZE * NR_CURSEG_TYPE;
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci	/* build dirty segmap */
27262306a36Sopenharmony_ci	si->base_mem += sizeof(struct dirty_seglist_info);
27362306a36Sopenharmony_ci	si->base_mem += NR_DIRTY_TYPE * f2fs_bitmap_size(MAIN_SEGS(sbi));
27462306a36Sopenharmony_ci	si->base_mem += f2fs_bitmap_size(MAIN_SECS(sbi));
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci	/* build nm */
27762306a36Sopenharmony_ci	si->base_mem += sizeof(struct f2fs_nm_info);
27862306a36Sopenharmony_ci	si->base_mem += __bitmap_size(sbi, NAT_BITMAP);
27962306a36Sopenharmony_ci	si->base_mem += (NM_I(sbi)->nat_bits_blocks << F2FS_BLKSIZE_BITS);
28062306a36Sopenharmony_ci	si->base_mem += NM_I(sbi)->nat_blocks *
28162306a36Sopenharmony_ci				f2fs_bitmap_size(NAT_ENTRY_PER_BLOCK);
28262306a36Sopenharmony_ci	si->base_mem += NM_I(sbi)->nat_blocks / 8;
28362306a36Sopenharmony_ci	si->base_mem += NM_I(sbi)->nat_blocks * sizeof(unsigned short);
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ciget_cache:
28662306a36Sopenharmony_ci	si->cache_mem = 0;
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	/* build gc */
28962306a36Sopenharmony_ci	if (sbi->gc_thread)
29062306a36Sopenharmony_ci		si->cache_mem += sizeof(struct f2fs_gc_kthread);
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci	/* build merge flush thread */
29362306a36Sopenharmony_ci	if (SM_I(sbi)->fcc_info)
29462306a36Sopenharmony_ci		si->cache_mem += sizeof(struct flush_cmd_control);
29562306a36Sopenharmony_ci	if (SM_I(sbi)->dcc_info) {
29662306a36Sopenharmony_ci		si->cache_mem += sizeof(struct discard_cmd_control);
29762306a36Sopenharmony_ci		si->cache_mem += sizeof(struct discard_cmd) *
29862306a36Sopenharmony_ci			atomic_read(&SM_I(sbi)->dcc_info->discard_cmd_cnt);
29962306a36Sopenharmony_ci	}
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci	/* free nids */
30262306a36Sopenharmony_ci	si->cache_mem += (NM_I(sbi)->nid_cnt[FREE_NID] +
30362306a36Sopenharmony_ci				NM_I(sbi)->nid_cnt[PREALLOC_NID]) *
30462306a36Sopenharmony_ci				sizeof(struct free_nid);
30562306a36Sopenharmony_ci	si->cache_mem += NM_I(sbi)->nat_cnt[TOTAL_NAT] *
30662306a36Sopenharmony_ci				sizeof(struct nat_entry);
30762306a36Sopenharmony_ci	si->cache_mem += NM_I(sbi)->nat_cnt[DIRTY_NAT] *
30862306a36Sopenharmony_ci				sizeof(struct nat_entry_set);
30962306a36Sopenharmony_ci	for (i = 0; i < MAX_INO_ENTRY; i++)
31062306a36Sopenharmony_ci		si->cache_mem += sbi->im[i].ino_num * sizeof(struct ino_entry);
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	for (i = 0; i < NR_EXTENT_CACHES; i++) {
31362306a36Sopenharmony_ci		struct extent_tree_info *eti = &sbi->extent_tree[i];
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci		si->ext_mem[i] = atomic_read(&eti->total_ext_tree) *
31662306a36Sopenharmony_ci						sizeof(struct extent_tree);
31762306a36Sopenharmony_ci		si->ext_mem[i] += atomic_read(&eti->total_ext_node) *
31862306a36Sopenharmony_ci						sizeof(struct extent_node);
31962306a36Sopenharmony_ci		si->cache_mem += si->ext_mem[i];
32062306a36Sopenharmony_ci	}
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	si->page_mem = 0;
32362306a36Sopenharmony_ci	if (sbi->node_inode) {
32462306a36Sopenharmony_ci		unsigned long npages = NODE_MAPPING(sbi)->nrpages;
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci		si->page_mem += (unsigned long long)npages << PAGE_SHIFT;
32762306a36Sopenharmony_ci	}
32862306a36Sopenharmony_ci	if (sbi->meta_inode) {
32962306a36Sopenharmony_ci		unsigned long npages = META_MAPPING(sbi)->nrpages;
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci		si->page_mem += (unsigned long long)npages << PAGE_SHIFT;
33262306a36Sopenharmony_ci	}
33362306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
33462306a36Sopenharmony_ci	if (sbi->compress_inode) {
33562306a36Sopenharmony_ci		unsigned long npages = COMPRESS_MAPPING(sbi)->nrpages;
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci		si->page_mem += (unsigned long long)npages << PAGE_SHIFT;
33862306a36Sopenharmony_ci	}
33962306a36Sopenharmony_ci#endif
34062306a36Sopenharmony_ci}
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_cistatic const char *s_flag[MAX_SBI_FLAG] = {
34362306a36Sopenharmony_ci	[SBI_IS_DIRTY]		= "fs_dirty",
34462306a36Sopenharmony_ci	[SBI_IS_CLOSE]		= "closing",
34562306a36Sopenharmony_ci	[SBI_NEED_FSCK]		= "need_fsck",
34662306a36Sopenharmony_ci	[SBI_POR_DOING]		= "recovering",
34762306a36Sopenharmony_ci	[SBI_NEED_SB_WRITE]	= "sb_dirty",
34862306a36Sopenharmony_ci	[SBI_NEED_CP]		= "need_cp",
34962306a36Sopenharmony_ci	[SBI_IS_SHUTDOWN]	= "shutdown",
35062306a36Sopenharmony_ci	[SBI_IS_RECOVERED]	= "recovered",
35162306a36Sopenharmony_ci	[SBI_CP_DISABLED]	= "cp_disabled",
35262306a36Sopenharmony_ci	[SBI_CP_DISABLED_QUICK]	= "cp_disabled_quick",
35362306a36Sopenharmony_ci	[SBI_QUOTA_NEED_FLUSH]	= "quota_need_flush",
35462306a36Sopenharmony_ci	[SBI_QUOTA_SKIP_FLUSH]	= "quota_skip_flush",
35562306a36Sopenharmony_ci	[SBI_QUOTA_NEED_REPAIR]	= "quota_need_repair",
35662306a36Sopenharmony_ci	[SBI_IS_RESIZEFS]	= "resizefs",
35762306a36Sopenharmony_ci	[SBI_IS_FREEZING]	= "freezefs",
35862306a36Sopenharmony_ci	[SBI_IS_WRITABLE]	= "writable",
35962306a36Sopenharmony_ci};
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_cistatic const char *ipu_mode_names[F2FS_IPU_MAX] = {
36262306a36Sopenharmony_ci	[F2FS_IPU_FORCE]	= "FORCE",
36362306a36Sopenharmony_ci	[F2FS_IPU_SSR]		= "SSR",
36462306a36Sopenharmony_ci	[F2FS_IPU_UTIL]		= "UTIL",
36562306a36Sopenharmony_ci	[F2FS_IPU_SSR_UTIL]	= "SSR_UTIL",
36662306a36Sopenharmony_ci	[F2FS_IPU_FSYNC]	= "FSYNC",
36762306a36Sopenharmony_ci	[F2FS_IPU_ASYNC]	= "ASYNC",
36862306a36Sopenharmony_ci	[F2FS_IPU_NOCACHE]	= "NOCACHE",
36962306a36Sopenharmony_ci	[F2FS_IPU_HONOR_OPU_WRITE]	= "HONOR_OPU_WRITE",
37062306a36Sopenharmony_ci};
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_cistatic int stat_show(struct seq_file *s, void *v)
37362306a36Sopenharmony_ci{
37462306a36Sopenharmony_ci	struct f2fs_stat_info *si;
37562306a36Sopenharmony_ci	int i = 0, j = 0;
37662306a36Sopenharmony_ci	unsigned long flags;
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci	raw_spin_lock_irqsave(&f2fs_stat_lock, flags);
37962306a36Sopenharmony_ci	list_for_each_entry(si, &f2fs_stat_list, stat_list) {
38062306a36Sopenharmony_ci		struct f2fs_sb_info *sbi = si->sbi;
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci		update_general_status(sbi);
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci		seq_printf(s, "\n=====[ partition info(%pg). #%d, %s, CP: %s]=====\n",
38562306a36Sopenharmony_ci			sbi->sb->s_bdev, i++,
38662306a36Sopenharmony_ci			f2fs_readonly(sbi->sb) ? "RO" : "RW",
38762306a36Sopenharmony_ci			is_set_ckpt_flags(sbi, CP_DISABLED_FLAG) ?
38862306a36Sopenharmony_ci			"Disabled" : (f2fs_cp_error(sbi) ? "Error" : "Good"));
38962306a36Sopenharmony_ci		if (sbi->s_flag) {
39062306a36Sopenharmony_ci			seq_puts(s, "[SBI:");
39162306a36Sopenharmony_ci			for_each_set_bit(j, &sbi->s_flag, MAX_SBI_FLAG)
39262306a36Sopenharmony_ci				seq_printf(s, " %s", s_flag[j]);
39362306a36Sopenharmony_ci			seq_puts(s, "]\n");
39462306a36Sopenharmony_ci		}
39562306a36Sopenharmony_ci		seq_printf(s, "[SB: 1] [CP: 2] [SIT: %d] [NAT: %d] ",
39662306a36Sopenharmony_ci			   si->sit_area_segs, si->nat_area_segs);
39762306a36Sopenharmony_ci		seq_printf(s, "[SSA: %d] [MAIN: %d",
39862306a36Sopenharmony_ci			   si->ssa_area_segs, si->main_area_segs);
39962306a36Sopenharmony_ci		seq_printf(s, "(OverProv:%d Resv:%d)]\n\n",
40062306a36Sopenharmony_ci			   si->overp_segs, si->rsvd_segs);
40162306a36Sopenharmony_ci		seq_printf(s, "Current Time Sec: %llu / Mounted Time Sec: %llu\n\n",
40262306a36Sopenharmony_ci					ktime_get_boottime_seconds(),
40362306a36Sopenharmony_ci					SIT_I(sbi)->mounted_time);
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci		seq_puts(s, "Policy:\n");
40662306a36Sopenharmony_ci		seq_puts(s, "  - IPU: [");
40762306a36Sopenharmony_ci		if (IS_F2FS_IPU_DISABLE(sbi)) {
40862306a36Sopenharmony_ci			seq_puts(s, " DISABLE");
40962306a36Sopenharmony_ci		} else {
41062306a36Sopenharmony_ci			unsigned long policy = SM_I(sbi)->ipu_policy;
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci			for_each_set_bit(j, &policy, F2FS_IPU_MAX)
41362306a36Sopenharmony_ci				seq_printf(s, " %s", ipu_mode_names[j]);
41462306a36Sopenharmony_ci		}
41562306a36Sopenharmony_ci		seq_puts(s, " ]\n\n");
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci		if (test_opt(sbi, DISCARD))
41862306a36Sopenharmony_ci			seq_printf(s, "Utilization: %u%% (%u valid blocks, %u discard blocks)\n",
41962306a36Sopenharmony_ci				si->utilization, si->valid_count, si->discard_blks);
42062306a36Sopenharmony_ci		else
42162306a36Sopenharmony_ci			seq_printf(s, "Utilization: %u%% (%u valid blocks)\n",
42262306a36Sopenharmony_ci				si->utilization, si->valid_count);
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci		seq_printf(s, "  - Node: %u (Inode: %u, ",
42562306a36Sopenharmony_ci			   si->valid_node_count, si->valid_inode_count);
42662306a36Sopenharmony_ci		seq_printf(s, "Other: %u)\n  - Data: %u\n",
42762306a36Sopenharmony_ci			   si->valid_node_count - si->valid_inode_count,
42862306a36Sopenharmony_ci			   si->valid_count - si->valid_node_count);
42962306a36Sopenharmony_ci		seq_printf(s, "  - Inline_xattr Inode: %u\n",
43062306a36Sopenharmony_ci			   si->inline_xattr);
43162306a36Sopenharmony_ci		seq_printf(s, "  - Inline_data Inode: %u\n",
43262306a36Sopenharmony_ci			   si->inline_inode);
43362306a36Sopenharmony_ci		seq_printf(s, "  - Inline_dentry Inode: %u\n",
43462306a36Sopenharmony_ci			   si->inline_dir);
43562306a36Sopenharmony_ci		seq_printf(s, "  - Compressed Inode: %u, Blocks: %llu\n",
43662306a36Sopenharmony_ci			   si->compr_inode, si->compr_blocks);
43762306a36Sopenharmony_ci		seq_printf(s, "  - Swapfile Inode: %u\n",
43862306a36Sopenharmony_ci			   si->swapfile_inode);
43962306a36Sopenharmony_ci		seq_printf(s, "  - Orphan/Append/Update Inode: %u, %u, %u\n",
44062306a36Sopenharmony_ci			   si->orphans, si->append, si->update);
44162306a36Sopenharmony_ci		seq_printf(s, "\nMain area: %d segs, %d secs %d zones\n",
44262306a36Sopenharmony_ci			   si->main_area_segs, si->main_area_sections,
44362306a36Sopenharmony_ci			   si->main_area_zones);
44462306a36Sopenharmony_ci		seq_printf(s, "    TYPE         %8s %8s %8s %10s %10s %10s\n",
44562306a36Sopenharmony_ci			   "segno", "secno", "zoneno", "dirty_seg", "full_seg", "valid_blk");
44662306a36Sopenharmony_ci		seq_printf(s, "  - COLD   data: %8d %8d %8d %10u %10u %10u\n",
44762306a36Sopenharmony_ci			   si->curseg[CURSEG_COLD_DATA],
44862306a36Sopenharmony_ci			   si->cursec[CURSEG_COLD_DATA],
44962306a36Sopenharmony_ci			   si->curzone[CURSEG_COLD_DATA],
45062306a36Sopenharmony_ci			   si->dirty_seg[CURSEG_COLD_DATA],
45162306a36Sopenharmony_ci			   si->full_seg[CURSEG_COLD_DATA],
45262306a36Sopenharmony_ci			   si->valid_blks[CURSEG_COLD_DATA]);
45362306a36Sopenharmony_ci		seq_printf(s, "  - WARM   data: %8d %8d %8d %10u %10u %10u\n",
45462306a36Sopenharmony_ci			   si->curseg[CURSEG_WARM_DATA],
45562306a36Sopenharmony_ci			   si->cursec[CURSEG_WARM_DATA],
45662306a36Sopenharmony_ci			   si->curzone[CURSEG_WARM_DATA],
45762306a36Sopenharmony_ci			   si->dirty_seg[CURSEG_WARM_DATA],
45862306a36Sopenharmony_ci			   si->full_seg[CURSEG_WARM_DATA],
45962306a36Sopenharmony_ci			   si->valid_blks[CURSEG_WARM_DATA]);
46062306a36Sopenharmony_ci		seq_printf(s, "  - HOT    data: %8d %8d %8d %10u %10u %10u\n",
46162306a36Sopenharmony_ci			   si->curseg[CURSEG_HOT_DATA],
46262306a36Sopenharmony_ci			   si->cursec[CURSEG_HOT_DATA],
46362306a36Sopenharmony_ci			   si->curzone[CURSEG_HOT_DATA],
46462306a36Sopenharmony_ci			   si->dirty_seg[CURSEG_HOT_DATA],
46562306a36Sopenharmony_ci			   si->full_seg[CURSEG_HOT_DATA],
46662306a36Sopenharmony_ci			   si->valid_blks[CURSEG_HOT_DATA]);
46762306a36Sopenharmony_ci		seq_printf(s, "  - Dir   dnode: %8d %8d %8d %10u %10u %10u\n",
46862306a36Sopenharmony_ci			   si->curseg[CURSEG_HOT_NODE],
46962306a36Sopenharmony_ci			   si->cursec[CURSEG_HOT_NODE],
47062306a36Sopenharmony_ci			   si->curzone[CURSEG_HOT_NODE],
47162306a36Sopenharmony_ci			   si->dirty_seg[CURSEG_HOT_NODE],
47262306a36Sopenharmony_ci			   si->full_seg[CURSEG_HOT_NODE],
47362306a36Sopenharmony_ci			   si->valid_blks[CURSEG_HOT_NODE]);
47462306a36Sopenharmony_ci		seq_printf(s, "  - File  dnode: %8d %8d %8d %10u %10u %10u\n",
47562306a36Sopenharmony_ci			   si->curseg[CURSEG_WARM_NODE],
47662306a36Sopenharmony_ci			   si->cursec[CURSEG_WARM_NODE],
47762306a36Sopenharmony_ci			   si->curzone[CURSEG_WARM_NODE],
47862306a36Sopenharmony_ci			   si->dirty_seg[CURSEG_WARM_NODE],
47962306a36Sopenharmony_ci			   si->full_seg[CURSEG_WARM_NODE],
48062306a36Sopenharmony_ci			   si->valid_blks[CURSEG_WARM_NODE]);
48162306a36Sopenharmony_ci		seq_printf(s, "  - Indir nodes: %8d %8d %8d %10u %10u %10u\n",
48262306a36Sopenharmony_ci			   si->curseg[CURSEG_COLD_NODE],
48362306a36Sopenharmony_ci			   si->cursec[CURSEG_COLD_NODE],
48462306a36Sopenharmony_ci			   si->curzone[CURSEG_COLD_NODE],
48562306a36Sopenharmony_ci			   si->dirty_seg[CURSEG_COLD_NODE],
48662306a36Sopenharmony_ci			   si->full_seg[CURSEG_COLD_NODE],
48762306a36Sopenharmony_ci			   si->valid_blks[CURSEG_COLD_NODE]);
48862306a36Sopenharmony_ci		seq_printf(s, "  - Pinned file: %8d %8d %8d\n",
48962306a36Sopenharmony_ci			   si->curseg[CURSEG_COLD_DATA_PINNED],
49062306a36Sopenharmony_ci			   si->cursec[CURSEG_COLD_DATA_PINNED],
49162306a36Sopenharmony_ci			   si->curzone[CURSEG_COLD_DATA_PINNED]);
49262306a36Sopenharmony_ci		seq_printf(s, "  - ATGC   data: %8d %8d %8d\n",
49362306a36Sopenharmony_ci			   si->curseg[CURSEG_ALL_DATA_ATGC],
49462306a36Sopenharmony_ci			   si->cursec[CURSEG_ALL_DATA_ATGC],
49562306a36Sopenharmony_ci			   si->curzone[CURSEG_ALL_DATA_ATGC]);
49662306a36Sopenharmony_ci		seq_printf(s, "\n  - Valid: %d\n  - Dirty: %d\n",
49762306a36Sopenharmony_ci			   si->main_area_segs - si->dirty_count -
49862306a36Sopenharmony_ci			   si->prefree_count - si->free_segs,
49962306a36Sopenharmony_ci			   si->dirty_count);
50062306a36Sopenharmony_ci		seq_printf(s, "  - Prefree: %d\n  - Free: %d (%d)\n\n",
50162306a36Sopenharmony_ci			   si->prefree_count, si->free_segs, si->free_secs);
50262306a36Sopenharmony_ci		seq_printf(s, "CP calls: %d (BG: %d)\n",
50362306a36Sopenharmony_ci			   si->cp_call_count[TOTAL_CALL],
50462306a36Sopenharmony_ci			   si->cp_call_count[BACKGROUND]);
50562306a36Sopenharmony_ci		seq_printf(s, "CP count: %d\n", si->cp_count);
50662306a36Sopenharmony_ci		seq_printf(s, "  - cp blocks : %u\n", si->meta_count[META_CP]);
50762306a36Sopenharmony_ci		seq_printf(s, "  - sit blocks : %u\n",
50862306a36Sopenharmony_ci				si->meta_count[META_SIT]);
50962306a36Sopenharmony_ci		seq_printf(s, "  - nat blocks : %u\n",
51062306a36Sopenharmony_ci				si->meta_count[META_NAT]);
51162306a36Sopenharmony_ci		seq_printf(s, "  - ssa blocks : %u\n",
51262306a36Sopenharmony_ci				si->meta_count[META_SSA]);
51362306a36Sopenharmony_ci		seq_puts(s, "CP merge:\n");
51462306a36Sopenharmony_ci		seq_printf(s, "  - Queued : %4d\n", si->nr_queued_ckpt);
51562306a36Sopenharmony_ci		seq_printf(s, "  - Issued : %4d\n", si->nr_issued_ckpt);
51662306a36Sopenharmony_ci		seq_printf(s, "  - Total : %4d\n", si->nr_total_ckpt);
51762306a36Sopenharmony_ci		seq_printf(s, "  - Cur time : %4d(ms)\n", si->cur_ckpt_time);
51862306a36Sopenharmony_ci		seq_printf(s, "  - Peak time : %4d(ms)\n", si->peak_ckpt_time);
51962306a36Sopenharmony_ci		seq_printf(s, "GC calls: %d (gc_thread: %d)\n",
52062306a36Sopenharmony_ci			   si->gc_call_count[BACKGROUND] +
52162306a36Sopenharmony_ci			   si->gc_call_count[FOREGROUND],
52262306a36Sopenharmony_ci			   si->gc_call_count[BACKGROUND]);
52362306a36Sopenharmony_ci		if (__is_large_section(sbi)) {
52462306a36Sopenharmony_ci			seq_printf(s, "  - data sections : %d (BG: %d)\n",
52562306a36Sopenharmony_ci					si->gc_secs[DATA][BG_GC] + si->gc_secs[DATA][FG_GC],
52662306a36Sopenharmony_ci					si->gc_secs[DATA][BG_GC]);
52762306a36Sopenharmony_ci			seq_printf(s, "  - node sections : %d (BG: %d)\n",
52862306a36Sopenharmony_ci					si->gc_secs[NODE][BG_GC] + si->gc_secs[NODE][FG_GC],
52962306a36Sopenharmony_ci					si->gc_secs[NODE][BG_GC]);
53062306a36Sopenharmony_ci		}
53162306a36Sopenharmony_ci		seq_printf(s, "  - data segments : %d (BG: %d)\n",
53262306a36Sopenharmony_ci				si->gc_segs[DATA][BG_GC] + si->gc_segs[DATA][FG_GC],
53362306a36Sopenharmony_ci				si->gc_segs[DATA][BG_GC]);
53462306a36Sopenharmony_ci		seq_printf(s, "  - node segments : %d (BG: %d)\n",
53562306a36Sopenharmony_ci				si->gc_segs[NODE][BG_GC] + si->gc_segs[NODE][FG_GC],
53662306a36Sopenharmony_ci				si->gc_segs[NODE][BG_GC]);
53762306a36Sopenharmony_ci		seq_puts(s, "  - Reclaimed segs :\n");
53862306a36Sopenharmony_ci		seq_printf(s, "    - Normal : %d\n", sbi->gc_reclaimed_segs[GC_NORMAL]);
53962306a36Sopenharmony_ci		seq_printf(s, "    - Idle CB : %d\n", sbi->gc_reclaimed_segs[GC_IDLE_CB]);
54062306a36Sopenharmony_ci		seq_printf(s, "    - Idle Greedy : %d\n",
54162306a36Sopenharmony_ci				sbi->gc_reclaimed_segs[GC_IDLE_GREEDY]);
54262306a36Sopenharmony_ci		seq_printf(s, "    - Idle AT : %d\n", sbi->gc_reclaimed_segs[GC_IDLE_AT]);
54362306a36Sopenharmony_ci		seq_printf(s, "    - Urgent High : %d\n",
54462306a36Sopenharmony_ci				sbi->gc_reclaimed_segs[GC_URGENT_HIGH]);
54562306a36Sopenharmony_ci		seq_printf(s, "    - Urgent Mid : %d\n", sbi->gc_reclaimed_segs[GC_URGENT_MID]);
54662306a36Sopenharmony_ci		seq_printf(s, "    - Urgent Low : %d\n", sbi->gc_reclaimed_segs[GC_URGENT_LOW]);
54762306a36Sopenharmony_ci		seq_printf(s, "Try to move %d blocks (BG: %d)\n", si->tot_blks,
54862306a36Sopenharmony_ci				si->bg_data_blks + si->bg_node_blks);
54962306a36Sopenharmony_ci		seq_printf(s, "  - data blocks : %d (%d)\n", si->data_blks,
55062306a36Sopenharmony_ci				si->bg_data_blks);
55162306a36Sopenharmony_ci		seq_printf(s, "  - node blocks : %d (%d)\n", si->node_blks,
55262306a36Sopenharmony_ci				si->bg_node_blks);
55362306a36Sopenharmony_ci		seq_printf(s, "BG skip : IO: %u, Other: %u\n",
55462306a36Sopenharmony_ci				si->io_skip_bggc, si->other_skip_bggc);
55562306a36Sopenharmony_ci		seq_puts(s, "\nExtent Cache (Read):\n");
55662306a36Sopenharmony_ci		seq_printf(s, "  - Hit Count: L1-1:%llu L1-2:%llu L2:%llu\n",
55762306a36Sopenharmony_ci				si->hit_largest, si->hit_cached[EX_READ],
55862306a36Sopenharmony_ci				si->hit_rbtree[EX_READ]);
55962306a36Sopenharmony_ci		seq_printf(s, "  - Hit Ratio: %llu%% (%llu / %llu)\n",
56062306a36Sopenharmony_ci				!si->total_ext[EX_READ] ? 0 :
56162306a36Sopenharmony_ci				div64_u64(si->hit_total[EX_READ] * 100,
56262306a36Sopenharmony_ci				si->total_ext[EX_READ]),
56362306a36Sopenharmony_ci				si->hit_total[EX_READ], si->total_ext[EX_READ]);
56462306a36Sopenharmony_ci		seq_printf(s, "  - Inner Struct Count: tree: %d(%d), node: %d\n",
56562306a36Sopenharmony_ci				si->ext_tree[EX_READ], si->zombie_tree[EX_READ],
56662306a36Sopenharmony_ci				si->ext_node[EX_READ]);
56762306a36Sopenharmony_ci		seq_puts(s, "\nExtent Cache (Block Age):\n");
56862306a36Sopenharmony_ci		seq_printf(s, "  - Allocated Data Blocks: %llu\n",
56962306a36Sopenharmony_ci				si->allocated_data_blocks);
57062306a36Sopenharmony_ci		seq_printf(s, "  - Hit Count: L1:%llu L2:%llu\n",
57162306a36Sopenharmony_ci				si->hit_cached[EX_BLOCK_AGE],
57262306a36Sopenharmony_ci				si->hit_rbtree[EX_BLOCK_AGE]);
57362306a36Sopenharmony_ci		seq_printf(s, "  - Hit Ratio: %llu%% (%llu / %llu)\n",
57462306a36Sopenharmony_ci				!si->total_ext[EX_BLOCK_AGE] ? 0 :
57562306a36Sopenharmony_ci				div64_u64(si->hit_total[EX_BLOCK_AGE] * 100,
57662306a36Sopenharmony_ci				si->total_ext[EX_BLOCK_AGE]),
57762306a36Sopenharmony_ci				si->hit_total[EX_BLOCK_AGE],
57862306a36Sopenharmony_ci				si->total_ext[EX_BLOCK_AGE]);
57962306a36Sopenharmony_ci		seq_printf(s, "  - Inner Struct Count: tree: %d(%d), node: %d\n",
58062306a36Sopenharmony_ci				si->ext_tree[EX_BLOCK_AGE],
58162306a36Sopenharmony_ci				si->zombie_tree[EX_BLOCK_AGE],
58262306a36Sopenharmony_ci				si->ext_node[EX_BLOCK_AGE]);
58362306a36Sopenharmony_ci		seq_puts(s, "\nBalancing F2FS Async:\n");
58462306a36Sopenharmony_ci		seq_printf(s, "  - DIO (R: %4d, W: %4d)\n",
58562306a36Sopenharmony_ci			   si->nr_dio_read, si->nr_dio_write);
58662306a36Sopenharmony_ci		seq_printf(s, "  - IO_R (Data: %4d, Node: %4d, Meta: %4d\n",
58762306a36Sopenharmony_ci			   si->nr_rd_data, si->nr_rd_node, si->nr_rd_meta);
58862306a36Sopenharmony_ci		seq_printf(s, "  - IO_W (CP: %4d, Data: %4d, Flush: (%4d %4d %4d), ",
58962306a36Sopenharmony_ci			   si->nr_wb_cp_data, si->nr_wb_data,
59062306a36Sopenharmony_ci			   si->nr_flushing, si->nr_flushed,
59162306a36Sopenharmony_ci			   si->flush_list_empty);
59262306a36Sopenharmony_ci		seq_printf(s, "Discard: (%4d %4d)) cmd: %4d undiscard:%4u\n",
59362306a36Sopenharmony_ci			   si->nr_discarding, si->nr_discarded,
59462306a36Sopenharmony_ci			   si->nr_discard_cmd, si->undiscard_blks);
59562306a36Sopenharmony_ci		seq_printf(s, "  - atomic IO: %4d (Max. %4d)\n",
59662306a36Sopenharmony_ci			   si->aw_cnt, si->max_aw_cnt);
59762306a36Sopenharmony_ci		seq_printf(s, "  - compress: %4d, hit:%8d\n", si->compress_pages, si->compress_page_hit);
59862306a36Sopenharmony_ci		seq_printf(s, "  - nodes: %4d in %4d\n",
59962306a36Sopenharmony_ci			   si->ndirty_node, si->node_pages);
60062306a36Sopenharmony_ci		seq_printf(s, "  - dents: %4d in dirs:%4d (%4d)\n",
60162306a36Sopenharmony_ci			   si->ndirty_dent, si->ndirty_dirs, si->ndirty_all);
60262306a36Sopenharmony_ci		seq_printf(s, "  - datas: %4d in files:%4d\n",
60362306a36Sopenharmony_ci			   si->ndirty_data, si->ndirty_files);
60462306a36Sopenharmony_ci		seq_printf(s, "  - quota datas: %4d in quota files:%4d\n",
60562306a36Sopenharmony_ci			   si->ndirty_qdata, si->nquota_files);
60662306a36Sopenharmony_ci		seq_printf(s, "  - meta: %4d in %4d\n",
60762306a36Sopenharmony_ci			   si->ndirty_meta, si->meta_pages);
60862306a36Sopenharmony_ci		seq_printf(s, "  - imeta: %4d\n",
60962306a36Sopenharmony_ci			   si->ndirty_imeta);
61062306a36Sopenharmony_ci		seq_printf(s, "  - fsync mark: %4lld\n",
61162306a36Sopenharmony_ci			   percpu_counter_sum_positive(
61262306a36Sopenharmony_ci					&sbi->rf_node_block_count));
61362306a36Sopenharmony_ci		seq_printf(s, "  - NATs: %9d/%9d\n  - SITs: %9d/%9d\n",
61462306a36Sopenharmony_ci			   si->dirty_nats, si->nats, si->dirty_sits, si->sits);
61562306a36Sopenharmony_ci		seq_printf(s, "  - free_nids: %9d/%9d\n  - alloc_nids: %9d\n",
61662306a36Sopenharmony_ci			   si->free_nids, si->avail_nids, si->alloc_nids);
61762306a36Sopenharmony_ci		seq_puts(s, "\nDistribution of User Blocks:");
61862306a36Sopenharmony_ci		seq_puts(s, " [ valid | invalid | free ]\n");
61962306a36Sopenharmony_ci		seq_puts(s, "  [");
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ci		for (j = 0; j < si->util_valid; j++)
62262306a36Sopenharmony_ci			seq_putc(s, '-');
62362306a36Sopenharmony_ci		seq_putc(s, '|');
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_ci		for (j = 0; j < si->util_invalid; j++)
62662306a36Sopenharmony_ci			seq_putc(s, '-');
62762306a36Sopenharmony_ci		seq_putc(s, '|');
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci		for (j = 0; j < si->util_free; j++)
63062306a36Sopenharmony_ci			seq_putc(s, '-');
63162306a36Sopenharmony_ci		seq_puts(s, "]\n\n");
63262306a36Sopenharmony_ci		seq_printf(s, "IPU: %u blocks\n", si->inplace_count);
63362306a36Sopenharmony_ci		seq_printf(s, "SSR: %u blocks in %u segments\n",
63462306a36Sopenharmony_ci			   si->block_count[SSR], si->segment_count[SSR]);
63562306a36Sopenharmony_ci		seq_printf(s, "LFS: %u blocks in %u segments\n",
63662306a36Sopenharmony_ci			   si->block_count[LFS], si->segment_count[LFS]);
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci		/* segment usage info */
63962306a36Sopenharmony_ci		f2fs_update_sit_info(sbi);
64062306a36Sopenharmony_ci		seq_printf(s, "\nBDF: %u, avg. vblocks: %u\n",
64162306a36Sopenharmony_ci			   si->bimodal, si->avg_vblocks);
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci		/* memory footprint */
64462306a36Sopenharmony_ci		update_mem_info(sbi);
64562306a36Sopenharmony_ci		seq_printf(s, "\nMemory: %llu KB\n",
64662306a36Sopenharmony_ci			(si->base_mem + si->cache_mem + si->page_mem) >> 10);
64762306a36Sopenharmony_ci		seq_printf(s, "  - static: %llu KB\n",
64862306a36Sopenharmony_ci				si->base_mem >> 10);
64962306a36Sopenharmony_ci		seq_printf(s, "  - cached all: %llu KB\n",
65062306a36Sopenharmony_ci				si->cache_mem >> 10);
65162306a36Sopenharmony_ci		seq_printf(s, "  - read extent cache: %llu KB\n",
65262306a36Sopenharmony_ci				si->ext_mem[EX_READ] >> 10);
65362306a36Sopenharmony_ci		seq_printf(s, "  - block age extent cache: %llu KB\n",
65462306a36Sopenharmony_ci				si->ext_mem[EX_BLOCK_AGE] >> 10);
65562306a36Sopenharmony_ci		seq_printf(s, "  - paged : %llu KB\n",
65662306a36Sopenharmony_ci				si->page_mem >> 10);
65762306a36Sopenharmony_ci	}
65862306a36Sopenharmony_ci	raw_spin_unlock_irqrestore(&f2fs_stat_lock, flags);
65962306a36Sopenharmony_ci	return 0;
66062306a36Sopenharmony_ci}
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(stat);
66362306a36Sopenharmony_ci#endif
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ciint f2fs_build_stats(struct f2fs_sb_info *sbi)
66662306a36Sopenharmony_ci{
66762306a36Sopenharmony_ci	struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
66862306a36Sopenharmony_ci	struct f2fs_stat_info *si;
66962306a36Sopenharmony_ci	unsigned long flags;
67062306a36Sopenharmony_ci	int i;
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	si = f2fs_kzalloc(sbi, sizeof(struct f2fs_stat_info), GFP_KERNEL);
67362306a36Sopenharmony_ci	if (!si)
67462306a36Sopenharmony_ci		return -ENOMEM;
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	si->all_area_segs = le32_to_cpu(raw_super->segment_count);
67762306a36Sopenharmony_ci	si->sit_area_segs = le32_to_cpu(raw_super->segment_count_sit);
67862306a36Sopenharmony_ci	si->nat_area_segs = le32_to_cpu(raw_super->segment_count_nat);
67962306a36Sopenharmony_ci	si->ssa_area_segs = le32_to_cpu(raw_super->segment_count_ssa);
68062306a36Sopenharmony_ci	si->main_area_segs = le32_to_cpu(raw_super->segment_count_main);
68162306a36Sopenharmony_ci	si->main_area_sections = le32_to_cpu(raw_super->section_count);
68262306a36Sopenharmony_ci	si->main_area_zones = si->main_area_sections /
68362306a36Sopenharmony_ci				le32_to_cpu(raw_super->secs_per_zone);
68462306a36Sopenharmony_ci	si->sbi = sbi;
68562306a36Sopenharmony_ci	sbi->stat_info = si;
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	/* general extent cache stats */
68862306a36Sopenharmony_ci	for (i = 0; i < NR_EXTENT_CACHES; i++) {
68962306a36Sopenharmony_ci		atomic64_set(&sbi->total_hit_ext[i], 0);
69062306a36Sopenharmony_ci		atomic64_set(&sbi->read_hit_rbtree[i], 0);
69162306a36Sopenharmony_ci		atomic64_set(&sbi->read_hit_cached[i], 0);
69262306a36Sopenharmony_ci	}
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci	/* read extent_cache only */
69562306a36Sopenharmony_ci	atomic64_set(&sbi->read_hit_largest, 0);
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci	atomic_set(&sbi->inline_xattr, 0);
69862306a36Sopenharmony_ci	atomic_set(&sbi->inline_inode, 0);
69962306a36Sopenharmony_ci	atomic_set(&sbi->inline_dir, 0);
70062306a36Sopenharmony_ci	atomic_set(&sbi->compr_inode, 0);
70162306a36Sopenharmony_ci	atomic64_set(&sbi->compr_blocks, 0);
70262306a36Sopenharmony_ci	atomic_set(&sbi->swapfile_inode, 0);
70362306a36Sopenharmony_ci	atomic_set(&sbi->atomic_files, 0);
70462306a36Sopenharmony_ci	atomic_set(&sbi->inplace_count, 0);
70562306a36Sopenharmony_ci	for (i = META_CP; i < META_MAX; i++)
70662306a36Sopenharmony_ci		atomic_set(&sbi->meta_count[i], 0);
70762306a36Sopenharmony_ci	for (i = 0; i < MAX_CALL_TYPE; i++)
70862306a36Sopenharmony_ci		atomic_set(&sbi->cp_call_count[i], 0);
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci	atomic_set(&sbi->max_aw_cnt, 0);
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_ci	raw_spin_lock_irqsave(&f2fs_stat_lock, flags);
71362306a36Sopenharmony_ci	list_add_tail(&si->stat_list, &f2fs_stat_list);
71462306a36Sopenharmony_ci	raw_spin_unlock_irqrestore(&f2fs_stat_lock, flags);
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci	return 0;
71762306a36Sopenharmony_ci}
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_civoid f2fs_destroy_stats(struct f2fs_sb_info *sbi)
72062306a36Sopenharmony_ci{
72162306a36Sopenharmony_ci	struct f2fs_stat_info *si = F2FS_STAT(sbi);
72262306a36Sopenharmony_ci	unsigned long flags;
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci	raw_spin_lock_irqsave(&f2fs_stat_lock, flags);
72562306a36Sopenharmony_ci	list_del(&si->stat_list);
72662306a36Sopenharmony_ci	raw_spin_unlock_irqrestore(&f2fs_stat_lock, flags);
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci	kfree(si);
72962306a36Sopenharmony_ci}
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_civoid __init f2fs_create_root_stats(void)
73262306a36Sopenharmony_ci{
73362306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
73462306a36Sopenharmony_ci	f2fs_debugfs_root = debugfs_create_dir("f2fs", NULL);
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_ci	debugfs_create_file("status", 0444, f2fs_debugfs_root, NULL,
73762306a36Sopenharmony_ci			    &stat_fops);
73862306a36Sopenharmony_ci#endif
73962306a36Sopenharmony_ci}
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_civoid f2fs_destroy_root_stats(void)
74262306a36Sopenharmony_ci{
74362306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
74462306a36Sopenharmony_ci	debugfs_remove_recursive(f2fs_debugfs_root);
74562306a36Sopenharmony_ci	f2fs_debugfs_root = NULL;
74662306a36Sopenharmony_ci#endif
74762306a36Sopenharmony_ci}
748