NVMe: Add tracepoints

Adding tracepoints for bio_complete and block_split into nvme to help
with gathering IO info using blktrace and blkparse.

Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com>
This commit is contained in:
Keith Busch 2014-04-28 12:30:52 -06:00 committed by Matthew Wilcox
parent 94bbac4052
commit 3291fa57cb
2 changed files with 10 additions and 4 deletions

View File

@ -43,6 +43,7 @@
EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap); EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap);
EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap); EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete); EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);
EXPORT_TRACEPOINT_SYMBOL_GPL(block_split);
EXPORT_TRACEPOINT_SYMBOL_GPL(block_unplug); EXPORT_TRACEPOINT_SYMBOL_GPL(block_unplug);
DEFINE_IDA(blk_queue_ida); DEFINE_IDA(blk_queue_ida);

View File

@ -42,6 +42,8 @@
#include <scsi/sg.h> #include <scsi/sg.h>
#include <asm-generic/io-64-nonatomic-lo-hi.h> #include <asm-generic/io-64-nonatomic-lo-hi.h>
#include <trace/events/block.h>
#define NVME_Q_DEPTH 1024 #define NVME_Q_DEPTH 1024
#define SQ_SIZE(depth) (depth * sizeof(struct nvme_command)) #define SQ_SIZE(depth) (depth * sizeof(struct nvme_command))
#define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion)) #define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion))
@ -411,6 +413,7 @@ static void bio_completion(struct nvme_queue *nvmeq, void *ctx,
struct nvme_iod *iod = ctx; struct nvme_iod *iod = ctx;
struct bio *bio = iod->private; struct bio *bio = iod->private;
u16 status = le16_to_cpup(&cqe->status) >> 1; u16 status = le16_to_cpup(&cqe->status) >> 1;
int error = 0;
if (unlikely(status)) { if (unlikely(status)) {
if (!(status & NVME_SC_DNR || if (!(status & NVME_SC_DNR ||
@ -423,6 +426,7 @@ static void bio_completion(struct nvme_queue *nvmeq, void *ctx,
wake_up(&nvmeq->sq_full); wake_up(&nvmeq->sq_full);
return; return;
} }
error = -EIO;
} }
if (iod->nents) { if (iod->nents) {
dma_unmap_sg(nvmeq->q_dmadev, iod->sg, iod->nents, dma_unmap_sg(nvmeq->q_dmadev, iod->sg, iod->nents,
@ -430,10 +434,9 @@ static void bio_completion(struct nvme_queue *nvmeq, void *ctx,
nvme_end_io_acct(bio, iod->start_time); nvme_end_io_acct(bio, iod->start_time);
} }
nvme_free_iod(nvmeq->dev, iod); nvme_free_iod(nvmeq->dev, iod);
if (status)
bio_endio(bio, -EIO); trace_block_bio_complete(bdev_get_queue(bio->bi_bdev), bio, error);
else bio_endio(bio, error);
bio_endio(bio, 0);
} }
/* length is in bytes. gfp flags indicates whether we may sleep. */ /* length is in bytes. gfp flags indicates whether we may sleep. */
@ -522,6 +525,8 @@ static int nvme_split_and_submit(struct bio *bio, struct nvme_queue *nvmeq,
if (!split) if (!split)
return -ENOMEM; return -ENOMEM;
trace_block_split(bdev_get_queue(bio->bi_bdev), bio,
split->bi_iter.bi_sector);
bio_chain(split, bio); bio_chain(split, bio);
if (!waitqueue_active(&nvmeq->sq_full)) if (!waitqueue_active(&nvmeq->sq_full))