Skip to contentSkip to conversation

Blktrace port to tracepoints

PATCH New Mathieu Desnoyers 1 participant 1 message Jul 17, 2008

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Blktrace port to tracepoints

Port blktrace to the tracepoint infrastructure. It's just like markers, but without the format strings. Type checking of probes and call sites is done at probe registration. A reference count of blktrace users is kept. As soon as it is higher than 0, the probes are connected, which means that the branch is activated to enable the function calls and that the function addresses are added to the list of function to call for these tracepoints.

By the way, I think something is silly with the current blk_trace_remove logic :
if a remove is done on a running trace, a memory leak will potentially occur because the "bt" ressource will never be freed, but the pointer will not be in the request queue anymore. There is no attempt to fix this already existing bug here.

This patch depends on the "Tracepoints" patch.

CC Jens Axboe <[email protected]>
CC 'Peter Zijlstra' <[email protected]>
---
 block/Kconfig                |    1 
 block/blk-core.c             |   27 +++---
 block/blktrace.c             |  188 ++++++++++++++++++++++++++++++++++++++++++-
 block/elevator.c             |    5 -
 drivers/md/dm.c              |    5 -
 fs/bio.c                     |    3 
 include/linux/blktrace_api.h |  132 ------------------------------
 include/trace/block.h        |   25 +++++
 mm/bounce.c                  |    3 
 9 files changed, 235 insertions(+), 154 deletions(-)
include/trace/block.h new file +25 -0
Index: linux-2.6-lttng/include/trace/block.h
===================================================================
@@ -0,0 +1,25 @@
+#ifndef _TRACE_BLOCK_H
+#define _TRACE_BLOCK_H
+
+#include <linux/blkdev.h>
+#include <linux/tracepoint.h>
+
+DEFINE_TRACE(block_rq,
+	TPPROTO(struct request_queue *q, struct request *rq, u32 what),
+	TPARGS(q, rq, what));
+DEFINE_TRACE(block_bio,
+	TPPROTO(struct request_queue *q, struct bio *bio, u32 what),
+	TPARGS(q, bio, what));
+DEFINE_TRACE(block_generic,
+	TPPROTO(struct request_queue *q, struct bio *bio, int rw, u32 what),
+	TPARGS(q, bio, rw, what));
+DEFINE_TRACE(block_pdu_int,
+	TPPROTO(struct request_queue *q, u32 what, struct bio *bio,
+		unsigned int pdu),
+	TPARGS(q, what, bio, pdu));
+DEFINE_TRACE(block_remap,
+	TPPROTO(struct request_queue *q, struct bio *bio, dev_t dev,
+		sector_t from, sector_t to),
+	TPARGS(q, bio, dev, from, to));
+
+#endif
block/blk-core.c +14 -13
Index: linux-2.6-lttng/block/blk-core.c
===================================================================
@@ -30,6 +30,7 @@
 #include <linux/cpu.h>
 #include <linux/blktrace_api.h>
 #include <linux/fault-inject.h>
+#include <trace/block.h>
 
 #include "blk.h"
 
@@ -207,7 +208,7 @@ void blk_plug_device(struct request_queu
 
 	if (!queue_flag_test_and_set(QUEUE_FLAG_PLUGGED, q)) {
 		mod_timer(&q->unplug_timer, jiffies + q->unplug_delay);
-		blk_add_trace_generic(q, NULL, 0, BLK_TA_PLUG);
+		trace_block_generic(q, NULL, 0, BLK_TA_PLUG);
 	}
 }
 EXPORT_SYMBOL(blk_plug_device);
