a4b6817625
Whenever we notice some sluggish issues on our machines, we are always curious about how well all types of I/O in the f2fs filesystem are handled. But, it's hard to get this kind of real data. First of all, we need to reproduce the issue while turning on the profiling tool like blktrace, but the issue doesn't happen again easily. Second, with the intervention of any tools, the overall timing of the issue will be slightly changed and it sometimes makes us hard to figure it out. So, I added the feature printing out IO latency statistics tracepoint events, which are minimal things to understand filesystem's I/O related behaviors, into F2FS_IOSTAT kernel config. With "iostat_enable" sysfs node on, we can get this statistics info in a periodic way and it would cause the least overhead. [samples] f2fs_ckpt-254:1-507 [003] .... 2842.439683: f2fs_iostat_latency: dev = (254,11), iotype [peak lat.(ms)/avg lat.(ms)/count], rd_data [136/1/801], rd_node [136/1/1704], rd_meta [4/2/4], wr_sync_data [164/16/3331], wr_sync_node [152/3/648], wr_sync_meta [160/2/4243], wr_async_data [24/13/15], wr_async_node [0/0/0], wr_async_meta [0/0/0] f2fs_ckpt-254:1-507 [002] .... 2845.450514: f2fs_iostat_latency: dev = (254,11), iotype [peak lat.(ms)/avg lat.(ms)/count], rd_data [60/3/456], rd_node [60/3/1258], rd_meta [0/0/1], wr_sync_data [120/12/2285], wr_sync_node [88/5/428], wr_sync_meta [52/6/2990], wr_async_data [4/1/3], wr_async_node [0/0/0], wr_async_meta [0/0/0] Signed-off-by: Daeho Jeong <daehojeong@google.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
85 lines
2.6 KiB
C
85 lines
2.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright 2021 Google LLC
|
|
* Author: Daeho Jeong <daehojeong@google.com>
|
|
*/
|
|
#ifndef __F2FS_IOSTAT_H__
|
|
#define __F2FS_IOSTAT_H__
|
|
|
|
struct bio_post_read_ctx;
|
|
|
|
#ifdef CONFIG_F2FS_IOSTAT
|
|
|
|
#define DEFAULT_IOSTAT_PERIOD_MS 3000
|
|
#define MIN_IOSTAT_PERIOD_MS 100
|
|
/* maximum period of iostat tracing is 1 day */
|
|
#define MAX_IOSTAT_PERIOD_MS 8640000
|
|
|
|
enum {
|
|
READ_IO,
|
|
WRITE_SYNC_IO,
|
|
WRITE_ASYNC_IO,
|
|
MAX_IO_TYPE,
|
|
};
|
|
|
|
struct iostat_lat_info {
|
|
unsigned long sum_lat[MAX_IO_TYPE][NR_PAGE_TYPE]; /* sum of io latencies */
|
|
unsigned long peak_lat[MAX_IO_TYPE][NR_PAGE_TYPE]; /* peak io latency */
|
|
unsigned int bio_cnt[MAX_IO_TYPE][NR_PAGE_TYPE]; /* bio count */
|
|
};
|
|
|
|
extern int __maybe_unused iostat_info_seq_show(struct seq_file *seq,
|
|
void *offset);
|
|
extern void f2fs_reset_iostat(struct f2fs_sb_info *sbi);
|
|
extern void f2fs_update_iostat(struct f2fs_sb_info *sbi,
|
|
enum iostat_type type, unsigned long long io_bytes);
|
|
|
|
struct bio_iostat_ctx {
|
|
struct f2fs_sb_info *sbi;
|
|
unsigned long submit_ts;
|
|
enum page_type type;
|
|
struct bio_post_read_ctx *post_read_ctx;
|
|
};
|
|
|
|
static inline void iostat_update_submit_ctx(struct bio *bio,
|
|
enum page_type type)
|
|
{
|
|
struct bio_iostat_ctx *iostat_ctx = bio->bi_private;
|
|
|
|
iostat_ctx->submit_ts = jiffies;
|
|
iostat_ctx->type = type;
|
|
}
|
|
|
|
static inline struct bio_post_read_ctx *get_post_read_ctx(struct bio *bio)
|
|
{
|
|
struct bio_iostat_ctx *iostat_ctx = bio->bi_private;
|
|
|
|
return iostat_ctx->post_read_ctx;
|
|
}
|
|
|
|
extern void iostat_update_and_unbind_ctx(struct bio *bio, int rw);
|
|
extern void iostat_alloc_and_bind_ctx(struct f2fs_sb_info *sbi,
|
|
struct bio *bio, struct bio_post_read_ctx *ctx);
|
|
extern int f2fs_init_iostat_processing(void);
|
|
extern void f2fs_destroy_iostat_processing(void);
|
|
extern int f2fs_init_iostat(struct f2fs_sb_info *sbi);
|
|
extern void f2fs_destroy_iostat(struct f2fs_sb_info *sbi);
|
|
#else
|
|
static inline void f2fs_update_iostat(struct f2fs_sb_info *sbi,
|
|
enum iostat_type type, unsigned long long io_bytes) {}
|
|
static inline void iostat_update_and_unbind_ctx(struct bio *bio, int rw) {}
|
|
static inline void iostat_alloc_and_bind_ctx(struct f2fs_sb_info *sbi,
|
|
struct bio *bio, struct bio_post_read_ctx *ctx) {}
|
|
static inline void iostat_update_submit_ctx(struct bio *bio,
|
|
enum page_type type) {}
|
|
static inline struct bio_post_read_ctx *get_post_read_ctx(struct bio *bio)
|
|
{
|
|
return bio->bi_private;
|
|
}
|
|
static inline int f2fs_init_iostat_processing(void) { return 0; }
|
|
static inline void f2fs_destroy_iostat_processing(void) {}
|
|
static inline int f2fs_init_iostat(struct f2fs_sb_info *sbi) { return 0; }
|
|
static inline void f2fs_destroy_iostat(struct f2fs_sb_info *sbi) {}
|
|
#endif
|
|
#endif /* __F2FS_IOSTAT_H__ */
|