From: Zhang Yi To facilitate the tracing of ordered I/Os in the iomap buffered I/O path, add tracepoints to track the ordered I/O flow: - ext4_iomap_ordered_submit: trace when ordered I/O is being submitted; - ext4_iomap_ordered_complete: trace when ordered I/O completes; - ext4_iomap_disksize_update: trace when i_disksize is updated, either when appending I/O or when an ordered I/O completes; - ext4_block_zero_eof - trace zero EOF partial block. Signed-off-by: Zhang Yi --- fs/ext4/inode.c | 4 ++ fs/ext4/page-io.c | 9 ++++ include/trace/events/ext4.h | 97 +++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index e47b504e85c9..cf83b4e619e0 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4376,6 +4376,9 @@ static int ext4_iomap_writeback_submit(struct iomap_writepage_ctx *wpc, ioend->io_offset + ioend->io_size); if (start <= order_lblk && end >= order_lblk + order_len) { + trace_ext4_iomap_ordered_submit(ioend->io_inode, + ioend->io_offset, ioend->io_size, + order_lblk, order_len); ioend->io_bio.bi_end_io = ext4_iomap_end_bio; ioend->io_private = (void *)EXT4_IOMAP_IOEND_ORDER_IO; ioend->io_flags |= IOMAP_IOEND_BOUNDARY; @@ -4910,6 +4913,7 @@ int ext4_block_zero_eof(struct inode *inode, loff_t from, loff_t end) } } + trace_ext4_block_zero_eof(inode, from, length, did_zero, zero_written); return 0; } diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 2ad9f900c9f3..b5b32dc388be 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -31,6 +31,8 @@ #include "xattr.h" #include "acl.h" +#include + static struct kmem_cache *io_end_cachep; static struct kmem_cache *io_end_vec_cachep; @@ -682,6 +684,9 @@ static int ext4_iomap_wb_update_disksize(handle_t *handle, struct inode *inode, * not yet on disk, but stale data will never be exposed. */ new_disksize = is_ordered ? i_size : min(end, i_size); + trace_ext4_iomap_disksize_update(inode, end, i_size, ei->i_disksize, + new_disksize, is_ordered); + if (new_disksize > ei->i_disksize) ei->i_disksize = new_disksize; up_write(&ei->i_data_sem); @@ -784,6 +789,10 @@ void ext4_iomap_end_bio(struct bio *bio) * the inode i_disksize. */ if (io_mode == EXT4_IOMAP_IOEND_ORDER_IO) { + trace_ext4_iomap_ordered_complete(inode, ioend->io_offset, + ioend->io_size, READ_ONCE(ei->i_ordered_lblk), + READ_ONCE(ei->i_ordered_len)); + /* * Pairs with wait_event() in ext4_iomap_wb_ordered_wait(). * Ensure i_ordered_len = 0 is visible before waking up diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index ebafa06cd191..423aec6d09d1 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -3141,6 +3141,103 @@ DEFINE_SET_IOMAP_EVENT(ext4_iomap_buffered_write_begin); DEFINE_SET_IOMAP_EVENT(ext4_iomap_map_writeback_range); DEFINE_SET_IOMAP_EVENT(ext4_iomap_zero_begin); +/* Ordered I/O tracepoints for iomap buffered I/O path */ +DECLARE_EVENT_CLASS(ext4_iomap_ordered_io, + TP_PROTO(struct inode *inode, loff_t io_offset, size_t io_size, + ext4_lblk_t i_ordered_lblk, unsigned int i_ordered_len), + TP_ARGS(inode, io_offset, io_size, i_ordered_lblk, i_ordered_len), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u64, ino) + __field(loff_t, io_offset) + __field(size_t, io_size) + __field(ext4_lblk_t, i_ordered_lblk) + __field(unsigned int, i_ordered_len) + ), + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->io_offset = io_offset; + __entry->io_size = io_size; + __entry->i_ordered_lblk = i_ordered_lblk; + __entry->i_ordered_len = i_ordered_len; + ), + TP_printk("dev %d:%d ino %llu io_offset %lld io_size %zu i_ordered_lblk %u i_ordered_len %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->io_offset, __entry->io_size, + __entry->i_ordered_lblk, __entry->i_ordered_len) +); + +DEFINE_EVENT(ext4_iomap_ordered_io, ext4_iomap_ordered_submit, + TP_PROTO(struct inode *inode, loff_t io_offset, size_t io_size, + ext4_lblk_t i_ordered_lblk, unsigned int i_ordered_len), + TP_ARGS(inode, io_offset, io_size, i_ordered_lblk, i_ordered_len) +); + +DEFINE_EVENT(ext4_iomap_ordered_io, ext4_iomap_ordered_complete, + TP_PROTO(struct inode *inode, loff_t io_offset, size_t io_size, + ext4_lblk_t i_ordered_lblk, unsigned int i_ordered_len), + TP_ARGS(inode, io_offset, io_size, i_ordered_lblk, i_ordered_len) +); + + +/* i_disksize update tracepoint */ +TRACE_EVENT(ext4_iomap_disksize_update, + TP_PROTO(struct inode *inode, loff_t end, loff_t i_size, + loff_t i_disksize, loff_t new_disksize, bool is_ordered), + TP_ARGS(inode, end, i_size, i_disksize, new_disksize, is_ordered), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u64, ino) + __field(loff_t, end) + __field(loff_t, i_size) + __field(loff_t, i_disksize) + __field(loff_t, new_disksize) + __field(bool, is_ordered) + ), + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->end = end; + __entry->i_size = i_size; + __entry->i_disksize = i_disksize; + __entry->new_disksize = new_disksize; + __entry->is_ordered = is_ordered; + ), + TP_printk("dev %d:%d ino %llu end %lld i_size %lld i_disksize %lld new_disksize %lld is_ordered %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->end, __entry->i_size, + __entry->i_disksize, __entry->new_disksize, + __entry->is_ordered) +); + +/* Block zero EOF tracepoint */ +TRACE_EVENT(ext4_block_zero_eof, + TP_PROTO(struct inode *inode, loff_t from, loff_t length, + bool did_zero, bool zero_written), + TP_ARGS(inode, from, length, did_zero, zero_written), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u64, ino) + __field(loff_t, from) + __field(loff_t, length) + __field(bool, did_zero) + __field(bool, zero_written) + ), + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->from = from; + __entry->length = length; + __entry->did_zero = did_zero; + __entry->zero_written = zero_written; + ), + TP_printk("dev %d:%d ino %llu zero EOF from %lld length %lld did_zero %d zero_written %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->from, __entry->length, + __entry->did_zero, __entry->zero_written) +); + #endif /* _TRACE_EXT4_H */ /* This part must be outside protection */ -- 2.52.0