@@ -1864,6 +1864,7 @@ struct f2fs_sb_info {
#ifdef CONFIG_F2FS_IOSTAT
/* For app/fs IO statistics */
spinlock_t iostat_lock;
+ unsigned long long iostat_count[NR_IO_TYPE];
unsigned long long rw_iostat[NR_IO_TYPE];
unsigned long long prev_rw_iostat[NR_IO_TYPE];
bool iostat_enable;
@@ -18,6 +18,13 @@
static struct kmem_cache *bio_iostat_ctx_cache;
static mempool_t *bio_iostat_ctx_pool;
+static inline unsigned long long iostat_get_avg_bytes(struct f2fs_sb_info *sbi,
+ enum iostat_type type)
+{
+ return sbi->iostat_count[type] ? div64_u64(sbi->rw_iostat[type],
+ sbi->iostat_count[type]) : 0;
+}
+
int __maybe_unused iostat_info_seq_show(struct seq_file *seq, void *offset)
{
struct super_block *sb = seq->private;
@@ -28,69 +35,121 @@ int __maybe_unused iostat_info_seq_show(struct seq_file *seq, void *offset)
return 0;
seq_printf(seq, "time: %-16llu\n", now);
+ seq_printf(seq, "\t\t\t%-16s %-16s %-16s\n",
+ "io_bytes", "count", "avg_bytes");
/* print app write IOs */
seq_puts(seq, "[WRITE]\n");
- seq_printf(seq, "app buffered data: %-16llu\n",
- sbi->rw_iostat[APP_BUFFERED_IO]);
- seq_printf(seq, "app direct data: %-16llu\n",
- sbi->rw_iostat[APP_DIRECT_IO]);
- seq_printf(seq, "app mapped data: %-16llu\n",
- sbi->rw_iostat[APP_MAPPED_IO]);
- seq_printf(seq, "app buffered cdata: %-16llu\n",
- sbi->rw_iostat[APP_BUFFERED_CDATA_IO]);
- seq_printf(seq, "app mapped cdata: %-16llu\n",
- sbi->rw_iostat[APP_MAPPED_CDATA_IO]);
+ seq_printf(seq, "app buffered data: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[APP_BUFFERED_IO],
+ sbi->iostat_count[APP_BUFFERED_IO],
+ iostat_get_avg_bytes(sbi, APP_BUFFERED_IO));
+ seq_printf(seq, "app direct data: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[APP_DIRECT_IO],
+ sbi->iostat_count[APP_DIRECT_IO],
+ iostat_get_avg_bytes(sbi, APP_DIRECT_IO));
+ seq_printf(seq, "app mapped data: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[APP_MAPPED_IO],
+ sbi->iostat_count[APP_MAPPED_IO],
+ iostat_get_avg_bytes(sbi, APP_MAPPED_IO));
+ seq_printf(seq, "app buffered cdata: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[APP_BUFFERED_CDATA_IO],
+ sbi->iostat_count[APP_BUFFERED_CDATA_IO],
+ iostat_get_avg_bytes(sbi, APP_BUFFERED_CDATA_IO));
+ seq_printf(seq, "app mapped cdata: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[APP_MAPPED_CDATA_IO],
+ sbi->iostat_count[APP_MAPPED_CDATA_IO],
+ iostat_get_avg_bytes(sbi, APP_MAPPED_CDATA_IO));
/* print fs write IOs */
- seq_printf(seq, "fs data: %-16llu\n",
- sbi->rw_iostat[FS_DATA_IO]);
- seq_printf(seq, "fs cdata: %-16llu\n",
- sbi->rw_iostat[FS_CDATA_IO]);
- seq_printf(seq, "fs node: %-16llu\n",
- sbi->rw_iostat[FS_NODE_IO]);
- seq_printf(seq, "fs meta: %-16llu\n",
- sbi->rw_iostat[FS_META_IO]);
- seq_printf(seq, "fs gc data: %-16llu\n",
- sbi->rw_iostat[FS_GC_DATA_IO]);
- seq_printf(seq, "fs gc node: %-16llu\n",
- sbi->rw_iostat[FS_GC_NODE_IO]);
- seq_printf(seq, "fs cp data: %-16llu\n",
- sbi->rw_iostat[FS_CP_DATA_IO]);
- seq_printf(seq, "fs cp node: %-16llu\n",
- sbi->rw_iostat[FS_CP_NODE_IO]);
- seq_printf(seq, "fs cp meta: %-16llu\n",
- sbi->rw_iostat[FS_CP_META_IO]);
+ seq_printf(seq, "fs data: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_DATA_IO],
+ sbi->iostat_count[FS_DATA_IO],
+ iostat_get_avg_bytes(sbi, FS_DATA_IO));
+ seq_printf(seq, "fs cdata: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_CDATA_IO],
+ sbi->iostat_count[FS_CDATA_IO],
+ iostat_get_avg_bytes(sbi, FS_CDATA_IO));
+ seq_printf(seq, "fs node: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_NODE_IO],
+ sbi->iostat_count[FS_NODE_IO],
+ iostat_get_avg_bytes(sbi, FS_NODE_IO));
+ seq_printf(seq, "fs meta: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_META_IO],
+ sbi->iostat_count[FS_META_IO],
+ iostat_get_avg_bytes(sbi, FS_META_IO));
+ seq_printf(seq, "fs gc data: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_GC_DATA_IO],
+ sbi->iostat_count[FS_GC_DATA_IO],
+ iostat_get_avg_bytes(sbi, FS_GC_DATA_IO));
+ seq_printf(seq, "fs gc node: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_GC_NODE_IO],
+ sbi->iostat_count[FS_GC_NODE_IO],
+ iostat_get_avg_bytes(sbi, FS_GC_NODE_IO));
+ seq_printf(seq, "fs cp data: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_CP_DATA_IO],
+ sbi->iostat_count[FS_CP_DATA_IO],
+ iostat_get_avg_bytes(sbi, FS_CP_DATA_IO));
+ seq_printf(seq, "fs cp node: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_CP_NODE_IO],
+ sbi->iostat_count[FS_CP_NODE_IO],
+ iostat_get_avg_bytes(sbi, FS_CP_NODE_IO));
+ seq_printf(seq, "fs cp meta: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_CP_META_IO],
+ sbi->iostat_count[FS_CP_META_IO],
+ iostat_get_avg_bytes(sbi, FS_CP_META_IO));
/* print app read IOs */
seq_puts(seq, "[READ]\n");
- seq_printf(seq, "app buffered data: %-16llu\n",
- sbi->rw_iostat[APP_BUFFERED_READ_IO]);
- seq_printf(seq, "app direct data: %-16llu\n",
- sbi->rw_iostat[APP_DIRECT_READ_IO]);
- seq_printf(seq, "app mapped data: %-16llu\n",
- sbi->rw_iostat[APP_MAPPED_READ_IO]);
- seq_printf(seq, "app buffered cdata: %-16llu\n",
- sbi->rw_iostat[APP_BUFFERED_CDATA_READ_IO]);
- seq_printf(seq, "app mapped cdata: %-16llu\n",
- sbi->rw_iostat[APP_MAPPED_CDATA_READ_IO]);
+ seq_printf(seq, "app buffered data: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[APP_BUFFERED_READ_IO],
+ sbi->iostat_count[APP_BUFFERED_READ_IO],
+ iostat_get_avg_bytes(sbi, APP_BUFFERED_READ_IO));
+ seq_printf(seq, "app direct data: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[APP_DIRECT_READ_IO],
+ sbi->iostat_count[APP_DIRECT_READ_IO],
+ iostat_get_avg_bytes(sbi, APP_DIRECT_READ_IO));
+ seq_printf(seq, "app mapped data: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[APP_MAPPED_READ_IO],
+ sbi->iostat_count[APP_MAPPED_READ_IO],
+ iostat_get_avg_bytes(sbi, APP_MAPPED_READ_IO));
+ seq_printf(seq, "app buffered cdata: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[APP_BUFFERED_CDATA_READ_IO],
+ sbi->iostat_count[APP_BUFFERED_CDATA_READ_IO],
+ iostat_get_avg_bytes(sbi, APP_BUFFERED_CDATA_READ_IO));
+ seq_printf(seq, "app mapped cdata: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[APP_MAPPED_CDATA_READ_IO],
+ sbi->iostat_count[APP_MAPPED_CDATA_READ_IO],
+ iostat_get_avg_bytes(sbi, APP_MAPPED_CDATA_READ_IO));
/* print fs read IOs */
- seq_printf(seq, "fs data: %-16llu\n",
- sbi->rw_iostat[FS_DATA_READ_IO]);
- seq_printf(seq, "fs gc data: %-16llu\n",
- sbi->rw_iostat[FS_GDATA_READ_IO]);
- seq_printf(seq, "fs cdata: %-16llu\n",
- sbi->rw_iostat[FS_CDATA_READ_IO]);
- seq_printf(seq, "fs node: %-16llu\n",
- sbi->rw_iostat[FS_NODE_READ_IO]);
- seq_printf(seq, "fs meta: %-16llu\n",
- sbi->rw_iostat[FS_META_READ_IO]);
+ seq_printf(seq, "fs data: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_DATA_READ_IO],
+ sbi->iostat_count[FS_DATA_READ_IO],
+ iostat_get_avg_bytes(sbi, FS_DATA_READ_IO));
+ seq_printf(seq, "fs gc data: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_GDATA_READ_IO],
+ sbi->iostat_count[FS_GDATA_READ_IO],
+ iostat_get_avg_bytes(sbi, FS_GDATA_READ_IO));
+ seq_printf(seq, "fs cdata: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_CDATA_READ_IO],
+ sbi->iostat_count[FS_CDATA_READ_IO],
+ iostat_get_avg_bytes(sbi, FS_CDATA_READ_IO));
+ seq_printf(seq, "fs node: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_NODE_READ_IO],
+ sbi->iostat_count[FS_NODE_READ_IO],
+ iostat_get_avg_bytes(sbi, FS_NODE_READ_IO));
+ seq_printf(seq, "fs meta: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_META_READ_IO],
+ sbi->iostat_count[FS_META_READ_IO],
+ iostat_get_avg_bytes(sbi, FS_META_READ_IO));
/* print other IOs */
seq_puts(seq, "[OTHER]\n");
- seq_printf(seq, "fs discard: %-16llu\n",
- sbi->rw_iostat[FS_DISCARD]);
+ seq_printf(seq, "fs discard: %-16llu %-16llu %-16llu\n",
+ sbi->rw_iostat[FS_DISCARD],
+ sbi->iostat_count[FS_DISCARD],
+ iostat_get_avg_bytes(sbi, FS_DISCARD));
return 0;
}
@@ -169,6 +228,13 @@ void f2fs_reset_iostat(struct f2fs_sb_info *sbi)
spin_unlock_irq(&sbi->iostat_lat_lock);
}
+static inline void __f2fs_update_iostat(struct f2fs_sb_info *sbi,
+ enum iostat_type type, unsigned long long io_bytes)
+{
+ sbi->rw_iostat[type] += io_bytes;
+ sbi->iostat_count[type]++;
+}
+
void f2fs_update_iostat(struct f2fs_sb_info *sbi, struct inode *inode,
enum iostat_type type, unsigned long long io_bytes)
{
@@ -178,33 +244,33 @@ void f2fs_update_iostat(struct f2fs_sb_info *sbi, struct inode *inode,
return;
spin_lock_irqsave(&sbi->iostat_lock, flags);
- sbi->rw_iostat[type] += io_bytes;
+ __f2fs_update_iostat(sbi, type, io_bytes);
if (type == APP_BUFFERED_IO || type == APP_DIRECT_IO)
- sbi->rw_iostat[APP_WRITE_IO] += io_bytes;
+ __f2fs_update_iostat(sbi, APP_WRITE_IO, io_bytes);
if (type == APP_BUFFERED_READ_IO || type == APP_DIRECT_READ_IO)
- sbi->rw_iostat[APP_READ_IO] += io_bytes;
+ __f2fs_update_iostat(sbi, APP_READ_IO, io_bytes);
#ifdef CONFIG_F2FS_FS_COMPRESSION
if (inode && f2fs_compressed_file(inode)) {
if (type == APP_BUFFERED_IO)
- sbi->rw_iostat[APP_BUFFERED_CDATA_IO] += io_bytes;
+ __f2fs_update_iostat(sbi, APP_BUFFERED_CDATA_IO, io_bytes);
if (type == APP_BUFFERED_READ_IO)
- sbi->rw_iostat[APP_BUFFERED_CDATA_READ_IO] += io_bytes;
+ __f2fs_update_iostat(sbi, APP_BUFFERED_CDATA_READ_IO, io_bytes);
if (type == APP_MAPPED_READ_IO)
- sbi->rw_iostat[APP_MAPPED_CDATA_READ_IO] += io_bytes;
+ __f2fs_update_iostat(sbi, APP_MAPPED_CDATA_READ_IO, io_bytes);
if (type == APP_MAPPED_IO)
- sbi->rw_iostat[APP_MAPPED_CDATA_IO] += io_bytes;
+ __f2fs_update_iostat(sbi, APP_MAPPED_CDATA_IO, io_bytes);
if (type == FS_DATA_READ_IO)
- sbi->rw_iostat[FS_CDATA_READ_IO] += io_bytes;
+ __f2fs_update_iostat(sbi, FS_CDATA_READ_IO, io_bytes);
if (type == FS_DATA_IO)
- sbi->rw_iostat[FS_CDATA_IO] += io_bytes;
+ __f2fs_update_iostat(sbi, FS_CDATA_IO, io_bytes);
}
#endif