@@ -277,7 +278,7 @@ void blk_unplug_work(struct work_struct 
 	struct request_queue *q =
 		container_of(work, struct request_queue, unplug_work);
 
-	blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_IO, NULL,
+	trace_block_pdu_int(q, BLK_TA_UNPLUG_IO, NULL,
 				q->rq.count[READ] + q->rq.count[WRITE]);
 
 	q->unplug_fn(q);
@@ -287,7 +288,7 @@ void blk_unplug_timeout(unsigned long da
 {
 	struct request_queue *q = (struct request_queue *)data;
 
-	blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_TIMER, NULL,
+	trace_block_pdu_int(q, BLK_TA_UNPLUG_TIMER, NULL,
 				q->rq.count[READ] + q->rq.count[WRITE]);
 
 	kblockd_schedule_work(&q->unplug_work);
@@ -299,7 +300,7 @@ void blk_unplug(struct request_queue *q)
 	 * devices don't necessarily have an ->unplug_fn defined
 	 */
 	if (q->unplug_fn) {
-		blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_IO, NULL,
+		trace_block_pdu_int(q, BLK_TA_UNPLUG_IO, NULL,
 					q->rq.count[READ] + q->rq.count[WRITE]);
 
 		q->unplug_fn(q);
@@ -786,7 +787,7 @@ rq_starved:
 	if (ioc_batching(q, ioc))
 		ioc->nr_batch_requests--;
 
-	blk_add_trace_generic(q, bio, rw, BLK_TA_GETRQ);
+	trace_block_generic(q, bio, rw, BLK_TA_GETRQ);
 out:
 	return rq;
 }
@@ -812,7 +813,7 @@ static struct request *get_request_wait(
 		prepare_to_wait_exclusive(&rl->wait[rw], &wait,
 				TASK_UNINTERRUPTIBLE);
 
-		blk_add_trace_generic(q, bio, rw, BLK_TA_SLEEPRQ);
+		trace_block_generic(q, bio, rw, BLK_TA_SLEEPRQ);
 
 		__generic_unplug_device(q);
 		spin_unlock_irq(q->queue_lock);
@@ -887,7 +888,7 @@ EXPORT_SYMBOL(blk_start_queueing);
  */
 void blk_requeue_request(struct request_queue *q, struct request *rq)
 {
-	blk_add_trace_rq(q, rq, BLK_TA_REQUEUE);
+	trace_block_rq(q, rq, BLK_TA_REQUEUE);
 
 	if (blk_rq_tagged(rq))
 		blk_queue_end_tag(q, rq);
@@ -1112,7 +1113,7 @@ static int __make_request(struct request
 		if (!ll_back_merge_fn(q, req, bio))
 			break;
 
-		blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE);
+		trace_block_bio(q, bio, BLK_TA_BACKMERGE);
 
 		req->biotail->bi_next = bio;
 		req->biotail = bio;
@@ -1129,7 +1130,7 @@ static int __make_request(struct request
 		if (!ll_front_merge_fn(q, req, bio))
 			break;
 
-		blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE);
+		trace_block_bio(q, bio, BLK_TA_FRONTMERGE);
 
 		bio->bi_next = req->bio;
 		req->bio = bio;
@@ -1208,7 +1209,7 @@ static inline void blk_partition_remap(s
 		bio->bi_sector += p->start_sect;
 		bio->bi_bdev = bdev->bd_contains;
 
-		blk_add_trace_remap(bdev_get_queue(bio->bi_bdev), bio,
+		trace_block_remap(bdev_get_queue(bio->bi_bdev), bio,
 				    bdev->bd_dev, bio->bi_sector,
 				    bio->bi_sector - p->start_sect);
 	}
@@ -1379,10 +1380,10 @@ end_io:
 			goto end_io;
 
 		if (old_sector != -1)
-			blk_add_trace_remap(q, bio, old_dev, bio->bi_sector,
+			trace_block_remap(q, bio, old_dev, bio->bi_sector,
 					    old_sector);
 
-		blk_add_trace_bio(q, bio, BLK_TA_QUEUE);
+		trace_block_bio(q, bio, BLK_TA_QUEUE);
 
 		old_sector = bio->bi_sector;
 		old_dev = bio->bi_bdev->bd_dev;
@@ -1516,7 +1517,7 @@ static int __end_that_request_first(stru
 	int total_bytes, bio_nbytes, next_idx = 0;
 	struct bio *bio;
 
-	blk_add_trace_rq(req->q, req, BLK_TA_COMPLETE);
+	trace_block_rq(req->q, req, BLK_TA_COMPLETE);
 
 	/*
 	 * for a REQ_BLOCK_PC request, we want to carry any eventual
block/elevator.c +3 -2
Index: linux-2.6-lttng/block/elevator.c
===================================================================
@@ -34,6 +34,7 @@
 #include <linux/delay.h>
 #include <linux/blktrace_api.h>
 #include <linux/hash.h>
+#include <trace/block.h>
 
 #include <asm/uaccess.h>
 
@@ -577,7 +578,7 @@ void elv_insert(struct request_queue *q,
 	unsigned ordseq;
 	int unplug_it = 1;
 
-	blk_add_trace_rq(q, rq, BLK_TA_INSERT);
+	trace_block_rq(q, rq, BLK_TA_INSERT);
 
 	rq->q = q;
 
@@ -763,7 +764,7 @@ struct request *elv_next_request(struct 
 			 * not be passed by new incoming requests
 			 */
 			rq->cmd_flags |= REQ_STARTED;
-			blk_add_trace_rq(q, rq, BLK_TA_ISSUE);
+			trace_block_rq(q, rq, BLK_TA_ISSUE);
 		}
 
 		if (!q->boundary_rq || q->boundary_rq == rq) {
fs/bio.c +2 -1
Index: linux-2.6-lttng/fs/bio.c
===================================================================
@@ -26,6 +26,7 @@
 #include <linux/mempool.h>
 #include <linux/workqueue.h>
 #include <linux/blktrace_api.h>
+#include <trace/block.h>
 #include <scsi/sg.h>		/* for struct sg_iovec */
 
 static struct kmem_cache *bio_slab __read_mostly;
@@ -1226,7 +1227,7 @@ struct bio_pair *bio_split(struct bio *b
 	if (!bp)
 		return bp;
 
-	blk_add_trace_pdu_int(bdev_get_queue(bi->bi_bdev), BLK_TA_SPLIT, bi,
+	trace_block_pdu_int(bdev_get_queue(bi->bi_bdev), BLK_TA_SPLIT, bi,
 				bi->bi_sector + first_sectors);
 
 	BUG_ON(bi->bi_vcnt != 1);
block/Kconfig +1 -0
Index: linux-2.6-lttng/block/Kconfig
===================================================================
@@ -47,6 +47,7 @@ config BLK_DEV_IO_TRACE
 	depends on SYSFS
 	select RELAY
 	select DEBUG_FS
+	select TRACEPOINTS
 	help
 	  Say Y here if you want to be able to trace the block layer actions
 	  on a given queue. Tracing allows you to see any traffic happening
drivers/md/dm.c +3 -2
Index: linux-2.6-lttng/drivers/md/dm.c
===================================================================
@@ -22,6 +22,7 @@
 #include <linux/hdreg.h>
 #include <linux/blktrace_api.h>
 #include <linux/smp_lock.h>
+#include <trace/block.h>
 
 #define DM_MSG_PREFIX "core"
 
@@ -514,7 +515,7 @@ static void dec_pending(struct dm_io *io
 			wake_up(&io->md->wait);
 
 		if (io->error != DM_ENDIO_REQUEUE) {
-			blk_add_trace_bio(io->md->queue, io->bio,
+			trace_block_bio(io->md->queue, io->bio,
 					  BLK_TA_COMPLETE);
 
 			bio_endio(io->bio, io->error);
@@ -608,7 +609,7 @@ static void __map_bio(struct dm_target *
 	if (r == DM_MAPIO_REMAPPED) {
 		/* the bio has been remapped so dispatch it */
 
-		blk_add_trace_remap(bdev_get_queue(clone->bi_bdev), clone,
+		trace_block_remap(bdev_get_queue(clone->bi_bdev), clone,
 				    tio->io->bio->bi_bdev->bd_dev,
 				    clone->bi_sector, sector);
 
mm/bounce.c +2 -1
Index: linux-2.6-lttng/mm/bounce.c
===================================================================
@@ -14,6 +14,7 @@
 #include <linux/hash.h>
 #include <linux/highmem.h>
 #include <linux/blktrace_api.h>
+#include <trace/block.h>
 #include <asm/tlbflush.h>
 
 #define POOL_SIZE	64
@@ -222,7 +223,7 @@ static void __blk_queue_bounce(struct re
 	if (!bio)
 		return;
 
-	blk_add_trace_bio(q, *bio_orig, BLK_TA_BOUNCE);
+	trace_block_bio(q, *bio_orig, BLK_TA_BOUNCE);
 
 	/*
 	 * at least one page was bounced, fill in possible non-highmem
block/blktrace.c +185 -3

231 lines not on this page · raw message

include/linux/blktrace_api.h +0 -132

144 lines not on this page · raw message

Signature · 2 lines
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68