diff options
| -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) | |||
| 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); |
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 { | |||
| 572 | int offset; /* Of PRP list */ | 572 | int offset; /* Of PRP list */ |
| 573 | int nents; /* Used in scatterlist */ | 573 | int nents; /* Used in scatterlist */ |
| 574 | int length; /* Of data, in bytes */ | 574 | int length; /* Of data, in bytes */ |
| 575 | unsigned long start_time; | ||
| 575 | dma_addr_t first_dma; | 576 | dma_addr_t first_dma; |
| 576 | struct scatterlist sg[0]; | 577 | struct scatterlist sg[0]; |
| 577 | }; | 578 | }; |
