f2fs: support read iostat
authorChao Yu <yuchao0@huawei.com>
Thu, 16 Apr 2020 10:16:56 +0000 (18:16 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Fri, 17 Apr 2020 16:17:00 +0000 (09:17 -0700)
Adds to support accounting read IOs from userspace/kernel.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/checkpoint.c
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/file.c
fs/f2fs/gc.c
fs/f2fs/node.c
fs/f2fs/sysfs.c
include/trace/events/f2fs.h

index 6be357c8e00203b2c1399fe54008dcde26b26526..5ba649e17c72be1dc9a64ee1972b1825e3bb0cdb 100644 (file)
@@ -86,6 +86,8 @@ repeat:
                return ERR_PTR(err);
        }
 
+       f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE);
+
        lock_page(page);
        if (unlikely(page->mapping != mapping)) {
                f2fs_put_page(page, 1);
@@ -266,6 +268,9 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
                fio.page = page;
                err = f2fs_submit_page_bio(&fio);
                f2fs_put_page(page, err ? 1 : 0);
+
+               if (!err)
+                       f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE);
        }
 out:
        blk_finish_plug(&plug);
index accd28728642a2fbf7867c19ded0706d47360229..199877cb57fe27d7fcfb6015afc5278bf605ee82 100644 (file)
@@ -1033,6 +1033,7 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,
        }
        ClearPageError(page);
        inc_page_count(sbi, F2FS_RD_DATA);
+       f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
        __submit_bio(sbi, bio, DATA);
        return 0;
 }
@@ -2038,6 +2039,7 @@ submit_and_realloc:
                goto submit_and_realloc;
 
        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);
        *last_block_in_bio = block_nr;
        goto out;
@@ -2173,6 +2175,7 @@ submit_and_realloc:
                        goto submit_and_realloc;
 
                inc_page_count(sbi, F2FS_RD_DATA);
+               f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
                ClearPageError(page);
                *last_block_in_bio = blkaddr;
        }
@@ -3526,6 +3529,9 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
                } else if (err < 0) {
                        f2fs_write_failed(mapping, offset + count);
                }
+       } else {
+               if (err > 0)
+                       f2fs_update_iostat(sbi, APP_DIRECT_READ_IO, err);
        }
 
 out:
index 6cedbfb2067c508e820784d24c51a86e384f169b..3b9603266a2aa4d260175341c99b3a6f2a0a29f5 100644 (file)
@@ -1088,8 +1088,9 @@ enum cp_reason_type {
 };
 
 enum iostat_type {
-       APP_DIRECT_IO,                  /* app direct IOs */
-       APP_BUFFERED_IO,                /* app buffered IOs */
+       /* WRITE IO */
+       APP_DIRECT_IO,                  /* app direct write IOs */
+       APP_BUFFERED_IO,                /* app buffered write IOs */
        APP_WRITE_IO,                   /* app write IOs */
        APP_MAPPED_IO,                  /* app mapped IOs */
        FS_DATA_IO,                     /* data IOs from kworker/fsync/reclaimer */
@@ -1100,6 +1101,17 @@ enum iostat_type {
        FS_CP_DATA_IO,                  /* data IOs from checkpoint */
        FS_CP_NODE_IO,                  /* node 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 */
        NR_IO_TYPE,
 };
@@ -1504,8 +1516,8 @@ struct f2fs_sb_info {
 
        /* For app/fs IO statistics */
        spinlock_t iostat_lock;
-       unsigned long long write_iostat[NR_IO_TYPE];
-       unsigned long long prev_write_iostat[NR_IO_TYPE];
+       unsigned long long rw_iostat[NR_IO_TYPE];
+       unsigned long long prev_rw_iostat[NR_IO_TYPE];
        bool iostat_enable;
        unsigned long iostat_next_period;
        unsigned int iostat_period_ms;
@@ -3013,8 +3025,8 @@ static inline void f2fs_reset_iostat(struct f2fs_sb_info *sbi)
 
        spin_lock(&sbi->iostat_lock);
        for (i = 0; i < NR_IO_TYPE; i++) {
-               sbi->write_iostat[i] = 0;
-               sbi->prev_write_iostat[i] = 0;
+               sbi->rw_iostat[i] = 0;
+               sbi->prev_rw_iostat[i] = 0;
        }
        spin_unlock(&sbi->iostat_lock);
 }
@@ -3027,12 +3039,17 @@ static inline void f2fs_update_iostat(struct f2fs_sb_info *sbi,
        if (!sbi->iostat_enable)
                return;
        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)
-               sbi->write_iostat[APP_BUFFERED_IO] =
-                       sbi->write_iostat[APP_WRITE_IO] -
-                       sbi->write_iostat[APP_DIRECT_IO];
+               sbi->rw_iostat[APP_BUFFERED_IO] =
+                       sbi->rw_iostat[APP_WRITE_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);
 
        f2fs_record_iostat(sbi);
index 6ab8f621a3c5a25caa268c55f021488180efb3f2..a0a4413d6083bc4f06c67dc406893f300913a60e 100644 (file)
@@ -40,6 +40,10 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf)
        ret = filemap_fault(vmf);
        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);
 
        return ret;
