提交 f0dc089c 编写于 作者: D Dan Williams

libnvdimm: enable iostat

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: NVishal Verma <vishal.l.verma@linux.intel.com>
Signed-off-by: NDan Williams <dan.j.williams@intel.com>
上级 edc870e5
...@@ -168,8 +168,10 @@ static void nd_blk_make_request(struct request_queue *q, struct bio *bio) ...@@ -168,8 +168,10 @@ static void nd_blk_make_request(struct request_queue *q, struct bio *bio)
struct bio_integrity_payload *bip; struct bio_integrity_payload *bip;
struct nd_blk_device *blk_dev; struct nd_blk_device *blk_dev;
struct bvec_iter iter; struct bvec_iter iter;
unsigned long start;
struct bio_vec bvec; struct bio_vec bvec;
int err = 0, rw; int err = 0, rw;
bool do_acct;
/* /*
* bio_integrity_enabled also checks if the bio already has an * bio_integrity_enabled also checks if the bio already has an
...@@ -185,6 +187,7 @@ static void nd_blk_make_request(struct request_queue *q, struct bio *bio) ...@@ -185,6 +187,7 @@ static void nd_blk_make_request(struct request_queue *q, struct bio *bio)
bip = bio_integrity(bio); bip = bio_integrity(bio);
blk_dev = disk->private_data; blk_dev = disk->private_data;
rw = bio_data_dir(bio); rw = bio_data_dir(bio);
do_acct = nd_iostat_start(bio, &start);
bio_for_each_segment(bvec, bio, iter) { bio_for_each_segment(bvec, bio, iter) {
unsigned int len = bvec.bv_len; unsigned int len = bvec.bv_len;
...@@ -196,9 +199,11 @@ static void nd_blk_make_request(struct request_queue *q, struct bio *bio) ...@@ -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", "io error in %s sector %lld, len %d,\n",
(rw == READ) ? "READ" : "WRITE", (rw == READ) ? "READ" : "WRITE",
(unsigned long long) iter.bi_sector, len); (unsigned long long) iter.bi_sector, len);
goto out; break;
} }
} }
if (do_acct)
nd_iostat_end(bio, start);
out: out:
bio_endio(bio, err); bio_endio(bio, err);
......
...@@ -1177,8 +1177,10 @@ static void btt_make_request(struct request_queue *q, struct bio *bio) ...@@ -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 bio_integrity_payload *bip = bio_integrity(bio);
struct btt *btt = q->queuedata; struct btt *btt = q->queuedata;
struct bvec_iter iter; struct bvec_iter iter;
unsigned long start;
struct bio_vec bvec; struct bio_vec bvec;
int err = 0, rw; int err = 0, rw;
bool do_acct;
/* /*
* bio_integrity_enabled also checks if the bio already has an * bio_integrity_enabled also checks if the bio already has an
...@@ -1191,6 +1193,7 @@ static void btt_make_request(struct request_queue *q, struct bio *bio) ...@@ -1191,6 +1193,7 @@ static void btt_make_request(struct request_queue *q, struct bio *bio)
goto out; goto out;
} }
do_acct = nd_iostat_start(bio, &start);
rw = bio_data_dir(bio); rw = bio_data_dir(bio);
bio_for_each_segment(bvec, bio, iter) { bio_for_each_segment(bvec, bio, iter) {
unsigned int len = bvec.bv_len; unsigned int len = bvec.bv_len;
...@@ -1208,9 +1211,11 @@ static void btt_make_request(struct request_queue *q, struct bio *bio) ...@@ -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", "io error in %s sector %lld, len %d,\n",
(rw == READ) ? "READ" : "WRITE", (rw == READ) ? "READ" : "WRITE",
(unsigned long long) iter.bi_sector, len); (unsigned long long) iter.bi_sector, len);
goto out; break;
} }
} }
if (do_acct)
nd_iostat_end(bio, start);
out: out:
bio_endio(bio, err); bio_endio(bio, err);
......
...@@ -214,6 +214,35 @@ ssize_t nd_sector_size_store(struct device *dev, const char *buf, ...@@ -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, static ssize_t commands_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#ifndef __ND_H__ #ifndef __ND_H__
#define __ND_H__ #define __ND_H__
#include <linux/libnvdimm.h> #include <linux/libnvdimm.h>
#include <linux/blkdev.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/ndctl.h> #include <linux/ndctl.h>
...@@ -202,5 +203,17 @@ int nvdimm_namespace_detach_btt(struct nd_namespace_common *ndns); ...@@ -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, const char *nvdimm_namespace_disk_name(struct nd_namespace_common *ndns,
char *name); char *name);
int nd_blk_region_init(struct nd_region *nd_region); 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); resource_size_t nd_namespace_blk_validate(struct nd_namespace_blk *nsblk);
#endif /* __ND_H__ */ #endif /* __ND_H__ */
...@@ -58,14 +58,19 @@ static void pmem_do_bvec(struct pmem_device *pmem, struct page *page, ...@@ -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) static void pmem_make_request(struct request_queue *q, struct bio *bio)
{ {
bool do_acct;
unsigned long start;
struct bio_vec bvec; struct bio_vec bvec;
struct bvec_iter iter; struct bvec_iter iter;
struct block_device *bdev = bio->bi_bdev; struct block_device *bdev = bio->bi_bdev;
struct pmem_device *pmem = bdev->bd_disk->private_data; struct pmem_device *pmem = bdev->bd_disk->private_data;
do_acct = nd_iostat_start(bio, &start);
bio_for_each_segment(bvec, bio, iter) bio_for_each_segment(bvec, bio, iter)
pmem_do_bvec(pmem, bvec.bv_page, bvec.bv_len, bvec.bv_offset, pmem_do_bvec(pmem, bvec.bv_page, bvec.bv_len, bvec.bv_offset,
bio_data_dir(bio), iter.bi_sector); bio_data_dir(bio), iter.bi_sector);
if (do_acct)
nd_iostat_end(bio, start);
bio_endio(bio, 0); bio_endio(bio, 0);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册