Skip to content

Commit

Permalink
libnvdimm: enable iostat
Browse files Browse the repository at this point in the history
This is disabled by default as the overhead is prohibitive, but if the
user takes the action to turn it on we'll oblige.

Reviewed-by: Vishal Verma <vishal.l.verma@linux.intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
Dan Williams committed Jun 26, 2015
1 parent edc870e commit f0dc089
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 2 deletions.
7 changes: 6 additions & 1 deletion drivers/nvdimm/blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,10 @@ static void nd_blk_make_request(struct request_queue *q, struct bio *bio)
struct bio_integrity_payload *bip;
struct nd_blk_device *blk_dev;
struct bvec_iter iter;
unsigned long start;
struct bio_vec bvec;
int err = 0, rw;
bool do_acct;

/*
* bio_integrity_enabled also checks if the bio already has an
Expand All @@ -185,6 +187,7 @@ static void nd_blk_make_request(struct request_queue *q, struct bio *bio)
bip = bio_integrity(bio);
blk_dev = disk->private_data;
rw = bio_data_dir(bio);
do_acct = nd_iostat_start(bio, &start);
bio_for_each_segment(bvec, bio, iter) {
unsigned int len = bvec.bv_len;

Expand All @@ -196,9 +199,11 @@ static void nd_blk_make_request(struct request_queue *q, struct bio *bio)
"io error in %s sector %lld, len %d,\n",
(rw == READ) ? "READ" : "WRITE",
(unsigned long long) iter.bi_sector, len);
goto out;
break;
}
}
if (do_acct)
nd_iostat_end(bio, start);

out:
bio_endio(bio, err);
Expand Down
7 changes: 6 additions & 1 deletion drivers/nvdimm/btt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1177,8 +1177,10 @@ static void btt_make_request(struct request_queue *q, struct bio *bio)
struct bio_integrity_payload *bip = bio_integrity(bio);
struct btt *btt = q->queuedata;
struct bvec_iter iter;
unsigned long start;
struct bio_vec bvec;
int err = 0, rw;
bool do_acct;

/*
* bio_integrity_enabled also checks if the bio already has an
Expand All @@ -1191,6 +1193,7 @@ static void btt_make_request(struct request_queue *q, struct bio *bio)
goto out;
}

do_acct = nd_iostat_start(bio, &start);
rw = bio_data_dir(bio);
bio_for_each_segment(bvec, bio, iter) {
unsigned int len = bvec.bv_len;
Expand All @@ -1208,9 +1211,11 @@ static void btt_make_request(struct request_queue *q, struct bio *bio)
"io error in %s sector %lld, len %d,\n",
(rw == READ) ? "READ" : "WRITE",
(unsigned long long) iter.bi_sector, len);
goto out;
break;
}
}
if (do_acct)
nd_iostat_end(bio, start);

out:
bio_endio(bio, err);
Expand Down
29 changes: 29 additions & 0 deletions drivers/nvdimm/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,35 @@ ssize_t nd_sector_size_store(struct device *dev, const char *buf,
}
}

void __nd_iostat_start(struct bio *bio, unsigned long *start)
{
struct gendisk *disk = bio->bi_bdev->bd_disk;
const int rw = bio_data_dir(bio);
int cpu = part_stat_lock();

*start = jiffies;
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();
}
EXPORT_SYMBOL(__nd_iostat_start);

void nd_iostat_end(struct bio *bio, unsigned long start)
{
struct gendisk *disk = bio->bi_bdev->bd_disk;
unsigned long duration = jiffies - start;
const int rw = bio_data_dir(bio);
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();
}
EXPORT_SYMBOL(nd_iostat_end);

static ssize_t commands_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
Expand Down
13 changes: 13 additions & 0 deletions drivers/nvdimm/nd.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#ifndef __ND_H__
#define __ND_H__
#include <linux/libnvdimm.h>
#include <linux/blkdev.h>
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/ndctl.h>
Expand Down Expand Up @@ -202,5 +203,17 @@ int nvdimm_namespace_detach_btt(struct nd_namespace_common *ndns);
const char *nvdimm_namespace_disk_name(struct nd_namespace_common *ndns,
char *name);
int nd_blk_region_init(struct nd_region *nd_region);
void __nd_iostat_start(struct bio *bio, unsigned long *start);
static inline bool nd_iostat_start(struct bio *bio, unsigned long *start)
{
struct gendisk *disk = bio->bi_bdev->bd_disk;

if (!blk_queue_io_stat(disk->queue))
return false;

__nd_iostat_start(bio, start);
return true;
}
void nd_iostat_end(struct bio *bio, unsigned long start);
resource_size_t nd_namespace_blk_validate(struct nd_namespace_blk *nsblk);
#endif /* __ND_H__ */
5 changes: 5 additions & 0 deletions drivers/nvdimm/pmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,19 @@ static void pmem_do_bvec(struct pmem_device *pmem, struct page *page,

static void pmem_make_request(struct request_queue *q, struct bio *bio)
{
bool do_acct;
unsigned long start;
struct bio_vec bvec;
struct bvec_iter iter;
struct block_device *bdev = bio->bi_bdev;
struct pmem_device *pmem = bdev->bd_disk->private_data;

do_acct = nd_iostat_start(bio, &start);
bio_for_each_segment(bvec, bio, iter)
pmem_do_bvec(pmem, bvec.bv_page, bvec.bv_len, bvec.bv_offset,
bio_data_dir(bio), iter.bi_sector);
if (do_acct)
nd_iostat_end(bio, start);
bio_endio(bio, 0);
}

Expand Down

0 comments on commit f0dc089

Please sign in to comment.