From a5fdb883c537dcd1e7a35765316cd7320fc7395c Mon Sep 17 00:00:00 2001 From: Nicolas Droux Date: Thu, 25 May 2017 15:22:32 -0600 Subject: [PATCH] dtrace: improve io provider coverage The DTrace io provider coverage is extended to include IO performed through the Generic Block Layer (bio). It also adds io provider probes to XFS. Orabug: 25816537 Signed-off-by: Nicolas Droux Acked-by: Nick Alcock Reviewed-by: Darrick J. Wong Reviewed-by: Shan Hai --- block/bio.c | 8 ++++++++ block/blk-core.c | 7 ++++--- fs/buffer.c | 5 ----- fs/xfs/xfs_buf.c | 14 ++++++++++++++ include/linux/blk_types.h | 2 +- include/linux/sdt.h | 3 +++ 6 files changed, 30 insertions(+), 9 deletions(-) diff --git a/block/bio.c b/block/bio.c index cbce3e2208f4..49a313b9807e 100644 --- a/block/bio.c +++ b/block/bio.c @@ -906,7 +906,11 @@ int submit_bio_wait(int rw, struct bio *bio) bio->bi_private = &ret; bio->bi_end_io = submit_bio_wait_endio; submit_bio(rw, bio); + DTRACE_IO(wait__start, struct bio * : (bufinfo_t *, devinfo_t *), bio, + struct file * : fileinfo_t *, NULL); wait_for_completion(&ret.event); + DTRACE_IO(wait__done, struct bio * : (bufinfo_t *, devinfo_t *), bio, + struct file * : fileinfo_t *, NULL); return ret.error; } @@ -1784,6 +1788,10 @@ void bio_endio(struct bio *bio, int error) bio_put(bio); bio = parent; } else { + DTRACE_IO(done, struct bio * : + (bufinfo_t *, devinfo_t *), bio, + struct file * : fileinfo_t *, NULL); + if (bio->bi_end_io) bio->bi_end_io(bio, error); bio = NULL; diff --git a/block/blk-core.c b/block/blk-core.c index 1d1a050d2853..538656a61b7b 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1699,9 +1699,6 @@ static inline void blk_partition_remap(struct bio *bio) if (bio_sectors(bio) && bdev != bdev->bd_contains) { struct hd_struct *p = bdev->bd_part; -#ifdef CONFIG_DTRACE - bio->bi_bdev_orig = bdev; -#endif bio->bi_iter.bi_sector += p->start_sect; bio->bi_bdev = bdev->bd_contains; @@ -1874,9 +1871,13 @@ generic_make_request_checks(struct bio *bio) return false; /* throttled, will be resubmitted later */ trace_block_bio_queue(q, bio); + DTRACE_IO(start, struct bio * : (bufinfo_t *, devinfo_t *), bio, + struct file * : fileinfo_t *, NULL); return true; end_io: + DTRACE_IO(start, struct bio * : (bufinfo_t *, devinfo_t *), bio, + struct file * : fileinfo_t *, NULL); bio_endio(bio, err); return false; } diff --git a/fs/buffer.c b/fs/buffer.c index 552bff810a16..c7a5602d01ee 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -116,9 +116,7 @@ EXPORT_SYMBOL(buffer_check_dirty_writeback); */ void __wait_on_buffer(struct buffer_head * bh) { - DTRACE_IO(wait__start, struct buffer_head * : (bufinfo_t *, devinfo_t *, fileinfo_t *), bh); wait_on_bit_io(&bh->b_state, BH_Lock, TASK_UNINTERRUPTIBLE); - DTRACE_IO(wait__done, struct buffer_head * : (bufinfo_t *, devinfo_t *, fileinfo_t *), bh); } EXPORT_SYMBOL(__wait_on_buffer); @@ -2947,7 +2945,6 @@ static void end_bio_bh_io_sync(struct bio *bio, int err) if (unlikely (test_bit(BIO_QUIET,&bio->bi_flags))) set_bit(BH_Quiet, &bh->b_state); - DTRACE_IO(done, struct buffer_head * : (bufinfo_t *, devinfo_t *, fileinfo_t *), bh, int, bio->bi_rw); bh->b_end_io(bh, test_bit(BIO_UPTODATE, &bio->bi_flags)); bio_put(bio); } @@ -3045,8 +3042,6 @@ int _submit_bh(int rw, struct buffer_head *bh, unsigned long bio_flags) rw |= REQ_PRIO; bio_get(bio); - DTRACE_IO(start, struct buffer_head * : (bufinfo_t *, devinfo_t *, - fileinfo_t *), bh, int, rw); submit_bio(rw, bio); if (bio_flagged(bio, BIO_EOPNOTSUPP)) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index b422a2a797a7..bb92da29b2c3 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -57,6 +57,18 @@ static kmem_zone_t *xfs_buf_zone; #define xb_to_gfp(flags) \ ((((flags) & XBF_READ_AHEAD) ? __GFP_NORETRY : GFP_NOFS) | __GFP_NOWARN) +#define DTRACE_IO_XFS_WAIT(name, bp) \ + if (DTRACE_IO_ENABLED(name)) { \ + struct bio bio = { \ + .bi_iter.bi_sector = (bp)->b_bn, \ + .bi_iter.bi_size = (bp)->b_length, \ + .bi_rw = ((bp)->b_flags & XBF_WRITE) != 0, \ + .bi_bdev = (bp)->b_target->bt_bdev, \ + }; \ + DTRACE_IO(name, struct bio * : (bufinfo_t *, \ + devinfo_t *), &bio, \ + struct file * : fileinfo_t *, NULL); \ + } static inline int xfs_buf_is_vmapped( @@ -1407,7 +1419,9 @@ xfs_buf_submit_wait( /* wait for completion before gathering the error from the buffer */ trace_xfs_buf_iowait(bp, _RET_IP_); + DTRACE_IO_XFS_WAIT(wait__start, bp); wait_for_completion(&bp->b_iowait); + DTRACE_IO_XFS_WAIT(wait__done, bp); trace_xfs_buf_iowait_done(bp, _RET_IP_); error = bp->b_error; diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 4b5f5e73553a..6d19dbaf9a78 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -47,7 +47,7 @@ struct bio { struct bio *bi_next; /* request queue link */ struct block_device *bi_bdev; /* bdev (possibly remapped) */ #ifdef CONFIG_DTRACE - struct block_device *bi_bdev_orig; /* bdev before remapping */ + struct block_device *bi_bdev_orig; /* for kABI compatibility */ #endif unsigned long bi_flags; /* status, command, etc */ unsigned long bi_rw; /* bottom bits READ/WRITE, diff --git a/include/linux/sdt.h b/include/linux/sdt.h index d585ed612874..68a31cecd5f2 100644 --- a/include/linux/sdt.h +++ b/include/linux/sdt.h @@ -101,6 +101,9 @@ typedef struct sdt_probedesc { #define DTRACE_IO(name, ...) \ DTRACE_PROBE(__io_##name, ## __VA_ARGS__); +#define DTRACE_IO_ENABLED(name) \ + DTRACE_PROBE_ENABLED(__io_##name) + #define DTRACE_ISCSI(name, ...) \ DTRACE_PROBE(__iscsi_##name, ## __VA_ARGS__); -- 2.50.1