aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-01-11 16:06:33 -0500
committerJens Axboe <axboe@kernel.dk>2013-01-14 09:00:36 -0500
commit3a366e614d0837d9fc23f78cdb1a1186ebc3387f (patch)
tree5be6ec716687234ac1e6202db62c84ee1d2246be
parentac9a19745196388ae5d828c0be7a1d6e472101f3 (diff)
block: add missing block_bio_complete() tracepoint
bio completion didn't kick block_bio_complete TP. Only dm was explicitly triggering the TP on IO completion. This makes block_bio_complete TP useless for tracers which want to know about bios, and all other bio based drivers skip generating blktrace completion events. This patch makes all bio completions via bio_endio() generate block_bio_complete TP. * Explicit trace_block_bio_complete() invocation removed from dm and the trace point is unexported. * @rq dropped from trace_block_bio_complete(). bios may fly around w/o queue associated. Verifying and accessing the assocaited queue belongs to TP probes. * blktrace now gets both request and bio completions. Make it ignore bio completions if request completion path is happening. This makes all bio based drivers generate blktrace completion events properly and makes the block_bio_complete TP actually useful. v2: With this change, block_bio_complete TP could be invoked on sg commands which have bio's with %NULL bi_bdev. Update TP assignment code to check whether bio->bi_bdev is %NULL before dereferencing. Signed-off-by: Tejun Heo <tj@kernel.org> Original-patch-by: Namhyung Kim <namhyung@gmail.com> Cc: Tejun Heo <tj@kernel.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Alasdair Kergon <agk@redhat.com> Cc: dm-devel@redhat.com Cc: Neil Brown <neilb@suse.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--block/blk-core.c1
-rw-r--r--drivers/md/dm.c1
-rw-r--r--drivers/md/raid5.c11
-rw-r--r--fs/bio.c2
-rw-r--r--include/linux/blktrace_api.h1
-rw-r--r--include/trace/events/block.h8
-rw-r--r--kernel/trace/blktrace.c26
7 files changed, 31 insertions, 19 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index aca5d82ff13c..4f5aec708be6 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -39,7 +39,6 @@
39 39
40EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap); 40EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap);
41EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap); 41EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
42EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);
43EXPORT_TRACEPOINT_SYMBOL_GPL(block_unplug); 42EXPORT_TRACEPOINT_SYMBOL_GPL(block_unplug);
44 43
45DEFINE_IDA(blk_queue_ida); 44DEFINE_IDA(blk_queue_ida);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index c72e4d5a9617..650ec2866e34 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -627,7 +627,6 @@ static void dec_pending(struct dm_io *io, int error)
627 queue_io(md, bio); 627 queue_io(md, bio);
628 } else { 628 } else {
629 /* done with normal IO or empty flush */ 629 /* done with normal IO or empty flush */
630 trace_block_bio_complete(md->queue, bio, io_error);
631 bio_endio(bio, io_error); 630 bio_endio(bio, io_error);
632 } 631 }
633 } 632 }
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 19d77a026639..9ab506df42da 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -184,8 +184,6 @@ static void return_io(struct bio *return_bi)
184 return_bi = bi->bi_next; 184 return_bi = bi->bi_next;
185 bi->bi_next = NULL; 185 bi->bi_next = NULL;
186 bi->bi_size = 0; 186 bi->bi_size = 0;
187 trace_block_bio_complete(bdev_get_queue(bi->bi_bdev),
188 bi, 0);
189 bio_endio(bi, 0); 187 bio_endio(bi, 0);
190 bi = return_bi; 188 bi = return_bi;
191 } 189 }
@@ -3917,8 +3915,6 @@ static void raid5_align_endio(struct bio *bi, int error)
3917 rdev_dec_pending(rdev, conf->mddev); 3915 rdev_dec_pending(rdev, conf->mddev);
3918 3916
3919 if (!error && uptodate) { 3917 if (!error && uptodate) {
3920 trace_block_bio_complete(bdev_get_queue(raid_bi->bi_bdev),
3921 raid_bi, 0);
3922 bio_endio(raid_bi, 0); 3918 bio_endio(raid_bi, 0);
3923 if (atomic_dec_and_test(&conf->active_aligned_reads)) 3919 if (atomic_dec_and_test(&conf->active_aligned_reads))
3924 wake_up(&conf->wait_for_stripe); 3920 wake_up(&conf->wait_for_stripe);
@@ -4377,8 +4373,6 @@ static void make_request(struct mddev *mddev, struct bio * bi)
4377 if ( rw == WRITE ) 4373 if ( rw == WRITE )
4378 md_write_end(mddev); 4374 md_write_end(mddev);
4379 4375
4380 trace_block_bio_complete(bdev_get_queue(bi->bi_bdev),
4381 bi, 0);
4382 bio_endio(bi, 0); 4376 bio_endio(bi, 0);
4383 } 4377 }
4384} 4378}
@@ -4755,11 +4749,8 @@ static int retry_aligned_read(struct r5conf *conf, struct bio *raid_bio)
4755 handled++; 4749 handled++;
4756 } 4750 }
4757 remaining = raid5_dec_bi_active_stripes(raid_bio); 4751 remaining = raid5_dec_bi_active_stripes(raid_bio);
4758 if (remaining == 0) { 4752 if (remaining == 0)
4759 trace_block_bio_complete(bdev_get_queue(raid_bio->bi_bdev),
4760 raid_bio, 0);
4761 bio_endio(raid_bio, 0); 4753 bio_endio(raid_bio, 0);
4762 }
4763 if (atomic_dec_and_test(&conf->active_aligned_reads)) 4754 if (atomic_dec_and_test(&conf->active_aligned_reads))
4764 wake_up(&conf->wait_for_stripe); 4755 wake_up(&conf->wait_for_stripe);
4765 return handled; 4756 return handled;
diff --git a/fs/bio.c b/fs/bio.c
index b96fc6ce4855..bb5768f59b32 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1428,6 +1428,8 @@ void bio_endio(struct bio *bio, int error)
1428 else if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) 1428 else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
1429 error = -EIO; 1429 error = -EIO;
1430 1430
1431 trace_block_bio_complete(bio, error);
1432
1431 if (bio->bi_end_io) 1433 if (bio->bi_end_io)
1432 bio->bi_end_io(bio, error); 1434 bio->bi_end_io(bio, error);
1433} 1435}
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 7c2e030e72f1..0ea61e07a91c 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -12,6 +12,7 @@
12 12
13struct blk_trace { 13struct blk_trace {
14 int trace_state; 14 int trace_state;
15 bool rq_based;
15 struct rchan *rchan; 16 struct rchan *rchan;
16 unsigned long __percpu *sequence; 17 unsigned long __percpu *sequence;
17 unsigned char __percpu *msg_data; 18 unsigned char __percpu *msg_data;
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index 05c5e61f0a7c..8a168db9a645 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -206,7 +206,6 @@ TRACE_EVENT(block_bio_bounce,
206 206
207/** 207/**
208 * block_bio_complete - completed all work on the block operation 208 * block_bio_complete - completed all work on the block operation
209 * @q: queue holding the block operation
210 * @bio: block operation completed 209 * @bio: block operation completed
211 * @error: io error value 210 * @error: io error value
212 * 211 *
@@ -215,9 +214,9 @@ TRACE_EVENT(block_bio_bounce,
215 */ 214 */
216TRACE_EVENT(block_bio_complete, 215TRACE_EVENT(block_bio_complete,
217 216
218 TP_PROTO(struct request_queue *q, struct bio *bio, int error), 217 TP_PROTO(struct bio *bio, int error),
219 218
220 TP_ARGS(q, bio, error), 219 TP_ARGS(bio, error),
221 220
222 TP_STRUCT__entry( 221 TP_STRUCT__entry(
223 __field( dev_t, dev ) 222 __field( dev_t, dev )
@@ -228,7 +227,8 @@ TRACE_EVENT(block_bio_complete,
228 ), 227 ),
229 228
230 TP_fast_assign( 229 TP_fast_assign(
231 __entry->dev = bio->bi_bdev->bd_dev; 230 __entry->dev = bio->bi_bdev ?
231 bio->bi_bdev->bd_dev : 0;
232 __entry->sector = bio->bi_sector; 232 __entry->sector = bio->bi_sector;
233 __entry->nr_sector = bio->bi_size >> 9; 233 __entry->nr_sector = bio->bi_size >> 9;
234 __entry->error = error; 234 __entry->error = error;
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index c0bd0308741c..190d98fbed27 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -739,6 +739,12 @@ static void blk_add_trace_rq_complete(void *ignore,
739 struct request_queue *q, 739 struct request_queue *q,
740 struct request *rq) 740 struct request *rq)
741{ 741{
742 struct blk_trace *bt = q->blk_trace;
743
744 /* if control ever passes through here, it's a request based driver */
745 if (unlikely(bt && !bt->rq_based))
746 bt->rq_based = true;
747
742 blk_add_trace_rq(q, rq, BLK_TA_COMPLETE); 748 blk_add_trace_rq(q, rq, BLK_TA_COMPLETE);
743} 749}
744 750
@@ -774,10 +780,24 @@ static void blk_add_trace_bio_bounce(void *ignore,
774 blk_add_trace_bio(q, bio, BLK_TA_BOUNCE, 0); 780 blk_add_trace_bio(q, bio, BLK_TA_BOUNCE, 0);
775} 781}
776 782
777static void blk_add_trace_bio_complete(void *ignore, 783static void blk_add_trace_bio_complete(void *ignore, struct bio *bio, int error)
778 struct request_queue *q, struct bio *bio,
779 int error)
780{ 784{
785 struct request_queue *q;
786 struct blk_trace *bt;
787
788 if (!bio->bi_bdev)
789 return;
790
791 q = bdev_get_queue(bio->bi_bdev);
792 bt = q->blk_trace;
793
794 /*
795 * Request based drivers will generate both rq and bio completions.
796 * Ignore bio ones.
797 */
798 if (likely(!bt) || bt->rq_based)
799 return;
800
781 blk_add_trace_bio(q, bio, BLK_TA_COMPLETE, error); 801 blk_add_trace_bio(q, bio, BLK_TA_COMPLETE, error);
782} 802}
783 803