Commit 23eddf39 authored by Minchan Kim's avatar Minchan Kim Committed by Linus Torvalds

zram: add bd_stat statistics

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

[minchan@kernel.org: v4]
  Link: http://lkml.kernel.org/r/20181203024045.153534-7-minchan@kernel.org
Link: http://lkml.kernel.org/r/20181127055429.251614-7-minchan@kernel.orgSigned-off-by: default avatarMinchan Kim <minchan@kernel.org>
Reviewed-by: default avatarSergey Senozhatsky <sergey.senozhatsky@gmail.com>
Cc: Joey Pabalinas <joeypabalinas@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a939888e
...@@ -113,3 +113,11 @@ Contact: Minchan Kim <minchan@kernel.org> ...@@ -113,3 +113,11 @@ Contact: Minchan Kim <minchan@kernel.org>
Description: Description:
The writeback file is write-only and trigger idle and/or The writeback file is write-only and trigger idle and/or
huge page writeback to backing device. huge page writeback to backing device.
What: /sys/block/zram<id>/bd_stat
Date: November 2018
Contact: Minchan Kim <minchan@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.
...@@ -221,6 +221,17 @@ line of text and contains the following stats separated by whitespace: ...@@ -221,6 +221,17 @@ line of text and contains the following stats separated by whitespace:
pages_compacted the number of pages freed during compaction pages_compacted the number of pages freed during compaction
huge_pages the number of incompressible pages 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: 4K bytes
bd_reads the number of reads from backing device
Unit: 4K bytes
bd_writes the number of writes to backing device
Unit: 4K bytes
9) Deactivate: 9) Deactivate:
swapoff /dev/zram0 swapoff /dev/zram0
umount /dev/zram1 umount /dev/zram1
......
...@@ -502,6 +502,7 @@ static unsigned long alloc_block_bdev(struct zram *zram) ...@@ -502,6 +502,7 @@ static unsigned long alloc_block_bdev(struct zram *zram)
if (test_and_set_bit(blk_idx, zram->bitmap)) if (test_and_set_bit(blk_idx, zram->bitmap))
goto retry; goto retry;
atomic64_inc(&zram->stats.bd_count);
return blk_idx; return blk_idx;
} }
...@@ -511,6 +512,7 @@ static void free_block_bdev(struct zram *zram, unsigned long blk_idx) ...@@ -511,6 +512,7 @@ static void free_block_bdev(struct zram *zram, unsigned long blk_idx)
was_set = test_and_clear_bit(blk_idx, zram->bitmap); was_set = test_and_clear_bit(blk_idx, zram->bitmap);
WARN_ON_ONCE(!was_set); WARN_ON_ONCE(!was_set);
atomic64_dec(&zram->stats.bd_count);
} }
static void zram_page_end_io(struct bio *bio) static void zram_page_end_io(struct bio *bio)
...@@ -668,6 +670,7 @@ static ssize_t writeback_store(struct device *dev, ...@@ -668,6 +670,7 @@ static ssize_t writeback_store(struct device *dev,
continue; continue;
} }
atomic64_inc(&zram->stats.bd_writes);
/* /*
* We released zram_slot_lock so need to check if the slot was * 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 * changed. If there is freeing for the slot, we can catch it
...@@ -757,6 +760,7 @@ static int read_from_bdev_sync(struct zram *zram, struct bio_vec *bvec, ...@@ -757,6 +760,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, static int read_from_bdev(struct zram *zram, struct bio_vec *bvec,
unsigned long entry, struct bio *parent, bool sync) unsigned long entry, struct bio *parent, bool sync)
{ {
atomic64_inc(&zram->stats.bd_reads);
if (sync) if (sync)
return read_from_bdev_sync(zram, bvec, entry, parent); return read_from_bdev_sync(zram, bvec, entry, parent);
else else
...@@ -1013,6 +1017,25 @@ static ssize_t mm_stat_show(struct device *dev, ...@@ -1013,6 +1017,25 @@ static ssize_t mm_stat_show(struct device *dev,
return ret; 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) * (PAGE_SHIFT - 12),
(u64)atomic64_read(&zram->stats.bd_reads) * (PAGE_SHIFT - 12),
(u64)atomic64_read(&zram->stats.bd_writes) * (PAGE_SHIFT - 12));
up_read(&zram->init_lock);
return ret;
}
#endif
static ssize_t debug_stat_show(struct device *dev, static ssize_t debug_stat_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
...@@ -1033,6 +1056,9 @@ static ssize_t debug_stat_show(struct device *dev, ...@@ -1033,6 +1056,9 @@ static ssize_t debug_stat_show(struct device *dev,
static DEVICE_ATTR_RO(io_stat); static DEVICE_ATTR_RO(io_stat);
static DEVICE_ATTR_RO(mm_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 DEVICE_ATTR_RO(debug_stat);
static void zram_meta_free(struct zram *zram, u64 disksize) static void zram_meta_free(struct zram *zram, u64 disksize)
...@@ -1759,6 +1785,9 @@ static struct attribute *zram_disk_attrs[] = { ...@@ -1759,6 +1785,9 @@ static struct attribute *zram_disk_attrs[] = {
#endif #endif
&dev_attr_io_stat.attr, &dev_attr_io_stat.attr,
&dev_attr_mm_stat.attr, &dev_attr_mm_stat.attr,
#ifdef CONFIG_ZRAM_WRITEBACK
&dev_attr_bd_stat.attr,
#endif
&dev_attr_debug_stat.attr, &dev_attr_debug_stat.attr,
NULL, NULL,
}; };
......
...@@ -82,6 +82,11 @@ struct zram_stats { ...@@ -82,6 +82,11 @@ struct zram_stats {
atomic_long_t max_used_pages; /* no. of maximum pages stored */ atomic_long_t max_used_pages; /* no. of maximum pages stored */
atomic64_t writestall; /* no. of write slow paths */ atomic64_t writestall; /* no. of write slow paths */
atomic64_t miss_free; /* no. of missed free */ 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 reads from backing device */
atomic64_t bd_writes; /* no. of writes from backing device */
#endif
}; };
struct zram { struct zram {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment