From: Daniel Lee via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
To: Jaegeuk Kim <jaegeuk@kernel.org>, Chao Yu <chao@kernel.org>
Cc: linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net
Subject: [f2fs-dev] [PATCH] f2fs: add page-order information for large folio reads in iostat
Date: Tue, 7 Apr 2026 23:08:40 -0700 [thread overview]
Message-ID: <20260408060840.316332-1-chullee@google.com> (raw)
Track read folio counts by order in F2FS iostat sysfs and tracepoints.
Signed-off-by: Daniel Lee <chullee@google.com>
---
fs/f2fs/data.c | 4 ++++
fs/f2fs/f2fs.h | 3 +++
fs/f2fs/iostat.c | 38 ++++++++++++++++++++++++++++++++++++-
fs/f2fs/iostat.h | 4 ++++
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 @@ static int f2fs_read_data_large_folio(struct inode *inode,
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..49c6cbb6f989 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, 16)
),
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, 16));
),
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
--
2.53.0.1213.gd9a14994de-goog
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
next reply other threads:[~2026-04-08 7:21 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-08 6:08 Daniel Lee via Linux-f2fs-devel [this message]
2026-04-13 11:35 ` [f2fs-dev] [PATCH] f2fs: add page-order information for large folio reads in iostat Chao Yu via Linux-f2fs-devel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260408060840.316332-1-chullee@google.com \
--to=linux-f2fs-devel@lists.sourceforge.net \
--cc=chao@kernel.org \
--cc=chullee@google.com \
--cc=jaegeuk@kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.