Message ID | 877f3iave6.fsf@notabene.neil.brown.name (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Mar 22, 2017 at 01:38:09PM +1100, NeilBrown wrote: > > Currently only dm and md/raid5 bios trigger trace_block_bio_complete(). > Now that we have bio_chain(), it is not possible, in general, for a > driver to know when the bio is really complete. Only bio_endio() > knows that. > > So move the trace_block_bio_complete() call to bio_endio(). This will cause duplicate events for request based drivers. You'll need to have a bio_endio_notrace or similar without that the request completion path can call.
On Wed, Mar 22 2017, Christoph Hellwig wrote: > On Wed, Mar 22, 2017 at 01:38:09PM +1100, NeilBrown wrote: >> >> Currently only dm and md/raid5 bios trigger trace_block_bio_complete(). >> Now that we have bio_chain(), it is not possible, in general, for a >> driver to know when the bio is really complete. Only bio_endio() >> knows that. >> >> So move the trace_block_bio_complete() call to bio_endio(). > > This will cause duplicate events for request based drivers. You'll > need to have a bio_endio_notrace or similar without that the request > completion path can call. Ah... I hadn't noticed that the request completion was the same event type as the bio completion... Thanks. Also after being processed by the request handler, bi_sector and bi_size have changed so the trace messsage would be wrong. I've sorted that out and will repost. Thanks, NeilBrown
diff --git a/block/bio.c b/block/bio.c index 5eec5e08417f..c89d83b3ca32 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1838,6 +1838,9 @@ void bio_endio(struct bio *bio) goto again; } + if (bio->bi_bdev) + trace_block_bio_complete(bdev_get_queue(bio->bi_bdev), + bio, bio->bi_error); if (bio->bi_end_io) bio->bi_end_io(bio); } diff --git a/drivers/md/dm.c b/drivers/md/dm.c index f4ffd1eb8f44..f5f09ace690a 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -810,7 +810,6 @@ static void dec_pending(struct dm_io *io, int error) queue_io(md, bio); } else { /* done with normal IO or empty flush */ - trace_block_bio_complete(md->queue, bio, io_error); bio->bi_error = io_error; bio_endio(bio); } diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 9a3b7da34137..f684cb566721 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5141,8 +5141,6 @@ static void raid5_align_endio(struct bio *bi) rdev_dec_pending(rdev, conf->mddev); if (!error) { - trace_block_bio_complete(bdev_get_queue(raid_bi->bi_bdev), - raid_bi, 0); bio_endio(raid_bi); if (atomic_dec_and_test(&conf->active_aligned_reads)) wake_up(&conf->wait_for_quiescent); @@ -5727,10 +5725,6 @@ static void raid5_make_request(struct mddev *mddev, struct bio * bi) md_write_end(mddev); remaining = raid5_dec_bi_active_stripes(bi); if (remaining == 0) { - - - trace_block_bio_complete(bdev_get_queue(bi->bi_bdev), - bi, 0); bio_endio(bi); } } @@ -6138,8 +6132,6 @@ static int retry_aligned_read(struct r5conf *conf, struct bio *raid_bio) } remaining = raid5_dec_bi_active_stripes(raid_bio); if (remaining == 0) { - trace_block_bio_complete(bdev_get_queue(raid_bio->bi_bdev), - raid_bio, 0); bio_endio(raid_bio); } if (atomic_dec_and_test(&conf->active_aligned_reads))
Currently only dm and md/raid5 bios trigger trace_block_bio_complete(). Now that we have bio_chain(), it is not possible, in general, for a driver to know when the bio is really complete. Only bio_endio() knows that. So move the trace_block_bio_complete() call to bio_endio(). Now trace_block_bio_complete() pairs with trace_block_bio_queue(). Any bio for which a 'queue' event is traced, will subsequently generate a 'complete' event. Signed-off-by: NeilBrown <neilb@suse.com> --- block/bio.c | 3 +++ drivers/md/dm.c | 1 - drivers/md/raid5.c | 8 -------- 3 files changed, 3 insertions(+), 9 deletions(-)