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>
This commit is contained in:
parent
063a8096f3
commit
6198221fa0
@ -285,6 +285,7 @@ nvme_alloc_iod(unsigned nseg, unsigned nbytes, gfp_t gfp)
|
|||||||
iod->npages = -1;
|
iod->npages = -1;
|
||||||
iod->length = nbytes;
|
iod->length = nbytes;
|
||||||
iod->nents = 0;
|
iod->nents = 0;
|
||||||
|
iod->start_time = jiffies;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iod;
|
return iod;
|
||||||
@ -308,6 +309,30 @@ void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod)
|
|||||||
kfree(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,
|
static void bio_completion(struct nvme_dev *dev, void *ctx,
|
||||||
struct nvme_completion *cqe)
|
struct nvme_completion *cqe)
|
||||||
{
|
{
|
||||||
@ -318,6 +343,8 @@ static void bio_completion(struct nvme_dev *dev, void *ctx,
|
|||||||
if (iod->nents)
|
if (iod->nents)
|
||||||
dma_unmap_sg(&dev->pci_dev->dev, iod->sg, iod->nents,
|
dma_unmap_sg(&dev->pci_dev->dev, iod->sg, iod->nents,
|
||||||
bio_data_dir(bio) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
bio_data_dir(bio) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
||||||
|
|
||||||
|
nvme_end_io_acct(bio, iod->start_time);
|
||||||
nvme_free_iod(dev, iod);
|
nvme_free_iod(dev, iod);
|
||||||
if (status)
|
if (status)
|
||||||
bio_endio(bio, -EIO);
|
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.control = cpu_to_le16(control);
|
||||||
cmnd->rw.dsmgmt = cpu_to_le32(dsmgmt);
|
cmnd->rw.dsmgmt = cpu_to_le32(dsmgmt);
|
||||||
|
|
||||||
|
nvme_start_io_acct(bio);
|
||||||
if (++nvmeq->sq_tail == nvmeq->q_depth)
|
if (++nvmeq->sq_tail == nvmeq->q_depth)
|
||||||
nvmeq->sq_tail = 0;
|
nvmeq->sq_tail = 0;
|
||||||
writel(nvmeq->sq_tail, nvmeq->q_db);
|
writel(nvmeq->sq_tail, nvmeq->q_db);
|
||||||
|
@ -572,6 +572,7 @@ struct nvme_iod {
|
|||||||
int offset; /* Of PRP list */
|
int offset; /* Of PRP list */
|
||||||
int nents; /* Used in scatterlist */
|
int nents; /* Used in scatterlist */
|
||||||
int length; /* Of data, in bytes */
|
int length; /* Of data, in bytes */
|
||||||
|
unsigned long start_time;
|
||||||
dma_addr_t first_dma;
|
dma_addr_t first_dma;
|
||||||
struct scatterlist sg[0];
|
struct scatterlist sg[0];
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user