@@ -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 inode *inode = file_inode(file);
+       int ret;
 
        if (!f2fs_is_compress_backend_ready(inode))
                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)
index 26248c8936db0f121ead3384215103399c8bb2dd..28a8c79c8bdc3076c06bdc04ebb2754af991fe22 100644 (file)
@@ -737,6 +737,9 @@ got_it:
                goto put_encrypted_page;
        f2fs_put_page(fio.encrypted_page, 0);
        f2fs_put_page(page, 1);
+
+       f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
+
        return 0;
 put_encrypted_page:
        f2fs_put_page(fio.encrypted_page, 1);
@@ -840,6 +843,9 @@ static int move_data_block(struct inode *inode, block_t bidx,
                        f2fs_put_page(mpage, 1);
                        goto up_out;
                }
+
+               f2fs_update_iostat(fio.sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
+
                lock_page(mpage);
                if (unlikely(mpage->mapping != META_MAPPING(fio.sbi) ||
                                                !PageUptodate(mpage))) {
index ecbd6bd14a494529a30590e30a26c6838c7bd4de..4da0d8713df5cb97ceecefa310cb27933bd12d93 100644 (file)
@@ -1300,7 +1300,13 @@ static int read_node_page(struct page *page, int op_flags)
        }
 
        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;
 }
 
 /*
index d05cb68c26374dc6f4a9fb9f6e50b3698d15eb1b..eaf8088548f080532f7c0ceb42d6a7c91659be65 100644 (file)
@@ -781,9 +781,9 @@ void f2fs_record_iostat(struct f2fs_sb_info *sbi)
                                msecs_to_jiffies(sbi->iostat_period_ms);
 
        for (i = 0; i < NR_IO_TYPE; i++) {
-               iostat_diff[i] = sbi->write_iostat[i] -
-                               sbi->prev_write_iostat[i];
-               sbi->prev_write_iostat[i] = sbi->write_iostat[i];
+               iostat_diff[i] = sbi->rw_iostat[i] -
+                               sbi->prev_rw_iostat[i];
+               sbi->prev_rw_iostat[i] = sbi->rw_iostat[i];
        }
        spin_unlock(&sbi->iostat_lock);
 
@@ -802,33 +802,51 @@ static int __maybe_unused iostat_info_seq_show(struct seq_file *seq,
 
        seq_printf(seq, "time:          %-16llu\n", now);
 
-       /* print app IOs */
+       /* print app write IOs */
        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",
-                               sbi->write_iostat[APP_DIRECT_IO]);
+                               sbi->rw_iostat[APP_DIRECT_IO]);
        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",
-                               sbi->write_iostat[FS_DATA_IO]);
+                               sbi->rw_iostat[FS_DATA_IO]);
        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",
-                               sbi->write_iostat[FS_META_IO]);
+                               sbi->rw_iostat[FS_META_IO]);
        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",
-                               sbi->write_iostat[FS_GC_NODE_IO]);
+                               sbi->rw_iostat[FS_GC_NODE_IO]);
        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",
-                               sbi->write_iostat[FS_CP_NODE_IO]);
+                               sbi->rw_iostat[FS_CP_NODE_IO]);
        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",
-                               sbi->write_iostat[FS_DISCARD]);
+                               sbi->rw_iostat[FS_DISCARD]);
 
        return 0;
 }
index e78c8696e2adc0a30298ad12918b709783ad5f9f..417a486f5c8a9be4220a9934804a8dba5660023b 100644 (file)
@@ -1832,6 +1832,13 @@ TRACE_EVENT(f2fs_iostat,
                __field(unsigned long long,     fs_cp_dio)
                __field(unsigned long long,     fs_cp_nio)
                __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)
        ),
 
@@ -1849,6 +1856,13 @@ TRACE_EVENT(f2fs_iostat,
                __entry->fs_cp_dio      = iostat[FS_CP_DATA_IO];
                __entry->fs_cp_nio      = iostat[FS_CP_NODE_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];
        ),
 
@@ -1856,12 +1870,17 @@ TRACE_EVENT(f2fs_iostat,
                "app [write=%llu (direct=%llu, buffered=%llu), mapped=%llu], "
                "fs [data=%llu, node=%llu, meta=%llu, discard=%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,
                __entry->app_bio, __entry->app_mio, __entry->fs_dio,
                __entry->fs_nio, __entry->fs_mio, __entry->fs_discard,
                __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 */