This patch-set adds/updates iostat functions to DAX and
libnvdimm.
Patch 1 adds iostat support to the DAX read/write path since
it only measures metadata at this point.
Patch 2 updates nd_iostat_start() and nd_iostat_end() to use
the generic iostat interfaces.
v3:
- Use generic_start_io_acct() and generic_end_io_acct() for
both dax and libnvdimm. (Dave Chinner, Dan Williams)
v2:
- Set a minimum of one sector. (Dan Williams)
---
Toshi Kani (2):
1/2 DAX: enable iostat for read/write
2/2 libnvdimm: use generic iostat interfaces
---
drivers/nvdimm/core.c | 29 -----------------------------
drivers/nvdimm/nd.h | 11 +++++++++--
fs/dax.c | 15 +++++++++++++++
3 files changed, 24 insertions(+), 31 deletions(-)
On Wed, Oct 19, 2016 at 7:19 AM, Toshi Kani <[email protected]> wrote:
> nd_iostat_start() and nd_iostat_end() implement the same functionality
> that generic_start_io_acct() and generic_end_io_acct() already provide.
>
> Change nd_iostat_start() and nd_iostat_end() to call the generic iostat
> interfaces. There is no change in the nd interfaces.
>
> Signed-off-by: Toshi Kani <[email protected]>
> Cc: Andrew Morton <[email protected]>
> Cc: Dan Williams <[email protected]>
> Cc: Alexander Viro <[email protected]>
> Cc: Dave Chinner <[email protected]>
> Cc: Ross Zwisler <[email protected]>
Thanks, applied to for-4.10/libnvdimm.
nd_iostat_start() and nd_iostat_end() implement the same functionality
that generic_start_io_acct() and generic_end_io_acct() already provide.
Change nd_iostat_start() and nd_iostat_end() to call the generic iostat
interfaces. There is no change in the nd interfaces.
Signed-off-by: Toshi Kani <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Alexander Viro <[email protected]>
Cc: Dave Chinner <[email protected]>
Cc: Ross Zwisler <[email protected]>
---
drivers/nvdimm/core.c | 29 -----------------------------
drivers/nvdimm/nd.h | 11 +++++++++--
2 files changed, 9 insertions(+), 31 deletions(-)
diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c
index 7ceba08..9303cfe 100644
--- a/drivers/nvdimm/core.c
+++ b/drivers/nvdimm/core.c
@@ -317,35 +317,6 @@ 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)
{
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index d3b2fca..065abf1 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -377,10 +377,17 @@ static inline bool nd_iostat_start(struct bio *bio, unsigned long *start)
if (!blk_queue_io_stat(disk->queue))
return false;
- __nd_iostat_start(bio, start);
+ *start = jiffies;
+ generic_start_io_acct(bio_data_dir(bio),
+ bio_sectors(bio), &disk->part0);
return true;
}
-void nd_iostat_end(struct bio *bio, unsigned long start);
+static inline void nd_iostat_end(struct bio *bio, unsigned long start)
+{
+ struct gendisk *disk = bio->bi_bdev->bd_disk;
+
+ generic_end_io_acct(bio_data_dir(bio), &disk->part0, start);
+}
static inline bool is_bad_pmem(struct badblocks *bb, sector_t sector,
unsigned int len)
{
DAX IO path does not support iostat, but its metadata IO path does.
Therefore, iostat shows metadata IO statistics only, which has been
confusing to users.
Add iostat support to the DAX read/write path.
Note, iostat still does not support the DAX mmap path as it allows
user applications to access directly.
Signed-off-by: Toshi Kani <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Alexander Viro <[email protected]>
Cc: Dave Chinner <[email protected]>
Cc: Ross Zwisler <[email protected]>
---
fs/dax.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/fs/dax.c b/fs/dax.c
index 014defd..2646969 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -265,9 +265,12 @@ ssize_t dax_do_io(struct kiocb *iocb, struct inode *inode,
ssize_t retval = -EINVAL;
loff_t pos = iocb->ki_pos;
loff_t end = pos + iov_iter_count(iter);
+ struct gendisk *disk;
+ unsigned long start = 0;
memset(&bh, 0, sizeof(bh));
bh.b_bdev = inode->i_sb->s_bdev;
+ disk = bh.b_bdev->bd_disk;
if ((flags & DIO_LOCKING) && iov_iter_rw(iter) == READ)
inode_lock(inode);
@@ -276,8 +279,20 @@ ssize_t dax_do_io(struct kiocb *iocb, struct inode *inode,
if (!(flags & DIO_SKIP_DIO_COUNT))
inode_dio_begin(inode);
+ if (blk_queue_io_stat(disk->queue)) {
+ int sec = iov_iter_count(iter) >> 9;
+
+ start = jiffies;
+ generic_start_io_acct(iov_iter_rw(iter),
+ (!sec) ? 1 : sec, &disk->part0);
+ }
+
retval = dax_io(inode, iter, pos, end, get_block, &bh);
+ if (start)
+ generic_end_io_acct(iov_iter_rw(iter),
+ &disk->part0, start);
+
if ((flags & DIO_LOCKING) && iov_iter_rw(iter) == READ)
inode_unlock(inode);