Commit 8b83ac81 authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim

f2fs: support read iostat

Adds to support accounting read IOs from userspace/kernel.
Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent df423399
...@@ -86,6 +86,8 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, ...@@ -86,6 +86,8 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
return ERR_PTR(err); return ERR_PTR(err);
} }
f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE);
lock_page(page); lock_page(page);
if (unlikely(page->mapping != mapping)) { if (unlikely(page->mapping != mapping)) {
f2fs_put_page(page, 1); f2fs_put_page(page, 1);
...@@ -266,6 +268,9 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, ...@@ -266,6 +268,9 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
fio.page = page; fio.page = page;
err = f2fs_submit_page_bio(&fio); err = f2fs_submit_page_bio(&fio);
f2fs_put_page(page, err ? 1 : 0); f2fs_put_page(page, err ? 1 : 0);
if (!err)
f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE);
} }
out: out:
blk_finish_plug(&plug); blk_finish_plug(&plug);
......
...@@ -1033,6 +1033,7 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page, ...@@ -1033,6 +1033,7 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,
} }
ClearPageError(page); ClearPageError(page);
inc_page_count(sbi, F2FS_RD_DATA); inc_page_count(sbi, F2FS_RD_DATA);
f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
__submit_bio(sbi, bio, DATA); __submit_bio(sbi, bio, DATA);
return 0; return 0;
} }
...@@ -2038,6 +2039,7 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page, ...@@ -2038,6 +2039,7 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
goto submit_and_realloc; goto submit_and_realloc;
inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA); inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA);
f2fs_update_iostat(F2FS_I_SB(inode), FS_DATA_READ_IO, F2FS_BLKSIZE);
ClearPageError(page); ClearPageError(page);
*last_block_in_bio = block_nr; *last_block_in_bio = block_nr;
goto out; goto out;
...@@ -2173,6 +2175,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, ...@@ -2173,6 +2175,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
goto submit_and_realloc; goto submit_and_realloc;
inc_page_count(sbi, F2FS_RD_DATA); inc_page_count(sbi, F2FS_RD_DATA);
f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
ClearPageError(page); ClearPageError(page);
*last_block_in_bio = blkaddr; *last_block_in_bio = blkaddr;
} }
...@@ -3526,6 +3529,9 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) ...@@ -3526,6 +3529,9 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
} else if (err < 0) { } else if (err < 0) {
f2fs_write_failed(mapping, offset + count); f2fs_write_failed(mapping, offset + count);
} }
} else {
if (err > 0)
f2fs_update_iostat(sbi, APP_DIRECT_READ_IO, err);
} }
out: out:
......
...@@ -1088,8 +1088,9 @@ enum cp_reason_type { ...@@ -1088,8 +1088,9 @@ enum cp_reason_type {
}; };
enum iostat_type { enum iostat_type {
APP_DIRECT_IO, /* app direct IOs */ /* WRITE IO */
APP_BUFFERED_IO, /* app buffered IOs */ APP_DIRECT_IO, /* app direct write IOs */
APP_BUFFERED_IO, /* app buffered write IOs */
APP_WRITE_IO, /* app write IOs */ APP_WRITE_IO, /* app write IOs */
APP_MAPPED_IO, /* app mapped IOs */ APP_MAPPED_IO, /* app mapped IOs */
FS_DATA_IO, /* data IOs from kworker/fsync/reclaimer */ FS_DATA_IO, /* data IOs from kworker/fsync/reclaimer */
...@@ -1100,6 +1101,17 @@ enum iostat_type { ...@@ -1100,6 +1101,17 @@ enum iostat_type {
FS_CP_DATA_IO, /* data IOs from checkpoint */ FS_CP_DATA_IO, /* data IOs from checkpoint */
FS_CP_NODE_IO, /* node IOs from checkpoint */ FS_CP_NODE_IO, /* node IOs from checkpoint */
FS_CP_META_IO, /* meta IOs from checkpoint */ FS_CP_META_IO, /* meta IOs from checkpoint */
/* READ IO */
APP_DIRECT_READ_IO, /* app direct read IOs */
APP_BUFFERED_READ_IO, /* app buffered read IOs */
APP_READ_IO, /* app read IOs */
APP_MAPPED_READ_IO, /* app mapped read IOs */
FS_DATA_READ_IO, /* data read IOs */
FS_NODE_READ_IO, /* node read IOs */
FS_META_READ_IO, /* meta read IOs */
/* other */
FS_DISCARD, /* discard */ FS_DISCARD, /* discard */
NR_IO_TYPE, NR_IO_TYPE,
}; };
...@@ -1504,8 +1516,8 @@ struct f2fs_sb_info { ...@@ -1504,8 +1516,8 @@ struct f2fs_sb_info {
/* For app/fs IO statistics */ /* For app/fs IO statistics */
spinlock_t iostat_lock; spinlock_t iostat_lock;
unsigned long long write_iostat[NR_IO_TYPE]; unsigned long long rw_iostat[NR_IO_TYPE];
unsigned long long prev_write_iostat[NR_IO_TYPE]; unsigned long long prev_rw_iostat[NR_IO_TYPE];
bool iostat_enable; bool iostat_enable;
unsigned long iostat_next_period; unsigned long iostat_next_period;
unsigned int iostat_period_ms; unsigned int iostat_period_ms;
...@@ -3013,8 +3025,8 @@ static inline void f2fs_reset_iostat(struct f2fs_sb_info *sbi) ...@@ -3013,8 +3025,8 @@ static inline void f2fs_reset_iostat(struct f2fs_sb_info *sbi)
spin_lock(&sbi->iostat_lock); spin_lock(&sbi->iostat_lock);
for (i = 0; i < NR_IO_TYPE; i++) { for (i = 0; i < NR_IO_TYPE; i++) {
sbi->write_iostat[i] = 0; sbi->rw_iostat[i] = 0;
sbi->prev_write_iostat[i] = 0; sbi->prev_rw_iostat[i] = 0;
} }
spin_unlock(&sbi->iostat_lock); spin_unlock(&sbi->iostat_lock);
} }
...@@ -3027,12 +3039,17 @@ static inline void f2fs_update_iostat(struct f2fs_sb_info *sbi, ...@@ -3027,12 +3039,17 @@ static inline void f2fs_update_iostat(struct f2fs_sb_info *sbi,
if (!sbi->iostat_enable) if (!sbi->iostat_enable)
return; return;
spin_lock(&sbi->iostat_lock); spin_lock(&sbi->iostat_lock);
sbi->write_iostat[type] += io_bytes; sbi->rw_iostat[type] += io_bytes;
if (type == APP_WRITE_IO || type == APP_DIRECT_IO) if (type == APP_WRITE_IO || type == APP_DIRECT_IO)
sbi->write_iostat[APP_BUFFERED_IO] = sbi->rw_iostat[APP_BUFFERED_IO] =
sbi->write_iostat[APP_WRITE_IO] - sbi->rw_iostat[APP_WRITE_IO] -
sbi->write_iostat[APP_DIRECT_IO]; sbi->rw_iostat[APP_DIRECT_IO];
if (type == APP_READ_IO || type == APP_DIRECT_READ_IO)
sbi->rw_iostat[APP_BUFFERED_READ_IO] =
sbi->rw_iostat[APP_READ_IO] -
sbi->rw_iostat[APP_DIRECT_READ_IO];
spin_unlock(&sbi->iostat_lock); spin_unlock(&sbi->iostat_lock);
f2fs_record_iostat(sbi); f2fs_record_iostat(sbi);
......
...@@ -40,6 +40,10 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf) ...@@ -40,6 +40,10 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf)
ret = filemap_fault(vmf); ret = filemap_fault(vmf);
up_read(&F2FS_I(inode)->i_mmap_sem); up_read(&F2FS_I(inode)->i_mmap_sem);
if (!ret)
f2fs_update_iostat(F2FS_I_SB(inode), APP_MAPPED_READ_IO,
F2FS_BLKSIZE);
trace_f2fs_filemap_fault(inode, vmf->pgoff, (unsigned long)ret); trace_f2fs_filemap_fault(inode, vmf->pgoff, (unsigned long)ret);
return ret; return ret;
...@@ -3510,11 +3514,17 @@ static ssize_t f2fs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) ...@@ -3510,11 +3514,17 @@ static ssize_t f2fs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
{ {
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
int ret;
if (!f2fs_is_compress_backend_ready(inode)) if (!f2fs_is_compress_backend_ready(inode))
return -EOPNOTSUPP; return -EOPNOTSUPP;
return generic_file_read_iter(iocb, iter); ret = generic_file_read_iter(iocb, iter);
if (ret > 0)
f2fs_update_iostat(F2FS_I_SB(inode), APP_READ_IO, ret);
return ret;
} }
static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
......
...@@ -737,6 +737,9 @@ static int ra_data_block(struct inode *inode, pgoff_t index) ...@@ -737,6 +737,9 @@ static int ra_data_block(struct inode *inode, pgoff_t index)
goto put_encrypted_page; goto put_encrypted_page;
f2fs_put_page(fio.encrypted_page, 0); f2fs_put_page(fio.encrypted_page, 0);
f2fs_put_page(page, 1); f2fs_put_page(page, 1);
f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
return 0; return 0;
put_encrypted_page: put_encrypted_page:
f2fs_put_page(fio.encrypted_page, 1); f2fs_put_page(fio.encrypted_page, 1);
...@@ -840,6 +843,9 @@ static int move_data_block(struct inode *inode, block_t bidx, ...@@ -840,6 +843,9 @@ static int move_data_block(struct inode *inode, block_t bidx,
f2fs_put_page(mpage, 1); f2fs_put_page(mpage, 1);
goto up_out; goto up_out;
} }
f2fs_update_iostat(fio.sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
lock_page(mpage); lock_page(mpage);
if (unlikely(mpage->mapping != META_MAPPING(fio.sbi) || if (unlikely(mpage->mapping != META_MAPPING(fio.sbi) ||
!PageUptodate(mpage))) { !PageUptodate(mpage))) {
......
...@@ -1300,7 +1300,13 @@ static int read_node_page(struct page *page, int op_flags) ...@@ -1300,7 +1300,13 @@ static int read_node_page(struct page *page, int op_flags)
} }
fio.new_blkaddr = fio.old_blkaddr = ni.blk_addr; fio.new_blkaddr = fio.old_blkaddr = ni.blk_addr;
return f2fs_submit_page_bio(&fio);
err = f2fs_submit_page_bio(&fio);
if (!err)
f2fs_update_iostat(sbi, FS_NODE_READ_IO, F2FS_BLKSIZE);
return err;
} }
/* /*
......
...@@ -781,9 +781,9 @@ void f2fs_record_iostat(struct f2fs_sb_info *sbi) ...@@ -781,9 +781,9 @@ void f2fs_record_iostat(struct f2fs_sb_info *sbi)
msecs_to_jiffies(sbi->iostat_period_ms); msecs_to_jiffies(sbi->iostat_period_ms);
for (i = 0; i < NR_IO_TYPE; i++) { for (i = 0; i < NR_IO_TYPE; i++) {
iostat_diff[i] = sbi->write_iostat[i] - iostat_diff[i] = sbi->rw_iostat[i] -
sbi->prev_write_iostat[i]; sbi->prev_rw_iostat[i];
sbi->prev_write_iostat[i] = sbi->write_iostat[i]; sbi->prev_rw_iostat[i] = sbi->rw_iostat[i];
} }
spin_unlock(&sbi->iostat_lock); spin_unlock(&sbi->iostat_lock);
...@@ -802,33 +802,51 @@ static int __maybe_unused iostat_info_seq_show(struct seq_file *seq, ...@@ -802,33 +802,51 @@ static int __maybe_unused iostat_info_seq_show(struct seq_file *seq,
seq_printf(seq, "time: %-16llu\n", now); seq_printf(seq, "time: %-16llu\n", now);
/* print app IOs */ /* print app write IOs */
seq_printf(seq, "app buffered: %-16llu\n", seq_printf(seq, "app buffered: %-16llu\n",
sbi->write_iostat[APP_BUFFERED_IO]); sbi->rw_iostat[APP_BUFFERED_IO]);
seq_printf(seq, "app direct: %-16llu\n", seq_printf(seq, "app direct: %-16llu\n",
sbi->write_iostat[APP_DIRECT_IO]); sbi->rw_iostat[APP_DIRECT_IO]);
seq_printf(seq, "app mapped: %-16llu\n", seq_printf(seq, "app mapped: %-16llu\n",
sbi->write_iostat[APP_MAPPED_IO]); sbi->rw_iostat[APP_MAPPED_IO]);
/* print fs IOs */ /* print fs write IOs */
seq_printf(seq, "fs data: %-16llu\n", seq_printf(seq, "fs data: %-16llu\n",
sbi->write_iostat[FS_DATA_IO]); sbi->rw_iostat[FS_DATA_IO]);
seq_printf(seq, "fs node: %-16llu\n", seq_printf(seq, "fs node: %-16llu\n",
sbi->write_iostat[FS_NODE_IO]); sbi->rw_iostat[FS_NODE_IO]);
seq_printf(seq, "fs meta: %-16llu\n", seq_printf(seq, "fs meta: %-16llu\n",
sbi->write_iostat[FS_META_IO]); sbi->rw_iostat[FS_META_IO]);
seq_printf(seq, "fs gc data: %-16llu\n", seq_printf(seq, "fs gc data: %-16llu\n",
sbi->write_iostat[FS_GC_DATA_IO]); sbi->rw_iostat[FS_GC_DATA_IO]);
seq_printf(seq, "fs gc node: %-16llu\n", seq_printf(seq, "fs gc node: %-16llu\n",
sbi->write_iostat[FS_GC_NODE_IO]); sbi->rw_iostat[FS_GC_NODE_IO]);
seq_printf(seq, "fs cp data: %-16llu\n", seq_printf(seq, "fs cp data: %-16llu\n",
sbi->write_iostat[FS_CP_DATA_IO]); sbi->rw_iostat[FS_CP_DATA_IO]);
seq_printf(seq, "fs cp node: %-16llu\n", seq_printf(seq, "fs cp node: %-16llu\n",
sbi->write_iostat[FS_CP_NODE_IO]); sbi->rw_iostat[FS_CP_NODE_IO]);
seq_printf(seq, "fs cp meta: %-16llu\n", seq_printf(seq, "fs cp meta: %-16llu\n",
sbi->write_iostat[FS_CP_META_IO]); sbi->rw_iostat[FS_CP_META_IO]);
/* print app read IOs */
seq_printf(seq, "app buffered: %-16llu\n",
sbi->rw_iostat[APP_BUFFERED_READ_IO]);
seq_printf(seq, "app direct: %-16llu\n",
sbi->rw_iostat[APP_DIRECT_READ_IO]);
seq_printf(seq, "app mapped: %-16llu\n",
sbi->rw_iostat[APP_MAPPED_READ_IO]);
/* print fs read IOs */
seq_printf(seq, "fs data: %-16llu\n",
sbi->rw_iostat[FS_DATA_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]);
/* print other IOs */
seq_printf(seq, "fs discard: %-16llu\n", seq_printf(seq, "fs discard: %-16llu\n",
sbi->write_iostat[FS_DISCARD]); sbi->rw_iostat[FS_DISCARD]);
return 0; return 0;
} }
......
...@@ -1832,6 +1832,13 @@ TRACE_EVENT(f2fs_iostat, ...@@ -1832,6 +1832,13 @@ TRACE_EVENT(f2fs_iostat,
__field(unsigned long long, fs_cp_dio) __field(unsigned long long, fs_cp_dio)
__field(unsigned long long, fs_cp_nio) __field(unsigned long long, fs_cp_nio)
__field(unsigned long long, fs_cp_mio) __field(unsigned long long, fs_cp_mio)
__field(unsigned long long, app_drio)
__field(unsigned long long, app_brio)
__field(unsigned long long, app_rio)
__field(unsigned long long, app_mrio)
__field(unsigned long long, fs_drio)
__field(unsigned long long, fs_nrio)
__field(unsigned long long, fs_mrio)
__field(unsigned long long, fs_discard) __field(unsigned long long, fs_discard)
), ),
...@@ -1849,6 +1856,13 @@ TRACE_EVENT(f2fs_iostat, ...@@ -1849,6 +1856,13 @@ TRACE_EVENT(f2fs_iostat,
__entry->fs_cp_dio = iostat[FS_CP_DATA_IO]; __entry->fs_cp_dio = iostat[FS_CP_DATA_IO];
__entry->fs_cp_nio = iostat[FS_CP_NODE_IO]; __entry->fs_cp_nio = iostat[FS_CP_NODE_IO];
__entry->fs_cp_mio = iostat[FS_CP_META_IO]; __entry->fs_cp_mio = iostat[FS_CP_META_IO];
__entry->app_drio = iostat[APP_DIRECT_READ_IO];
__entry->app_brio = iostat[APP_BUFFERED_READ_IO];
__entry->app_rio = iostat[APP_READ_IO];
__entry->app_mrio = iostat[APP_MAPPED_READ_IO];
__entry->fs_drio = iostat[FS_DATA_READ_IO];
__entry->fs_nrio = iostat[FS_NODE_READ_IO];
__entry->fs_mrio = iostat[FS_META_READ_IO];
__entry->fs_discard = iostat[FS_DISCARD]; __entry->fs_discard = iostat[FS_DISCARD];
), ),
...@@ -1856,12 +1870,17 @@ TRACE_EVENT(f2fs_iostat, ...@@ -1856,12 +1870,17 @@ TRACE_EVENT(f2fs_iostat,
"app [write=%llu (direct=%llu, buffered=%llu), mapped=%llu], " "app [write=%llu (direct=%llu, buffered=%llu), mapped=%llu], "
"fs [data=%llu, node=%llu, meta=%llu, discard=%llu], " "fs [data=%llu, node=%llu, meta=%llu, discard=%llu], "
"gc [data=%llu, node=%llu], " "gc [data=%llu, node=%llu], "
"cp [data=%llu, node=%llu, meta=%llu]", "cp [data=%llu, node=%llu, meta=%llu], "
"app [read=%llu (direct=%llu, buffered=%llu), mapped=%llu], "
"fs [data=%llu, node=%llu, meta=%llu]",
show_dev(__entry->dev), __entry->app_wio, __entry->app_dio, show_dev(__entry->dev), __entry->app_wio, __entry->app_dio,
__entry->app_bio, __entry->app_mio, __entry->fs_dio, __entry->app_bio, __entry->app_mio, __entry->fs_dio,
__entry->fs_nio, __entry->fs_mio, __entry->fs_discard, __entry->fs_nio, __entry->fs_mio, __entry->fs_discard,
__entry->fs_gc_dio, __entry->fs_gc_nio, __entry->fs_cp_dio, __entry->fs_gc_dio, __entry->fs_gc_nio, __entry->fs_cp_dio,
__entry->fs_cp_nio, __entry->fs_cp_mio) __entry->fs_cp_nio, __entry->fs_cp_mio,
__entry->app_rio, __entry->app_drio, __entry->app_brio,
__entry->app_mrio, __entry->fs_drio, __entry->fs_nrio,
__entry->fs_mrio)
); );
#endif /* _TRACE_F2FS_H */ #endif /* _TRACE_F2FS_H */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment