diff options
author | Keith Busch <keith.busch@intel.com> | 2013-05-29 17:59:39 -0400 |
---|---|---|
committer | Matthew Wilcox <matthew.r.wilcox@intel.com> | 2013-06-20 12:06:35 -0400 |
commit | 6198221fa0df0298513b35796f63f242ea97134e (patch) | |
tree | 2de31ecb41a65e2c63712f88cb9e68b1520fbf20 /drivers/block/nvme-core.c | |
parent | 063a8096f3dbca7521d5918b3aea7ab46c5d2fe9 (diff) |
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>
Diffstat (limited to 'drivers/block/nvme-core.c')
-rw-r--r-- | drivers/block/nvme-core.c | 28 |
1 files changed, 28 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) | |||
285 | iod->npages = -1; | 285 | iod->npages = -1; |
286 | iod->length = nbytes; | 286 | iod->length = nbytes; |
287 | iod->nents = 0; | 287 | iod->nents = 0; |
288 | iod->start_time = jiffies; | ||
288 | } | 289 | } |
289 | 290 | ||
290 | return iod; | 291 | return iod; |
@@ -308,6 +309,30 @@ void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod) | |||
308 | kfree(iod); | 309 | kfree(iod); |
309 | } | 310 | } |
310 | 311 | ||
312 | static void nvme_start_io_acct(struct bio *bio) | ||
313 | { | ||
314 | struct gendisk *disk = bio->bi_bdev->bd_disk; | ||
315 | const int rw = bio_data_dir(bio); | ||
316 | int cpu = part_stat_lock(); | ||
317 | part_round_stats(cpu, &disk->part0); | ||
318 | part_stat_inc(cpu, &disk->part0, ios[rw]); | ||
319 | part_stat_add(cpu, &disk->part0, sectors[rw], bio_sectors(bio)); | ||
320 | part_inc_in_flight(&disk->part0, rw); | ||
321 | part_stat_unlock(); | ||
322 | } | ||
323 | |||
324 | static void nvme_end_io_acct(struct bio *bio, unsigned long start_time) | ||
325 | { | ||
326 | struct gendisk *disk = bio->bi_bdev->bd_disk; | ||
327 | const int rw = bio_data_dir(bio); | ||
328 | unsigned long duration = jiffies - start_time; | ||
329 | int cpu = part_stat_lock(); | ||
330 | part_stat_add(cpu, &disk->part0, ticks[rw], duration); | ||
331 | part_round_stats(cpu, &disk->part0); | ||
332 | part_dec_in_flight(&disk->part0, rw); | ||
333 | part_stat_unlock(); | ||
334 | } | ||
335 | |||
311 | static void bio_completion(struct nvme_dev *dev, void *ctx, | 336 | static void bio_completion(struct nvme_dev *dev, void *ctx, |
312 | struct nvme_completion *cqe) | 337 | struct nvme_completion *cqe) |
313 | { | 338 | { |
@@ -318,6 +343,8 @@ static void bio_completion(struct nvme_dev *dev, void *ctx, | |||
318 | if (iod->nents) | 343 | if (iod->nents) |
319 | dma_unmap_sg(&dev->pci_dev->dev, iod->sg, iod->nents, | 344 | dma_unmap_sg(&dev->pci_dev->dev, iod->sg, iod->nents, |
320 | bio_data_dir(bio) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | 345 | bio_data_dir(bio) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); |
346 | |||
347 | nvme_end_io_acct(bio, iod->start_time); | ||
321 | nvme_free_iod(dev, iod); | 348 | nvme_free_iod(dev, iod); |
322 | if (status) | 349 | if (status) |
323 | bio_endio(bio, -EIO); | 350 | bio_endio(bio, -EIO); |
@@ -695,6 +722,7 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns, | |||
695 | cmnd->rw.control = cpu_to_le16(control); | 722 | cmnd->rw.control = cpu_to_le16(control); |
696 | cmnd->rw.dsmgmt = cpu_to_le32(dsmgmt); | 723 | cmnd->rw.dsmgmt = cpu_to_le32(dsmgmt); |
697 | 724 | ||
725 | nvme_start_io_acct(bio); | ||
698 | if (++nvmeq->sq_tail == nvmeq->q_depth) | 726 | if (++nvmeq->sq_tail == nvmeq->q_depth) |
699 | nvmeq->sq_tail = 0; | 727 | nvmeq->sq_tail = 0; |
700 | writel(nvmeq->sq_tail, nvmeq->q_db); | 728 | writel(nvmeq->sq_tail, nvmeq->q_db); |