]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
f2fs: add page-order information for large folio reads in iostat
authorDaniel Lee <chullee@google.com>
Fri, 17 Apr 2026 17:50:40 +0000 (10:50 -0700)
committerJaegeuk Kim <jaegeuk@kernel.org>
Sat, 18 Apr 2026 22:44:42 +0000 (22:44 +0000)
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>
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/iostat.c
fs/f2fs/iostat.h
include/trace/events/f2fs.h

index a210a7a627c6bf12f5572173e9e334ca4aef504e..965d4e6443c6e8be7e01d5cfdbaadf8a5537407e 100644 (file)
@@ -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;
 
index 56c4af4b17374e74683903f80ca67dfa5d118221..e40b6b2784ee97b8efd7a99f8787e0298284d5b4 100644 (file)
@@ -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;
index f8703038e1d81c619d71c038a1cc840401b04f38..ae265e3e9b2c980575e60ec8585a86aec446e138 100644 (file)
@@ -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)
 {
index eb99d05cf27273be29a53078788c4ba3dd4c9a85..2025225b5bedac7258c5011b2a56e44e0d8e1d54 100644 (file)
@@ -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) {}
index 9364e677556207ac041353a9eb2d5c2ee49b9dff..ff4a58c2cbbb252806f3ac6ce1bab13cdc1b9841 100644 (file)
@@ -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