debug.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * f2fs debugging statistics
  4. *
  5. * Copyright (c) 2012 Samsung Electronics Co., Ltd.
  6. * http://www.samsung.com/
  7. * Copyright (c) 2012 Linux Foundation
  8. * Copyright (c) 2012 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  9. */
  10. #include <linux/fs.h>
  11. #include <linux/backing-dev.h>
  12. #include <linux/f2fs_fs.h>
  13. #include <linux/blkdev.h>
  14. #include <linux/debugfs.h>
  15. #include <linux/seq_file.h>
  16. #include "f2fs.h"
  17. #include "node.h"
  18. #include "segment.h"
  19. #include "gc.h"
  20. static LIST_HEAD(f2fs_stat_list);
  21. static DEFINE_SPINLOCK(f2fs_stat_lock);
  22. #ifdef CONFIG_DEBUG_FS
  23. static struct dentry *f2fs_debugfs_root;
  24. #endif
  25. /*
  26. * This function calculates BDF of every segments
  27. */
  28. void f2fs_update_sit_info(struct f2fs_sb_info *sbi)
  29. {
  30. struct f2fs_stat_info *si = F2FS_STAT(sbi);
  31. unsigned long long blks_per_sec, hblks_per_sec, total_vblocks;
  32. unsigned long long bimodal, dist;
  33. unsigned int segno, vblocks;
  34. int ndirty = 0;
  35. bimodal = 0;
  36. total_vblocks = 0;
  37. blks_per_sec = CAP_BLKS_PER_SEC(sbi);
  38. hblks_per_sec = blks_per_sec / 2;
  39. for (segno = 0; segno < MAIN_SEGS(sbi); segno += SEGS_PER_SEC(sbi)) {
  40. vblocks = get_valid_blocks(sbi, segno, true);
  41. dist = abs(vblocks - hblks_per_sec);
  42. bimodal += dist * dist;
  43. if (vblocks > 0 && vblocks < blks_per_sec) {
  44. total_vblocks += vblocks;
  45. ndirty++;
  46. }
  47. }
  48. dist = div_u64(MAIN_SECS(sbi) * hblks_per_sec * hblks_per_sec, 100);
  49. si->bimodal = div64_u64(bimodal, dist);
  50. if (si->dirty_count)
  51. si->avg_vblocks = div_u64(total_vblocks, ndirty);
  52. else
  53. si->avg_vblocks = 0;
  54. }
  55. #ifdef CONFIG_DEBUG_FS
  56. static void update_multidevice_stats(struct f2fs_sb_info *sbi)
  57. {
  58. struct f2fs_stat_info *si = F2FS_STAT(sbi);
  59. struct f2fs_dev_stats *dev_stats = si->dev_stats;
  60. int i, j;
  61. if (!f2fs_is_multi_device(sbi))
  62. return;
  63. memset(dev_stats, 0, sizeof(struct f2fs_dev_stats) * sbi->s_ndevs);
  64. for (i = 0; i < sbi->s_ndevs; i++) {
  65. unsigned int start_segno, end_segno;
  66. block_t start_blk, end_blk;
  67. if (i == 0) {
  68. start_blk = MAIN_BLKADDR(sbi);
  69. end_blk = FDEV(i).end_blk + 1 - SEG0_BLKADDR(sbi);
  70. } else {
  71. start_blk = FDEV(i).start_blk;
  72. end_blk = FDEV(i).end_blk + 1;
  73. }
  74. start_segno = GET_SEGNO(sbi, start_blk);
  75. end_segno = GET_SEGNO(sbi, end_blk);
  76. for (j = start_segno; j < end_segno; j++) {
  77. unsigned int seg_blks, sec_blks;
  78. seg_blks = get_seg_entry(sbi, j)->valid_blocks;
  79. /* update segment stats */
  80. if (is_curseg(sbi, j))
  81. dev_stats[i].devstats[0][DEVSTAT_INUSE]++;
  82. else if (seg_blks == BLKS_PER_SEG(sbi))
  83. dev_stats[i].devstats[0][DEVSTAT_FULL]++;
  84. else if (seg_blks != 0)
  85. dev_stats[i].devstats[0][DEVSTAT_DIRTY]++;
  86. else if (!test_bit(j, FREE_I(sbi)->free_segmap))
  87. dev_stats[i].devstats[0][DEVSTAT_FREE]++;
  88. else
  89. dev_stats[i].devstats[0][DEVSTAT_PREFREE]++;
  90. if (!__is_large_section(sbi) ||
  91. (j % SEGS_PER_SEC(sbi)) != 0)
  92. continue;
  93. sec_blks = get_sec_entry(sbi, j)->valid_blocks;
  94. /* update section stats */
  95. if (is_cursec(sbi, GET_SEC_FROM_SEG(sbi, j)))
  96. dev_stats[i].devstats[1][DEVSTAT_INUSE]++;
  97. else if (sec_blks == BLKS_PER_SEC(sbi))
  98. dev_stats[i].devstats[1][DEVSTAT_FULL]++;
  99. else if (sec_blks != 0)
  100. dev_stats[i].devstats[1][DEVSTAT_DIRTY]++;
  101. else if (!test_bit(GET_SEC_FROM_SEG(sbi, j),
  102. FREE_I(sbi)->free_secmap))
  103. dev_stats[i].devstats[1][DEVSTAT_FREE]++;
  104. else
  105. dev_stats[i].devstats[1][DEVSTAT_PREFREE]++;
  106. }
  107. }
  108. }
  109. static void update_general_status(struct f2fs_sb_info *sbi)
  110. {
  111. struct f2fs_stat_info *si = F2FS_STAT(sbi);
  112. struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
  113. int i;
  114. /* these will be changed if online resize is done */
  115. si->main_area_segs = le32_to_cpu(raw_super->segment_count_main);
  116. si->main_area_sections = le32_to_cpu(raw_super->section_count);
  117. si->main_area_zones = si->main_area_sections /
  118. le32_to_cpu(raw_super->secs_per_zone);
  119. /* general extent cache stats */
  120. for (i = 0; i < NR_EXTENT_CACHES; i++) {
  121. struct extent_tree_info *eti = &sbi->extent_tree[i];
  122. si->hit_cached[i] = atomic64_read(&sbi->read_hit_cached[i]);
  123. si->hit_rbtree[i] = atomic64_read(&sbi->read_hit_rbtree[i]);
  124. si->total_ext[i] = atomic64_read(&sbi->total_hit_ext[i]);
  125. si->hit_total[i] = si->hit_cached[i] + si->hit_rbtree[i];
  126. si->ext_tree[i] = atomic_read(&eti->total_ext_tree);
  127. si->zombie_tree[i] = atomic_read(&eti->total_zombie_tree);
  128. si->ext_node[i] = atomic_read(&eti->total_ext_node);
  129. }
  130. /* read extent_cache only */
  131. si->hit_largest = atomic64_read(&sbi->read_hit_largest);
  132. si->hit_total[EX_READ] += si->hit_largest;
  133. /* block age extent_cache only */
  134. si->allocated_data_blocks = atomic64_read(&sbi->allocated_data_blocks);
  135. /* validation check of the segment numbers */
  136. si->ndirty_node = get_pages(sbi, F2FS_DIRTY_NODES);
  137. si->ndirty_dent = get_pages(sbi, F2FS_DIRTY_DENTS);
  138. si->ndirty_meta = get_pages(sbi, F2FS_DIRTY_META);
  139. si->ndirty_data = get_pages(sbi, F2FS_DIRTY_DATA);
  140. si->ndirty_qdata = get_pages(sbi, F2FS_DIRTY_QDATA);
  141. si->ndirty_imeta = get_pages(sbi, F2FS_DIRTY_IMETA);
  142. si->ndirty_dirs = sbi->ndirty_inode[DIR_INODE];
  143. si->ndirty_files = sbi->ndirty_inode[FILE_INODE];
  144. si->ndonate_files = sbi->donate_files;
  145. si->nquota_files = sbi->nquota_files;
  146. si->ndirty_all = sbi->ndirty_inode[DIRTY_META];
  147. si->aw_cnt = atomic_read(&sbi->atomic_files);
  148. si->max_aw_cnt = atomic_read(&sbi->max_aw_cnt);
  149. si->nr_dio_read = get_pages(sbi, F2FS_DIO_READ);
  150. si->nr_dio_write = get_pages(sbi, F2FS_DIO_WRITE);
  151. si->nr_wb_cp_data = get_pages(sbi, F2FS_WB_CP_DATA);
  152. si->nr_wb_data = get_pages(sbi, F2FS_WB_DATA);
  153. si->nr_rd_data = get_pages(sbi, F2FS_RD_DATA);
  154. si->nr_rd_node = get_pages(sbi, F2FS_RD_NODE);
  155. si->nr_rd_meta = get_pages(sbi, F2FS_RD_META);
  156. if (SM_I(sbi)->fcc_info) {
  157. si->nr_flushed =
  158. atomic_read(&SM_I(sbi)->fcc_info->issued_flush);
  159. si->nr_flushing =
  160. atomic_read(&SM_I(sbi)->fcc_info->queued_flush);
  161. si->flush_list_empty =
  162. llist_empty(&SM_I(sbi)->fcc_info->issue_list);
  163. }
  164. if (SM_I(sbi)->dcc_info) {
  165. si->nr_discarded =
  166. atomic_read(&SM_I(sbi)->dcc_info->issued_discard);
  167. si->nr_discarding =
  168. atomic_read(&SM_I(sbi)->dcc_info->queued_discard);
  169. si->nr_discard_cmd =
  170. atomic_read(&SM_I(sbi)->dcc_info->discard_cmd_cnt);
  171. si->undiscard_blks = SM_I(sbi)->dcc_info->undiscard_blks;
  172. }
  173. si->nr_issued_ckpt = atomic_read(&sbi->cprc_info.issued_ckpt);
  174. si->nr_total_ckpt = atomic_read(&sbi->cprc_info.total_ckpt);
  175. si->nr_queued_ckpt = atomic_read(&sbi->cprc_info.queued_ckpt);
  176. spin_lock(&sbi->cprc_info.stat_lock);
  177. si->cur_ckpt_time = sbi->cprc_info.cur_time;
  178. si->peak_ckpt_time = sbi->cprc_info.peak_time;
  179. spin_unlock(&sbi->cprc_info.stat_lock);
  180. si->total_count = BLKS_TO_SEGS(sbi, (int)sbi->user_block_count);
  181. si->rsvd_segs = reserved_segments(sbi);
  182. si->overp_segs = overprovision_segments(sbi);
  183. si->valid_count = valid_user_blocks(sbi);
  184. si->discard_blks = discard_blocks(sbi);
  185. si->valid_node_count = valid_node_count(sbi);
  186. si->valid_inode_count = valid_inode_count(sbi);
  187. si->inline_xattr = atomic_read(&sbi->inline_xattr);
  188. si->inline_inode = atomic_read(&sbi->inline_inode);
  189. si->inline_dir = atomic_read(&sbi->inline_dir);
  190. si->compr_inode = atomic_read(&sbi->compr_inode);
  191. si->swapfile_inode = atomic_read(&sbi->swapfile_inode);
  192. si->compr_blocks = atomic64_read(&sbi->compr_blocks);
  193. si->append = sbi->im[APPEND_INO].ino_num;
  194. si->update = sbi->im[UPDATE_INO].ino_num;
  195. si->orphans = sbi->im[ORPHAN_INO].ino_num;
  196. si->utilization = utilization(sbi);
  197. si->free_segs = free_segments(sbi);
  198. si->free_secs = free_sections(sbi);
  199. si->prefree_count = prefree_segments(sbi);
  200. si->dirty_count = dirty_segments(sbi);
  201. if (sbi->node_inode)
  202. si->node_pages = NODE_MAPPING(sbi)->nrpages;
  203. if (sbi->meta_inode)
  204. si->meta_pages = META_MAPPING(sbi)->nrpages;
  205. #ifdef CONFIG_F2FS_FS_COMPRESSION
  206. if (sbi->compress_inode) {
  207. si->compress_pages = COMPRESS_MAPPING(sbi)->nrpages;
  208. si->compress_page_hit = atomic_read(&sbi->compress_page_hit);
  209. }
  210. #endif
  211. si->nats = NM_I(sbi)->nat_cnt[TOTAL_NAT];
  212. si->dirty_nats = NM_I(sbi)->nat_cnt[DIRTY_NAT];
  213. si->sits = MAIN_SEGS(sbi);
  214. si->dirty_sits = SIT_I(sbi)->dirty_sentries;
  215. si->free_nids = NM_I(sbi)->nid_cnt[FREE_NID];
  216. si->avail_nids = NM_I(sbi)->available_nids;
  217. si->alloc_nids = NM_I(sbi)->nid_cnt[PREALLOC_NID];
  218. si->io_skip_bggc = sbi->io_skip_bggc;
  219. si->other_skip_bggc = sbi->other_skip_bggc;
  220. si->util_free = (int)(BLKS_TO_SEGS(sbi, free_user_blocks(sbi)))
  221. * 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
  222. / 2;
  223. si->util_valid = (int)(BLKS_TO_SEGS(sbi, written_block_count(sbi)))
  224. * 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
  225. / 2;
  226. si->util_invalid = 50 - si->util_free - si->util_valid;
  227. for (i = CURSEG_HOT_DATA; i < NO_CHECK_TYPE; i++) {
  228. struct curseg_info *curseg = CURSEG_I(sbi, i);
  229. si->blkoff[i] = curseg->next_blkoff;
  230. si->curseg[i] = curseg->segno;
  231. si->cursec[i] = GET_SEC_FROM_SEG(sbi, curseg->segno);
  232. si->curzone[i] = GET_ZONE_FROM_SEC(sbi, si->cursec[i]);
  233. }
  234. for (i = META_CP; i < META_MAX; i++)
  235. si->meta_count[i] = atomic_read(&sbi->meta_count[i]);
  236. for (i = 0; i < NO_CHECK_TYPE; i++) {
  237. si->dirty_seg[i] = 0;
  238. si->full_seg[i] = 0;
  239. si->valid_blks[i] = 0;
  240. }
  241. for (i = 0; i < MAIN_SEGS(sbi); i++) {
  242. int blks = get_seg_entry(sbi, i)->valid_blocks;
  243. int type = get_seg_entry(sbi, i)->type;
  244. if (!blks)
  245. continue;
  246. if (blks == BLKS_PER_SEG(sbi))
  247. si->full_seg[type]++;
  248. else
  249. si->dirty_seg[type]++;
  250. si->valid_blks[type] += blks;
  251. }
  252. update_multidevice_stats(sbi);
  253. for (i = 0; i < MAX_CALL_TYPE; i++)
  254. si->cp_call_count[i] = atomic_read(&sbi->cp_call_count[i]);
  255. for (i = 0; i < 2; i++) {
  256. si->segment_count[i] = sbi->segment_count[i];
  257. si->block_count[i] = sbi->block_count[i];
  258. }
  259. si->inplace_count = atomic_read(&sbi->inplace_count);
  260. }
  261. /*
  262. * This function calculates memory footprint.
  263. */
  264. static void update_mem_info(struct f2fs_sb_info *sbi)
  265. {
  266. struct f2fs_stat_info *si = F2FS_STAT(sbi);
  267. int i;
  268. if (si->base_mem)
  269. goto get_cache;
  270. /* build stat */
  271. si->base_mem = sizeof(struct f2fs_stat_info);
  272. /* build superblock */
  273. si->base_mem += sizeof(struct f2fs_sb_info) + sbi->sb->s_blocksize;
  274. si->base_mem += 2 * sizeof(struct f2fs_inode_info);
  275. si->base_mem += sizeof(*sbi->ckpt);
  276. /* build sm */
  277. si->base_mem += sizeof(struct f2fs_sm_info);
  278. /* build sit */
  279. si->base_mem += sizeof(struct sit_info);
  280. si->base_mem += MAIN_SEGS(sbi) * sizeof(struct seg_entry);
  281. si->base_mem += f2fs_bitmap_size(MAIN_SEGS(sbi));
  282. si->base_mem += 2 * SIT_VBLOCK_MAP_SIZE * MAIN_SEGS(sbi);
  283. si->base_mem += SIT_VBLOCK_MAP_SIZE * MAIN_SEGS(sbi);
  284. si->base_mem += SIT_VBLOCK_MAP_SIZE;
  285. if (__is_large_section(sbi))
  286. si->base_mem += MAIN_SECS(sbi) * sizeof(struct sec_entry);
  287. si->base_mem += __bitmap_size(sbi, SIT_BITMAP);
  288. /* build free segmap */
  289. si->base_mem += sizeof(struct free_segmap_info);
  290. si->base_mem += f2fs_bitmap_size(MAIN_SEGS(sbi));
  291. si->base_mem += f2fs_bitmap_size(MAIN_SECS(sbi));
  292. /* build curseg */
  293. si->base_mem += sizeof(struct curseg_info) * NR_CURSEG_TYPE;
  294. si->base_mem += PAGE_SIZE * NR_CURSEG_TYPE;
  295. /* build dirty segmap */
  296. si->base_mem += sizeof(struct dirty_seglist_info);
  297. si->base_mem += NR_DIRTY_TYPE * f2fs_bitmap_size(MAIN_SEGS(sbi));
  298. si->base_mem += f2fs_bitmap_size(MAIN_SECS(sbi));
  299. /* build nm */
  300. si->base_mem += sizeof(struct f2fs_nm_info);
  301. si->base_mem += __bitmap_size(sbi, NAT_BITMAP);
  302. si->base_mem += F2FS_BLK_TO_BYTES(NM_I(sbi)->nat_bits_blocks);
  303. si->base_mem += NM_I(sbi)->nat_blocks *
  304. f2fs_bitmap_size(NAT_ENTRY_PER_BLOCK);
  305. si->base_mem += NM_I(sbi)->nat_blocks / 8;
  306. si->base_mem += NM_I(sbi)->nat_blocks * sizeof(unsigned short);
  307. get_cache:
  308. si->cache_mem = 0;
  309. /* build gc */
  310. if (sbi->gc_thread)
  311. si->cache_mem += sizeof(struct f2fs_gc_kthread);
  312. /* build merge flush thread */
  313. if (SM_I(sbi)->fcc_info)
  314. si->cache_mem += sizeof(struct flush_cmd_control);
  315. if (SM_I(sbi)->dcc_info) {
  316. si->cache_mem += sizeof(struct discard_cmd_control);
  317. si->cache_mem += sizeof(struct discard_cmd) *
  318. atomic_read(&SM_I(sbi)->dcc_info->discard_cmd_cnt);
  319. }
  320. /* free nids */
  321. si->cache_mem += (NM_I(sbi)->nid_cnt[FREE_NID] +
  322. NM_I(sbi)->nid_cnt[PREALLOC_NID]) *
  323. sizeof(struct free_nid);
  324. si->cache_mem += NM_I(sbi)->nat_cnt[TOTAL_NAT] *
  325. sizeof(struct nat_entry);
  326. si->cache_mem += NM_I(sbi)->nat_cnt[DIRTY_NAT] *
  327. sizeof(struct nat_entry_set);
  328. for (i = 0; i < MAX_INO_ENTRY; i++)
  329. si->cache_mem += sbi->im[i].ino_num * sizeof(struct ino_entry);
  330. for (i = 0; i < NR_EXTENT_CACHES; i++) {
  331. struct extent_tree_info *eti = &sbi->extent_tree[i];
  332. si->ext_mem[i] = atomic_read(&eti->total_ext_tree) *
  333. sizeof(struct extent_tree);
  334. si->ext_mem[i] += atomic_read(&eti->total_ext_node) *
  335. sizeof(struct extent_node);
  336. si->cache_mem += si->ext_mem[i];
  337. }
  338. si->page_mem = 0;
  339. if (sbi->node_inode) {
  340. unsigned long npages = NODE_MAPPING(sbi)->nrpages;
  341. si->page_mem += (unsigned long long)npages << PAGE_SHIFT;
  342. }
  343. if (sbi->meta_inode) {
  344. unsigned long npages = META_MAPPING(sbi)->nrpages;
  345. si->page_mem += (unsigned long long)npages << PAGE_SHIFT;
  346. }
  347. #ifdef CONFIG_F2FS_FS_COMPRESSION
  348. if (sbi->compress_inode) {
  349. unsigned long npages = COMPRESS_MAPPING(sbi)->nrpages;
  350. si->page_mem += (unsigned long long)npages << PAGE_SHIFT;
  351. }
  352. #endif
  353. }
  354. static const char *s_flag[MAX_SBI_FLAG] = {
  355. [SBI_IS_DIRTY] = "fs_dirty",
  356. [SBI_IS_CLOSE] = "closing",
  357. [SBI_NEED_FSCK] = "need_fsck",
  358. [SBI_POR_DOING] = "recovering",
  359. [SBI_NEED_SB_WRITE] = "sb_dirty",
  360. [SBI_NEED_CP] = "need_cp",
  361. [SBI_IS_SHUTDOWN] = "shutdown",
  362. [SBI_IS_RECOVERED] = "recovered",
  363. [SBI_CP_DISABLED] = "cp_disabled",
  364. [SBI_CP_DISABLED_QUICK] = "cp_disabled_quick",
  365. [SBI_QUOTA_NEED_FLUSH] = "quota_need_flush",
  366. [SBI_QUOTA_SKIP_FLUSH] = "quota_skip_flush",
  367. [SBI_QUOTA_NEED_REPAIR] = "quota_need_repair",
  368. [SBI_IS_RESIZEFS] = "resizefs",
  369. [SBI_IS_FREEZING] = "freezefs",
  370. [SBI_IS_WRITABLE] = "writable",
  371. [SBI_ENABLE_CHECKPOINT] = "enable_checkpoint",
  372. };
  373. static const char *ipu_mode_names[F2FS_IPU_MAX] = {
  374. [F2FS_IPU_FORCE] = "FORCE",
  375. [F2FS_IPU_SSR] = "SSR",
  376. [F2FS_IPU_UTIL] = "UTIL",
  377. [F2FS_IPU_SSR_UTIL] = "SSR_UTIL",
  378. [F2FS_IPU_FSYNC] = "FSYNC",
  379. [F2FS_IPU_ASYNC] = "ASYNC",
  380. [F2FS_IPU_NOCACHE] = "NOCACHE",
  381. [F2FS_IPU_HONOR_OPU_WRITE] = "HONOR_OPU_WRITE",
  382. };
  383. static int stat_show(struct seq_file *s, void *v)
  384. {
  385. struct f2fs_stat_info *si;
  386. int i = 0, j = 0;
  387. spin_lock(&f2fs_stat_lock);
  388. list_for_each_entry(si, &f2fs_stat_list, stat_list) {
  389. struct f2fs_sb_info *sbi = si->sbi;
  390. update_general_status(sbi);
  391. seq_printf(s, "\n=====[ partition info(%pg). #%d, %s, CP: %s]=====\n",
  392. sbi->sb->s_bdev, i++,
  393. f2fs_readonly(sbi->sb) ? "RO" : "RW",
  394. is_set_ckpt_flags(sbi, CP_DISABLED_FLAG) ?
  395. "Disabled" : (f2fs_cp_error(sbi) ? "Error" : "Good"));
  396. if (sbi->s_flag) {
  397. seq_puts(s, "[SBI:");
  398. for_each_set_bit(j, &sbi->s_flag, MAX_SBI_FLAG)
  399. seq_printf(s, " %s", s_flag[j]);
  400. seq_puts(s, "]\n");
  401. }
  402. seq_printf(s, "[SB: 1] [CP: 2] [SIT: %d] [NAT: %d] ",
  403. si->sit_area_segs, si->nat_area_segs);
  404. seq_printf(s, "[SSA: %d] [MAIN: %d",
  405. si->ssa_area_segs, si->main_area_segs);
  406. seq_printf(s, "(OverProv:%d Resv:%d)]\n\n",
  407. si->overp_segs, si->rsvd_segs);
  408. seq_printf(s, "Current Time Sec: %llu / Mounted Time Sec: %llu\n\n",
  409. ktime_get_boottime_seconds(),
  410. SIT_I(sbi)->mounted_time);
  411. seq_puts(s, "Policy:\n");
  412. seq_puts(s, " - IPU: [");
  413. if (IS_F2FS_IPU_DISABLE(sbi)) {
  414. seq_puts(s, " DISABLE");
  415. } else {
  416. unsigned long policy = SM_I(sbi)->ipu_policy;
  417. for_each_set_bit(j, &policy, F2FS_IPU_MAX)
  418. seq_printf(s, " %s", ipu_mode_names[j]);
  419. }
  420. seq_puts(s, " ]\n\n");
  421. if (test_opt(sbi, DISCARD))
  422. seq_printf(s, "Utilization: %u%% (%u valid blocks, %u discard blocks)\n",
  423. si->utilization, si->valid_count, si->discard_blks);
  424. else
  425. seq_printf(s, "Utilization: %u%% (%u valid blocks)\n",
  426. si->utilization, si->valid_count);
  427. seq_printf(s, " - Node: %u (Inode: %u, ",
  428. si->valid_node_count, si->valid_inode_count);
  429. seq_printf(s, "Other: %u)\n - Data: %u\n",
  430. si->valid_node_count - si->valid_inode_count,
  431. si->valid_count - si->valid_node_count);
  432. seq_printf(s, " - Inline_xattr Inode: %u\n",
  433. si->inline_xattr);
  434. seq_printf(s, " - Inline_data Inode: %u\n",
  435. si->inline_inode);
  436. seq_printf(s, " - Inline_dentry Inode: %u\n",
  437. si->inline_dir);
  438. seq_printf(s, " - Compressed Inode: %u, Blocks: %llu\n",
  439. si->compr_inode, si->compr_blocks);
  440. seq_printf(s, " - Swapfile Inode: %u\n",
  441. si->swapfile_inode);
  442. seq_printf(s, " - Donate Inode: %u\n",
  443. si->ndonate_files);
  444. seq_printf(s, " - Orphan/Append/Update Inode: %u, %u, %u\n",
  445. si->orphans, si->append, si->update);
  446. seq_printf(s, "\nMain area: %d segs, %d secs %d zones\n",
  447. si->main_area_segs, si->main_area_sections,
  448. si->main_area_zones);
  449. seq_printf(s, " TYPE %8s %8s %8s %8s %10s %10s %10s\n",
  450. "blkoff", "segno", "secno", "zoneno", "dirty_seg", "full_seg", "valid_blk");
  451. seq_printf(s, " - COLD data: %8d %8d %8d %8d %10u %10u %10u\n",
  452. si->blkoff[CURSEG_COLD_DATA],
  453. si->curseg[CURSEG_COLD_DATA],
  454. si->cursec[CURSEG_COLD_DATA],
  455. si->curzone[CURSEG_COLD_DATA],
  456. si->dirty_seg[CURSEG_COLD_DATA],
  457. si->full_seg[CURSEG_COLD_DATA],
  458. si->valid_blks[CURSEG_COLD_DATA]);
  459. seq_printf(s, " - WARM data: %8d %8d %8d %8d %10u %10u %10u\n",
  460. si->blkoff[CURSEG_WARM_DATA],
  461. si->curseg[CURSEG_WARM_DATA],
  462. si->cursec[CURSEG_WARM_DATA],
  463. si->curzone[CURSEG_WARM_DATA],
  464. si->dirty_seg[CURSEG_WARM_DATA],
  465. si->full_seg[CURSEG_WARM_DATA],
  466. si->valid_blks[CURSEG_WARM_DATA]);
  467. seq_printf(s, " - HOT data: %8d %8d %8d %8d %10u %10u %10u\n",
  468. si->blkoff[CURSEG_HOT_DATA],
  469. si->curseg[CURSEG_HOT_DATA],
  470. si->cursec[CURSEG_HOT_DATA],
  471. si->curzone[CURSEG_HOT_DATA],
  472. si->dirty_seg[CURSEG_HOT_DATA],
  473. si->full_seg[CURSEG_HOT_DATA],
  474. si->valid_blks[CURSEG_HOT_DATA]);
  475. seq_printf(s, " - Dir dnode: %8d %8d %8d %8d %10u %10u %10u\n",
  476. si->blkoff[CURSEG_HOT_NODE],
  477. si->curseg[CURSEG_HOT_NODE],
  478. si->cursec[CURSEG_HOT_NODE],
  479. si->curzone[CURSEG_HOT_NODE],
  480. si->dirty_seg[CURSEG_HOT_NODE],
  481. si->full_seg[CURSEG_HOT_NODE],
  482. si->valid_blks[CURSEG_HOT_NODE]);
  483. seq_printf(s, " - File dnode: %8d %8d %8d %8d %10u %10u %10u\n",
  484. si->blkoff[CURSEG_WARM_NODE],
  485. si->curseg[CURSEG_WARM_NODE],
  486. si->cursec[CURSEG_WARM_NODE],
  487. si->curzone[CURSEG_WARM_NODE],
  488. si->dirty_seg[CURSEG_WARM_NODE],
  489. si->full_seg[CURSEG_WARM_NODE],
  490. si->valid_blks[CURSEG_WARM_NODE]);
  491. seq_printf(s, " - Indir nodes: %8d %8d %8d %8d %10u %10u %10u\n",
  492. si->blkoff[CURSEG_COLD_NODE],
  493. si->curseg[CURSEG_COLD_NODE],
  494. si->cursec[CURSEG_COLD_NODE],
  495. si->curzone[CURSEG_COLD_NODE],
  496. si->dirty_seg[CURSEG_COLD_NODE],
  497. si->full_seg[CURSEG_COLD_NODE],
  498. si->valid_blks[CURSEG_COLD_NODE]);
  499. seq_printf(s, " - Pinned file: %8d %8d %8d %8d\n",
  500. si->blkoff[CURSEG_COLD_DATA_PINNED],
  501. si->curseg[CURSEG_COLD_DATA_PINNED],
  502. si->cursec[CURSEG_COLD_DATA_PINNED],
  503. si->curzone[CURSEG_COLD_DATA_PINNED]);
  504. seq_printf(s, " - ATGC data: %8d %8d %8d %8d\n",
  505. si->blkoff[CURSEG_ALL_DATA_ATGC],
  506. si->curseg[CURSEG_ALL_DATA_ATGC],
  507. si->cursec[CURSEG_ALL_DATA_ATGC],
  508. si->curzone[CURSEG_ALL_DATA_ATGC]);
  509. seq_printf(s, "\n - Valid: %d\n - Dirty: %d\n",
  510. si->main_area_segs - si->dirty_count -
  511. si->prefree_count - si->free_segs,
  512. si->dirty_count);
  513. seq_printf(s, " - Prefree: %d\n - Free: %d (%d)\n\n",
  514. si->prefree_count, si->free_segs, si->free_secs);
  515. if (f2fs_is_multi_device(sbi)) {
  516. seq_puts(s, "Multidevice stats:\n");
  517. seq_printf(s, " [seg: %8s %8s %8s %8s %8s]",
  518. "inuse", "dirty", "full", "free", "prefree");
  519. if (__is_large_section(sbi))
  520. seq_printf(s, " [sec: %8s %8s %8s %8s %8s]\n",
  521. "inuse", "dirty", "full", "free", "prefree");
  522. else
  523. seq_puts(s, "\n");
  524. for (i = 0; i < sbi->s_ndevs; i++) {
  525. seq_printf(s, " #%-2d %8u %8u %8u %8u %8u", i,
  526. si->dev_stats[i].devstats[0][DEVSTAT_INUSE],
  527. si->dev_stats[i].devstats[0][DEVSTAT_DIRTY],
  528. si->dev_stats[i].devstats[0][DEVSTAT_FULL],
  529. si->dev_stats[i].devstats[0][DEVSTAT_FREE],
  530. si->dev_stats[i].devstats[0][DEVSTAT_PREFREE]);
  531. if (!__is_large_section(sbi)) {
  532. seq_puts(s, "\n");
  533. continue;
  534. }
  535. seq_printf(s, " %8u %8u %8u %8u %8u\n",
  536. si->dev_stats[i].devstats[1][DEVSTAT_INUSE],
  537. si->dev_stats[i].devstats[1][DEVSTAT_DIRTY],
  538. si->dev_stats[i].devstats[1][DEVSTAT_FULL],
  539. si->dev_stats[i].devstats[1][DEVSTAT_FREE],
  540. si->dev_stats[i].devstats[1][DEVSTAT_PREFREE]);
  541. }
  542. seq_puts(s, "\n");
  543. }
  544. seq_printf(s, "CP calls: %d (BG: %d)\n",
  545. si->cp_call_count[TOTAL_CALL],
  546. si->cp_call_count[BACKGROUND]);
  547. seq_printf(s, "CP count: %d\n", si->cp_count);
  548. seq_printf(s, " - cp blocks : %u\n", si->meta_count[META_CP]);
  549. seq_printf(s, " - sit blocks : %u\n",
  550. si->meta_count[META_SIT]);
  551. seq_printf(s, " - nat blocks : %u\n",
  552. si->meta_count[META_NAT]);
  553. seq_printf(s, " - ssa blocks : %u\n",
  554. si->meta_count[META_SSA]);
  555. seq_puts(s, "CP merge:\n");
  556. seq_printf(s, " - Queued : %4d\n", si->nr_queued_ckpt);
  557. seq_printf(s, " - Issued : %4d\n", si->nr_issued_ckpt);
  558. seq_printf(s, " - Total : %4d\n", si->nr_total_ckpt);
  559. seq_printf(s, " - Cur time : %4d(ms)\n", si->cur_ckpt_time);
  560. seq_printf(s, " - Peak time : %4d(ms)\n", si->peak_ckpt_time);
  561. seq_printf(s, "GC calls: %d (gc_thread: %d)\n",
  562. si->gc_call_count[BACKGROUND] +
  563. si->gc_call_count[FOREGROUND],
  564. si->gc_call_count[BACKGROUND]);
  565. if (__is_large_section(sbi)) {
  566. seq_printf(s, " - data sections : %d (BG: %d)\n",
  567. si->gc_secs[DATA][BG_GC] + si->gc_secs[DATA][FG_GC],
  568. si->gc_secs[DATA][BG_GC]);
  569. seq_printf(s, " - node sections : %d (BG: %d)\n",
  570. si->gc_secs[NODE][BG_GC] + si->gc_secs[NODE][FG_GC],
  571. si->gc_secs[NODE][BG_GC]);
  572. }
  573. seq_printf(s, " - data segments : %d (BG: %d)\n",
  574. si->gc_segs[DATA][BG_GC] + si->gc_segs[DATA][FG_GC],
  575. si->gc_segs[DATA][BG_GC]);
  576. seq_printf(s, " - node segments : %d (BG: %d)\n",
  577. si->gc_segs[NODE][BG_GC] + si->gc_segs[NODE][FG_GC],
  578. si->gc_segs[NODE][BG_GC]);
  579. seq_puts(s, " - Reclaimed segs :\n");
  580. seq_printf(s, " - Normal : %d\n", sbi->gc_reclaimed_segs[GC_NORMAL]);
  581. seq_printf(s, " - Idle CB : %d\n", sbi->gc_reclaimed_segs[GC_IDLE_CB]);
  582. seq_printf(s, " - Idle Greedy : %d\n",
  583. sbi->gc_reclaimed_segs[GC_IDLE_GREEDY]);
  584. seq_printf(s, " - Idle AT : %d\n", sbi->gc_reclaimed_segs[GC_IDLE_AT]);
  585. seq_printf(s, " - Urgent High : %d\n",
  586. sbi->gc_reclaimed_segs[GC_URGENT_HIGH]);
  587. seq_printf(s, " - Urgent Mid : %d\n", sbi->gc_reclaimed_segs[GC_URGENT_MID]);
  588. seq_printf(s, " - Urgent Low : %d\n", sbi->gc_reclaimed_segs[GC_URGENT_LOW]);
  589. seq_printf(s, "Try to move %d blocks (BG: %d)\n", si->tot_blks,
  590. si->bg_data_blks + si->bg_node_blks);
  591. seq_printf(s, " - data blocks : %d (%d)\n", si->data_blks,
  592. si->bg_data_blks);
  593. seq_printf(s, " - node blocks : %d (%d)\n", si->node_blks,
  594. si->bg_node_blks);
  595. seq_printf(s, "BG skip : IO: %u, Other: %u\n",
  596. si->io_skip_bggc, si->other_skip_bggc);
  597. seq_puts(s, "\nExtent Cache (Read):\n");
  598. seq_printf(s, " - Hit Count: L1-1:%llu L1-2:%llu L2:%llu\n",
  599. si->hit_largest, si->hit_cached[EX_READ],
  600. si->hit_rbtree[EX_READ]);
  601. seq_printf(s, " - Hit Ratio: %llu%% (%llu / %llu)\n",
  602. !si->total_ext[EX_READ] ? 0 :
  603. div64_u64(si->hit_total[EX_READ] * 100,
  604. si->total_ext[EX_READ]),
  605. si->hit_total[EX_READ], si->total_ext[EX_READ]);
  606. seq_printf(s, " - Inner Struct Count: tree: %d(%d), node: %d\n",
  607. si->ext_tree[EX_READ], si->zombie_tree[EX_READ],
  608. si->ext_node[EX_READ]);
  609. seq_puts(s, "\nExtent Cache (Block Age):\n");
  610. seq_printf(s, " - Allocated Data Blocks: %llu\n",
  611. si->allocated_data_blocks);
  612. seq_printf(s, " - Hit Count: L1:%llu L2:%llu\n",
  613. si->hit_cached[EX_BLOCK_AGE],
  614. si->hit_rbtree[EX_BLOCK_AGE]);
  615. seq_printf(s, " - Hit Ratio: %llu%% (%llu / %llu)\n",
  616. !si->total_ext[EX_BLOCK_AGE] ? 0 :
  617. div64_u64(si->hit_total[EX_BLOCK_AGE] * 100,
  618. si->total_ext[EX_BLOCK_AGE]),
  619. si->hit_total[EX_BLOCK_AGE],
  620. si->total_ext[EX_BLOCK_AGE]);
  621. seq_printf(s, " - Inner Struct Count: tree: %d(%d), node: %d\n",
  622. si->ext_tree[EX_BLOCK_AGE],
  623. si->zombie_tree[EX_BLOCK_AGE],
  624. si->ext_node[EX_BLOCK_AGE]);
  625. seq_puts(s, "\nBalancing F2FS Async:\n");
  626. seq_printf(s, " - DIO (R: %4d, W: %4d)\n",
  627. si->nr_dio_read, si->nr_dio_write);
  628. seq_printf(s, " - IO_R (Data: %4d, Node: %4d, Meta: %4d\n",
  629. si->nr_rd_data, si->nr_rd_node, si->nr_rd_meta);
  630. seq_printf(s, " - IO_W (CP: %4d, Data: %4d, Flush: (%4d %4d %4d), ",
  631. si->nr_wb_cp_data, si->nr_wb_data,
  632. si->nr_flushing, si->nr_flushed,
  633. si->flush_list_empty);
  634. seq_printf(s, "Discard: (%4d %4d)) cmd: %4d undiscard:%4u\n",
  635. si->nr_discarding, si->nr_discarded,
  636. si->nr_discard_cmd, si->undiscard_blks);
  637. seq_printf(s, " - atomic IO: %4d (Max. %4d)\n",
  638. si->aw_cnt, si->max_aw_cnt);
  639. seq_printf(s, " - compress: %4d, hit:%8d\n", si->compress_pages, si->compress_page_hit);
  640. seq_printf(s, " - nodes: %4d in %4d\n",
  641. si->ndirty_node, si->node_pages);
  642. seq_printf(s, " - dents: %4d in dirs:%4d (%4d)\n",
  643. si->ndirty_dent, si->ndirty_dirs, si->ndirty_all);
  644. seq_printf(s, " - data: %4d in files:%4d\n",
  645. si->ndirty_data, si->ndirty_files);
  646. seq_printf(s, " - quota data: %4d in quota files:%4d\n",
  647. si->ndirty_qdata, si->nquota_files);
  648. seq_printf(s, " - meta: %4d in %4d\n",
  649. si->ndirty_meta, si->meta_pages);
  650. seq_printf(s, " - imeta: %4d\n",
  651. si->ndirty_imeta);
  652. seq_printf(s, " - fsync mark: %4lld\n",
  653. percpu_counter_sum_positive(
  654. &sbi->rf_node_block_count));
  655. seq_printf(s, " - NATs: %9d/%9d\n - SITs: %9d/%9d\n",
  656. si->dirty_nats, si->nats, si->dirty_sits, si->sits);
  657. seq_printf(s, " - free_nids: %9d/%9d\n - alloc_nids: %9d\n",
  658. si->free_nids, si->avail_nids, si->alloc_nids);
  659. seq_puts(s, "\nDistribution of User Blocks:");
  660. seq_puts(s, " [ valid | invalid | free ]\n");
  661. seq_puts(s, " [");
  662. for (j = 0; j < si->util_valid; j++)
  663. seq_putc(s, '-');
  664. seq_putc(s, '|');
  665. for (j = 0; j < si->util_invalid; j++)
  666. seq_putc(s, '-');
  667. seq_putc(s, '|');
  668. for (j = 0; j < si->util_free; j++)
  669. seq_putc(s, '-');
  670. seq_puts(s, "]\n\n");
  671. seq_printf(s, "IPU: %u blocks\n", si->inplace_count);
  672. seq_printf(s, "SSR: %u blocks in %u segments\n",
  673. si->block_count[SSR], si->segment_count[SSR]);
  674. seq_printf(s, "LFS: %u blocks in %u segments\n",
  675. si->block_count[LFS], si->segment_count[LFS]);
  676. /* segment usage info */
  677. f2fs_update_sit_info(sbi);
  678. seq_printf(s, "\nBDF: %u, avg. vblocks: %u\n",
  679. si->bimodal, si->avg_vblocks);
  680. /* memory footprint */
  681. update_mem_info(sbi);
  682. seq_printf(s, "\nMemory: %llu KB\n",
  683. (si->base_mem + si->cache_mem + si->page_mem) >> 10);
  684. seq_printf(s, " - static: %llu KB\n",
  685. si->base_mem >> 10);
  686. seq_printf(s, " - cached all: %llu KB\n",
  687. si->cache_mem >> 10);
  688. seq_printf(s, " - read extent cache: %llu KB\n",
  689. si->ext_mem[EX_READ] >> 10);
  690. seq_printf(s, " - block age extent cache: %llu KB\n",
  691. si->ext_mem[EX_BLOCK_AGE] >> 10);
  692. seq_printf(s, " - paged : %llu KB\n",
  693. si->page_mem >> 10);
  694. }
  695. spin_unlock(&f2fs_stat_lock);
  696. return 0;
  697. }
  698. DEFINE_SHOW_ATTRIBUTE(stat);
  699. #endif
  700. int f2fs_build_stats(struct f2fs_sb_info *sbi)
  701. {
  702. struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
  703. struct f2fs_stat_info *si;
  704. struct f2fs_dev_stats *dev_stats;
  705. int i;
  706. si = f2fs_kzalloc(sbi, sizeof(struct f2fs_stat_info), GFP_KERNEL);
  707. if (!si)
  708. return -ENOMEM;
  709. dev_stats = f2fs_kzalloc(sbi, sizeof(struct f2fs_dev_stats) *
  710. sbi->s_ndevs, GFP_KERNEL);
  711. if (!dev_stats) {
  712. kfree(si);
  713. return -ENOMEM;
  714. }
  715. si->dev_stats = dev_stats;
  716. si->all_area_segs = le32_to_cpu(raw_super->segment_count);
  717. si->sit_area_segs = le32_to_cpu(raw_super->segment_count_sit);
  718. si->nat_area_segs = le32_to_cpu(raw_super->segment_count_nat);
  719. si->ssa_area_segs = le32_to_cpu(raw_super->segment_count_ssa);
  720. si->main_area_segs = le32_to_cpu(raw_super->segment_count_main);
  721. si->main_area_sections = le32_to_cpu(raw_super->section_count);
  722. si->main_area_zones = si->main_area_sections /
  723. le32_to_cpu(raw_super->secs_per_zone);
  724. si->sbi = sbi;
  725. sbi->stat_info = si;
  726. /* general extent cache stats */
  727. for (i = 0; i < NR_EXTENT_CACHES; i++) {
  728. atomic64_set(&sbi->total_hit_ext[i], 0);
  729. atomic64_set(&sbi->read_hit_rbtree[i], 0);
  730. atomic64_set(&sbi->read_hit_cached[i], 0);
  731. }
  732. /* read extent_cache only */
  733. atomic64_set(&sbi->read_hit_largest, 0);
  734. atomic_set(&sbi->inline_xattr, 0);
  735. atomic_set(&sbi->inline_inode, 0);
  736. atomic_set(&sbi->inline_dir, 0);
  737. atomic_set(&sbi->compr_inode, 0);
  738. atomic64_set(&sbi->compr_blocks, 0);
  739. atomic_set(&sbi->swapfile_inode, 0);
  740. atomic_set(&sbi->atomic_files, 0);
  741. atomic_set(&sbi->inplace_count, 0);
  742. for (i = META_CP; i < META_MAX; i++)
  743. atomic_set(&sbi->meta_count[i], 0);
  744. for (i = 0; i < MAX_CALL_TYPE; i++)
  745. atomic_set(&sbi->cp_call_count[i], 0);
  746. atomic_set(&sbi->max_aw_cnt, 0);
  747. spin_lock(&f2fs_stat_lock);
  748. list_add_tail(&si->stat_list, &f2fs_stat_list);
  749. spin_unlock(&f2fs_stat_lock);
  750. return 0;
  751. }
  752. void f2fs_destroy_stats(struct f2fs_sb_info *sbi)
  753. {
  754. struct f2fs_stat_info *si = F2FS_STAT(sbi);
  755. spin_lock(&f2fs_stat_lock);
  756. list_del(&si->stat_list);
  757. spin_unlock(&f2fs_stat_lock);
  758. kfree(si->dev_stats);
  759. kfree(si);
  760. }
  761. void __init f2fs_create_root_stats(void)
  762. {
  763. #ifdef CONFIG_DEBUG_FS
  764. f2fs_debugfs_root = debugfs_create_dir("f2fs", NULL);
  765. debugfs_create_file("status", 0444, f2fs_debugfs_root, NULL,
  766. &stat_fops);
  767. #endif
  768. }
  769. void f2fs_destroy_root_stats(void)
  770. {
  771. #ifdef CONFIG_DEBUG_FS
  772. debugfs_remove_recursive(f2fs_debugfs_root);
  773. f2fs_debugfs_root = NULL;
  774. #endif
  775. }