diff options
author | Keith Busch <keith.busch@intel.com> | 2013-05-29 15:59:39 -0600 |
---|---|---|
committer | Matthew Wilcox <matthew.r.wilcox@intel.com> | 2013-06-20 12:06:35 -0400 |
commit | 6198221fa0df0298513b35796f63f242ea97134e (patch) | |
tree | 2de31ecb41a65e2c63712f88cb9e68b1520fbf20 | |
parent | 063a8096f3dbca7521d5918b3aea7ab46c5d2fe9 (diff) | |
download | blackbird-op-linux-6198221fa0df0298513b35796f63f242ea97134e.tar.gz blackbird-op-linux-6198221fa0df0298513b35796f63f242ea97134e.zip |
NVMe: Disk IO statistics
Add io stats accounting for bio requests so nvme block devices show
useful disk stats.
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com>
-rw-r--r-- | drivers/block/nvme-core.c | 28 | ||||
-rw-r--r-- | include/linux/nvme.h | 1 |
2 files changed, 29 insertions, 0 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index de3a75978c56..4e71b075d3b4 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -285,6 +285,7 @@ nvme_alloc_iod(unsigned nseg, unsigned nbytes, gfp_t gfp) iod->npages = -1; iod->length = nbytes; iod->nents = 0; + iod->start_time = jiffies; } return iod; @@ -308,6 +309,30 @@ void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod) kfree(iod); } +static void nvme_start_io_acct(struct bio *bio) +{ + struct gendisk *disk = bio->bi_bdev->bd_disk; + const int rw = bio_data_dir(bio); + int cpu = part_stat_lock(); + part_round_stats(cpu, &disk->part0); + part_stat_inc(cpu, &disk->part0, ios[rw]); + part_stat_add(cpu, &disk->part0, sectors[rw], bio_sectors(bio)); + part_inc_in_flight(&disk->part0, rw); + part_stat_unlock(); +} + +static void nvme_end_io_acct(struct bio *bio, unsigned long start_time) +{ + struct gendisk *disk = bio->bi_bdev->bd_disk; + const int rw = bio_data_dir(bio); + unsigned long duration = jiffies - start_time; + int cpu = part_stat_lock(); + part_stat_add(cpu, &disk->part0, ticks[rw], duration); + part_round_stats(cpu, &disk->part0); + part_dec_in_flight(&disk->part0, rw); + part_stat_unlock(); +} + static void bio_completion(struct nvme_dev *dev, void *ctx, struct nvme_completion *cqe) { @@ -318,6 +343,8 @@ static void bio_completion(struct nvme_dev *dev, void *ctx, if (iod->nents) dma_unmap_sg(&dev->pci_dev->dev, iod->sg, iod->nents, bio_data_dir(bio) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + + nvme_end_io_acct(bio, iod->start_time); nvme_free_iod(dev, iod); if (status) bio_endio(bio, -EIO); @@ -695,6 +722,7 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns, cmnd->rw.control = cpu_to_le16(control); cmnd->rw.dsmgmt = cpu_to_le32(dsmgmt); + nvme_start_io_acct(bio); if (++nvmeq->sq_tail == nvmeq->q_depth) nvmeq->sq_tail = 0; writel(nvmeq->sq_tail, nvmeq->q_db); diff --git a/include/linux/nvme.h b/include/linux/nvme.h index f451c8d6e231..5d7c07946fbe 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -572,6 +572,7 @@ struct nvme_iod { int offset; /* Of PRP list */ int nents; /* Used in scatterlist */ int length; /* Of data, in bytes */ + unsigned long start_time; dma_addr_t first_dma; struct scatterlist sg[0]; }; |