diff options
| author | Daniel Lee <chullee@google.com> | 2026-04-17 10:50:40 -0700 |
|---|---|---|
| committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2026-04-18 22:44:42 +0000 |
| commit | cb8ff3ead9a3fc43727980be58c7099506f65261 (patch) | |
| tree | 75967c554018b10bd918235aec4306954df55956 | |
| parent | 1583a7ded0d3d67fd6e7e4336600bc191d068a20 (diff) | |
f2fs: add page-order information for large folio reads in iostat
Track read folio counts by order in F2FS iostat sysfs and tracepoints.
Signed-off-by: Daniel Lee <chullee@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
| -rw-r--r-- | fs/f2fs/data.c | 4 | ||||
| -rw-r--r-- | fs/f2fs/f2fs.h | 3 | ||||
| -rw-r--r-- | fs/f2fs/iostat.c | 38 | ||||
| -rw-r--r-- | fs/f2fs/iostat.h | 4 | ||||
| -rw-r--r-- | include/trace/events/f2fs.h | 21 |
5 files changed, 65 insertions, 5 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a210a7a627c6..965d4e6443c6 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2508,6 +2508,8 @@ next_folio: if (!folio) goto out; + f2fs_update_read_folio_count(F2FS_I_SB(inode), folio); + folio_in_bio = false; index = folio->index; offset = 0; @@ -2682,6 +2684,8 @@ static int f2fs_mpage_readpages(struct inode *inode, struct fsverity_info *vi, prefetchw(&folio->flags); } + f2fs_update_read_folio_count(F2FS_I_SB(inode), folio); + #ifdef CONFIG_F2FS_FS_COMPRESSION index = folio->index; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 56c4af4b1737..e40b6b2784ee 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -10,6 +10,7 @@ #include <linux/uio.h> #include <linux/types.h> +#include <linux/mmzone.h> #include <linux/page-flags.h> #include <linux/slab.h> #include <linux/crc32.h> @@ -2034,6 +2035,8 @@ struct f2fs_sb_info { unsigned long long iostat_count[NR_IO_TYPE]; unsigned long long iostat_bytes[NR_IO_TYPE]; unsigned long long prev_iostat_bytes[NR_IO_TYPE]; + unsigned long long iostat_read_folio_count[NR_PAGE_ORDERS]; + unsigned long long prev_iostat_read_folio_count[NR_PAGE_ORDERS]; bool iostat_enable; unsigned long iostat_next_period; unsigned int iostat_period_ms; diff --git a/fs/f2fs/iostat.c b/fs/f2fs/iostat.c index f8703038e1d8..ae265e3e9b2c 100644 --- a/fs/f2fs/iostat.c +++ b/fs/f2fs/iostat.c @@ -34,6 +34,7 @@ int __maybe_unused iostat_info_seq_show(struct seq_file *seq, void *offset) { struct super_block *sb = seq->private; struct f2fs_sb_info *sbi = F2FS_SB(sb); + int i; if (!sbi->iostat_enable) return 0; @@ -76,6 +77,12 @@ int __maybe_unused iostat_info_seq_show(struct seq_file *seq, void *offset) IOSTAT_INFO_SHOW("fs node", FS_NODE_READ_IO); IOSTAT_INFO_SHOW("fs meta", FS_META_READ_IO); + /* print read folio order stats */ + seq_printf(seq, "%-23s", "fs read folio order:"); + for (i = 0; i < NR_PAGE_ORDERS; i++) + seq_printf(seq, " %llu", sbi->iostat_read_folio_count[i]); + seq_putc(seq, '\n'); + /* print other IOs */ seq_puts(seq, "[OTHER]\n"); IOSTAT_INFO_SHOW("fs discard", FS_DISCARD_IO); @@ -113,6 +120,7 @@ static inline void __record_iostat_latency(struct f2fs_sb_info *sbi) static inline void f2fs_record_iostat(struct f2fs_sb_info *sbi) { unsigned long long iostat_diff[NR_IO_TYPE]; + unsigned long long read_folio_count_diff[NR_PAGE_ORDERS]; int i; unsigned long flags; @@ -133,9 +141,15 @@ static inline void f2fs_record_iostat(struct f2fs_sb_info *sbi) sbi->prev_iostat_bytes[i]; sbi->prev_iostat_bytes[i] = sbi->iostat_bytes[i]; } + + for (i = 0; i < NR_PAGE_ORDERS; i++) { + read_folio_count_diff[i] = sbi->iostat_read_folio_count[i] - + sbi->prev_iostat_read_folio_count[i]; + sbi->prev_iostat_read_folio_count[i] = sbi->iostat_read_folio_count[i]; + } spin_unlock_irqrestore(&sbi->iostat_lock, flags); - trace_f2fs_iostat(sbi, iostat_diff); + trace_f2fs_iostat(sbi, iostat_diff, read_folio_count_diff); __record_iostat_latency(sbi); } @@ -151,6 +165,10 @@ void f2fs_reset_iostat(struct f2fs_sb_info *sbi) sbi->iostat_bytes[i] = 0; sbi->prev_iostat_bytes[i] = 0; } + for (i = 0; i < NR_PAGE_ORDERS; i++) { + sbi->iostat_read_folio_count[i] = 0; + sbi->prev_iostat_read_folio_count[i] = 0; + } spin_unlock_irq(&sbi->iostat_lock); spin_lock_irq(&sbi->iostat_lat_lock); @@ -165,6 +183,24 @@ static inline void __f2fs_update_iostat(struct f2fs_sb_info *sbi, sbi->iostat_count[type]++; } +void f2fs_update_read_folio_count(struct f2fs_sb_info *sbi, struct folio *folio) +{ + unsigned int order = folio_order(folio); + unsigned long flags; + + if (!sbi->iostat_enable) + return; + + if (order >= NR_PAGE_ORDERS) + order = NR_PAGE_ORDERS - 1; + + spin_lock_irqsave(&sbi->iostat_lock, flags); + sbi->iostat_read_folio_count[order]++; + spin_unlock_irqrestore(&sbi->iostat_lock, flags); + + f2fs_record_iostat(sbi); +} + void f2fs_update_iostat(struct f2fs_sb_info *sbi, struct inode *inode, enum iostat_type type, unsigned long long io_bytes) { diff --git a/fs/f2fs/iostat.h b/fs/f2fs/iostat.h index eb99d05cf272..2025225b5bed 100644 --- a/fs/f2fs/iostat.h +++ b/fs/f2fs/iostat.h @@ -34,6 +34,8 @@ extern int __maybe_unused iostat_info_seq_show(struct seq_file *seq, extern void f2fs_reset_iostat(struct f2fs_sb_info *sbi); extern void f2fs_update_iostat(struct f2fs_sb_info *sbi, struct inode *inode, enum iostat_type type, unsigned long long io_bytes); +extern void f2fs_update_read_folio_count(struct f2fs_sb_info *sbi, + struct folio *folio); struct bio_iostat_ctx { struct f2fs_sb_info *sbi; @@ -68,6 +70,8 @@ extern void f2fs_destroy_iostat(struct f2fs_sb_info *sbi); #else static inline void f2fs_update_iostat(struct f2fs_sb_info *sbi, struct inode *inode, enum iostat_type type, unsigned long long io_bytes) {} +static inline void f2fs_update_read_folio_count(struct f2fs_sb_info *sbi, + struct folio *folio) {} static inline void iostat_update_and_unbind_ctx(struct bio *bio) {} static inline void iostat_alloc_and_bind_ctx(struct f2fs_sb_info *sbi, struct bio *bio, struct bio_post_read_ctx *ctx) {} diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index 9364e6775562..ff4a58c2cbbb 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -2116,9 +2116,10 @@ DEFINE_EVENT(f2fs_zip_end, f2fs_decompress_pages_end, #ifdef CONFIG_F2FS_IOSTAT TRACE_EVENT(f2fs_iostat, - TP_PROTO(struct f2fs_sb_info *sbi, unsigned long long *iostat), + TP_PROTO(struct f2fs_sb_info *sbi, unsigned long long *iostat, + unsigned long long *read_folio_count), - TP_ARGS(sbi, iostat), + TP_ARGS(sbi, iostat, read_folio_count), TP_STRUCT__entry( __field(dev_t, dev) @@ -2150,6 +2151,7 @@ TRACE_EVENT(f2fs_iostat, __field(unsigned long long, fs_mrio) __field(unsigned long long, fs_discard) __field(unsigned long long, fs_reset_zone) + __array(unsigned long long, read_folio_count, 11) ), TP_fast_assign( @@ -2182,6 +2184,9 @@ TRACE_EVENT(f2fs_iostat, __entry->fs_mrio = iostat[FS_META_READ_IO]; __entry->fs_discard = iostat[FS_DISCARD_IO]; __entry->fs_reset_zone = iostat[FS_ZONE_RESET_IO]; + memset(__entry->read_folio_count, 0, sizeof(__entry->read_folio_count)); + memcpy(__entry->read_folio_count, read_folio_count, + sizeof(unsigned long long) * min_t(int, NR_PAGE_ORDERS, 11)); ), TP_printk("dev = (%d,%d), " @@ -2194,7 +2199,9 @@ TRACE_EVENT(f2fs_iostat, "app [read=%llu (direct=%llu, buffered=%llu), mapped=%llu], " "compr(buffered=%llu, mapped=%llu)], " "fs [data=%llu, (gc_data=%llu, cdata=%llu), " - "node=%llu, meta=%llu]", + "node=%llu, meta=%llu], " + "read_folio_count [0=%llu, 1=%llu, 2=%llu, 3=%llu, 4=%llu, " + "5=%llu, 6=%llu, 7=%llu, 8=%llu, 9=%llu, 10=%llu]", show_dev(__entry->dev), __entry->app_wio, __entry->app_dio, __entry->app_bio, __entry->app_mio, __entry->app_bcdio, __entry->app_mcdio, __entry->fs_dio, __entry->fs_cdio, @@ -2205,7 +2212,13 @@ TRACE_EVENT(f2fs_iostat, __entry->app_rio, __entry->app_drio, __entry->app_brio, __entry->app_mrio, __entry->app_bcrio, __entry->app_mcrio, __entry->fs_drio, __entry->fs_gdrio, - __entry->fs_cdrio, __entry->fs_nrio, __entry->fs_mrio) + __entry->fs_cdrio, __entry->fs_nrio, __entry->fs_mrio, + __entry->read_folio_count[0], __entry->read_folio_count[1], + __entry->read_folio_count[2], __entry->read_folio_count[3], + __entry->read_folio_count[4], __entry->read_folio_count[5], + __entry->read_folio_count[6], __entry->read_folio_count[7], + __entry->read_folio_count[8], __entry->read_folio_count[9], + __entry->read_folio_count[10]) ); #ifndef __F2FS_IOSTAT_LATENCY_TYPE |
