bd_stat reprenents things happened in backing device. Currently,
it supports bd_counts, bd_reads and bd_writes which are helpful
to understand wearout of flash and memory saving.

Signed-off-by: Minchan Kim <minc...@kernel.org>
---
 Documentation/ABI/testing/sysfs-block-zram |  8 ++++++
 Documentation/blockdev/zram.txt            | 11 ++++++++
 drivers/block/zram/zram_drv.c              | 31 ++++++++++++++++++++++
 drivers/block/zram/zram_drv.h              |  5 ++++
 4 files changed, 55 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-block-zram 
b/Documentation/ABI/testing/sysfs-block-zram
index d1f80b077885..a4daca7e5043 100644
--- a/Documentation/ABI/testing/sysfs-block-zram
+++ b/Documentation/ABI/testing/sysfs-block-zram
@@ -113,3 +113,11 @@ Contact:   Minchan Kim <minc...@kernel.org>
 Description:
                The writeback file is write-only and trigger idle and/or
                huge page writeback to backing device.
+
+What:          /sys/block/zram<id>/bd_stat
+Date:          November 2018
+Contact:       Minchan Kim <minc...@kernel.org>
+Description:
+               The bd_stat file is read-only and represents backing device's
+               statistics (bd_count, bd_reads, bd_writes.) in a format
+               similar to block layer statistics file format.
diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt
index 60b585dab6e0..1f4907307a0d 100644
--- a/Documentation/blockdev/zram.txt
+++ b/Documentation/blockdev/zram.txt
@@ -221,6 +221,17 @@ The stat file represents device's mm statistics. It 
consists of a single
  pages_compacted  the number of pages freed during compaction
  huge_pages      the number of incompressible pages
 
+File /sys/block/zram<id>/bd_stat
+
+The stat file represents device's backing device statistics. It consists of
+a single line of text and contains the following stats separated by whitespace:
+ bd_count      size of data written in backing device.
+               Unit: pages
+ bd_reads      the number of reads from backing device
+               Unit: pages
+ bd_writes     the number of writes to backing device
+               Unit: pages
+
 9) Deactivate:
        swapoff /dev/zram0
        umount /dev/zram1
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index b7b5c9e5f0cd..17d566d9a321 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -505,6 +505,8 @@ static unsigned long alloc_block_bdev(struct zram *zram)
        ret = blk_idx;
 out:
        spin_unlock_irq(&zram->bitmap_lock);
+       if (ret != 0)
+               atomic64_inc(&zram->stats.bd_count);
 
        return ret;
 }
@@ -518,6 +520,7 @@ static void free_block_bdev(struct zram *zram, unsigned 
long blk_idx)
        was_set = test_and_clear_bit(blk_idx, zram->bitmap);
        spin_unlock_irqrestore(&zram->bitmap_lock, flags);
        WARN_ON_ONCE(!was_set);
+       atomic64_dec(&zram->stats.bd_count);
 }
 
 static void zram_page_end_io(struct bio *bio)
@@ -661,6 +664,7 @@ static ssize_t writeback_store(struct device *dev,
                        continue;
                }
 
+               atomic64_inc(&zram->stats.bd_writes);
                /*
                 * We released zram_slot_lock so need to check if the slot was
                 * changed. If there is freeing for the slot, we can catch it
@@ -748,6 +752,7 @@ static int read_from_bdev_sync(struct zram *zram, struct 
bio_vec *bvec,
 static int read_from_bdev(struct zram *zram, struct bio_vec *bvec,
                        unsigned long entry, struct bio *parent, bool sync)
 {
+       atomic64_inc(&zram->stats.bd_reads);
        if (sync)
                return read_from_bdev_sync(zram, bvec, entry, parent);
        else
@@ -790,6 +795,7 @@ static int write_to_bdev(struct zram *zram, struct bio_vec 
*bvec,
 
        submit_bio(bio);
        *pentry = entry;
+       atomic64_inc(&zram->stats.bd_writes);
 
        return 0;
 }
@@ -1053,6 +1059,25 @@ static ssize_t mm_stat_show(struct device *dev,
        return ret;
 }
 
+#ifdef CONFIG_ZRAM_WRITEBACK
+static ssize_t bd_stat_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct zram *zram = dev_to_zram(dev);
+       ssize_t ret;
+
+       down_read(&zram->init_lock);
+       ret = scnprintf(buf, PAGE_SIZE,
+                       "%8llu %8llu %8llu\n",
+                       (u64)atomic64_read(&zram->stats.bd_count),
+                       (u64)atomic64_read(&zram->stats.bd_reads),
+                       (u64)atomic64_read(&zram->stats.bd_writes));
+       up_read(&zram->init_lock);
+
+       return ret;
+}
+#endif
+
 static ssize_t debug_stat_show(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
@@ -1073,6 +1098,9 @@ static ssize_t debug_stat_show(struct device *dev,
 
 static DEVICE_ATTR_RO(io_stat);
 static DEVICE_ATTR_RO(mm_stat);
+#ifdef CONFIG_ZRAM_WRITEBACK
+static DEVICE_ATTR_RO(bd_stat);
+#endif
 static DEVICE_ATTR_RO(debug_stat);
 
 static void zram_meta_free(struct zram *zram, u64 disksize)
@@ -1813,6 +1841,9 @@ static struct attribute *zram_disk_attrs[] = {
 #endif
        &dev_attr_io_stat.attr,
        &dev_attr_mm_stat.attr,
+#ifdef CONFIG_ZRAM_WRITEBACK
+       &dev_attr_bd_stat.attr,
+#endif
        &dev_attr_debug_stat.attr,
        NULL,
 };
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index 07695fe70e17..487ff283fb31 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -82,6 +82,11 @@ struct zram_stats {
        atomic_long_t max_used_pages;   /* no. of maximum pages stored */
        atomic64_t writestall;          /* no. of write slow paths */
        atomic64_t miss_free;           /* no. of missed free */
+#ifdef CONFIG_ZRAM_WRITEBACK
+       atomic64_t bd_count;            /* no. of pages in backing device */
+       atomic64_t bd_reads;            /* no. of read from backing device */
+       atomic64_t bd_writes;           /* no. of write from backing device */
+#endif
 };
 
 struct zram {
-- 
2.19.1.1215.g8438c0b245-goog

Reply via email to