linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] zram stats rework and code cleanup
@ 2014-01-14  9:37 Sergey Senozhatsky
  2014-01-14  9:37 ` [PATCH 1/3] zram: drop `init_done' struct zram member Sergey Senozhatsky
                   ` (3 more replies)
  0 siblings, 4 replies; 24+ messages in thread
From: Sergey Senozhatsky @ 2014-01-14  9:37 UTC (permalink / raw)
  To: Minchan Kim
  Cc: Jerome Marchand, Nitin Gupta, linux-kernel, Sergey Senozhatsky

This patchset includes code clean up and zram stats rework.

Sergey Senozhatsky (3):
  zram: drop `init_done' struct zram member
  zram: do not pass rw argument to __zram_make_request()
  zram: rework reported to end-user zram statistics

 drivers/block/zram/zram_drv.c | 213 ++++++++++++++----------------------------
 drivers/block/zram/zram_drv.h |  18 ++--
 2 files changed, 76 insertions(+), 155 deletions(-)

-- 
1.8.5.2.487.g7559984


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 1/3] zram: drop `init_done' struct zram member
  2014-01-14  9:37 [PATCH 0/3] zram stats rework and code cleanup Sergey Senozhatsky
@ 2014-01-14  9:37 ` Sergey Senozhatsky
  2014-01-14 11:03   ` Jerome Marchand
  2014-01-15  1:52   ` Minchan Kim
  2014-01-14  9:37 ` [PATCH 2/3] zram: do not pass rw argument to __zram_make_request() Sergey Senozhatsky
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 24+ messages in thread
From: Sergey Senozhatsky @ 2014-01-14  9:37 UTC (permalink / raw)
  To: Minchan Kim
  Cc: Jerome Marchand, Nitin Gupta, linux-kernel, Sergey Senozhatsky

Introduce init_done() helper function which allows us to drop
`init_done' struct zram member. init_done() uses the fact that
->init_done == 1 equals to ->meta != NULL.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
 drivers/block/zram/zram_drv.c | 21 +++++++++++----------
 drivers/block/zram/zram_drv.h |  1 -
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 011e55d..c323e05 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -42,6 +42,11 @@ static struct zram *zram_devices;
 /* Module params (documentation at end) */
 static unsigned int num_devices = 1;
 
+static inline int init_done(struct zram *zram)
+{
+	return zram->meta != NULL;
+}
+
 static inline struct zram *dev_to_zram(struct device *dev)
 {
 	return (struct zram *)dev_to_disk(dev)->private_data;
@@ -60,7 +65,7 @@ static ssize_t initstate_show(struct device *dev,
 {
 	struct zram *zram = dev_to_zram(dev);
 
-	return sprintf(buf, "%u\n", zram->init_done);
+	return sprintf(buf, "%u\n", init_done(zram));
 }
 
 static ssize_t num_reads_show(struct device *dev,
@@ -133,7 +138,7 @@ static ssize_t mem_used_total_show(struct device *dev,
 	struct zram_meta *meta = zram->meta;
 
 	down_read(&zram->init_lock);
-	if (zram->init_done)
+	if (init_done(zram))
 		val = zs_get_total_size_bytes(meta->mem_pool);
 	up_read(&zram->init_lock);
 
@@ -546,14 +551,12 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
 	struct zram_meta *meta;
 
 	down_write(&zram->init_lock);
-	if (!zram->init_done) {
+	if (!init_done(zram)) {
 		up_write(&zram->init_lock);
 		return;
 	}
 
 	meta = zram->meta;
-	zram->init_done = 0;
-
 	/* Free all pages that are still in this zram device */
 	for (index = 0; index < zram->disksize >> PAGE_SHIFT; index++) {
 		unsigned long handle = meta->table[index].handle;
@@ -594,8 +597,6 @@ static void zram_init_device(struct zram *zram, struct zram_meta *meta)
 	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
 
 	zram->meta = meta;
-	zram->init_done = 1;
-
 	pr_debug("Initialization done!\n");
 }
 
@@ -613,7 +614,7 @@ static ssize_t disksize_store(struct device *dev,
 	disksize = PAGE_ALIGN(disksize);
 	meta = zram_meta_alloc(disksize);
 	down_write(&zram->init_lock);
-	if (zram->init_done) {
+	if (init_done(zram)) {
 		up_write(&zram->init_lock);
 		zram_meta_free(meta);
 		pr_info("Cannot change disksize for initialized device\n");
@@ -734,7 +735,7 @@ static void zram_make_request(struct request_queue *queue, struct bio *bio)
 	struct zram *zram = queue->queuedata;
 
 	down_read(&zram->init_lock);
-	if (unlikely(!zram->init_done))
+	if (unlikely(!init_done(zram)))
 		goto error;
 
 	if (!valid_io_request(zram, bio)) {
@@ -857,7 +858,7 @@ static int create_device(struct zram *zram, int device_id)
 		goto out_free_disk;
 	}
 
-	zram->init_done = 0;
+	zram->meta = NULL;
 	return 0;
 
 out_free_disk:
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index ad8aa35..e81e9cd 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -95,7 +95,6 @@ struct zram {
 	struct zram_meta *meta;
 	struct request_queue *queue;
 	struct gendisk *disk;
-	int init_done;
 	/* Prevent concurrent execution of device init, reset and R/W request */
 	struct rw_semaphore init_lock;
 	/*
-- 
1.8.5.2.487.g7559984


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 2/3] zram: do not pass rw argument to __zram_make_request()
  2014-01-14  9:37 [PATCH 0/3] zram stats rework and code cleanup Sergey Senozhatsky
  2014-01-14  9:37 ` [PATCH 1/3] zram: drop `init_done' struct zram member Sergey Senozhatsky
@ 2014-01-14  9:37 ` Sergey Senozhatsky
  2014-01-14 11:02   ` Jerome Marchand
  2014-01-14  9:37 ` [PATCH 3/3] zram: rework reported to end-user zram statistics Sergey Senozhatsky
  2014-01-14  9:42 ` [PATCH 0/3] zram stats rework and code cleanup Sergey Senozhatsky
  3 siblings, 1 reply; 24+ messages in thread
From: Sergey Senozhatsky @ 2014-01-14  9:37 UTC (permalink / raw)
  To: Minchan Kim
  Cc: Jerome Marchand, Nitin Gupta, linux-kernel, Sergey Senozhatsky

Do not pass rw argument down the __zram_make_request() -> zram_bvec_rw()
chain, decode it in zram_bvec_rw() instead. Besides, this is the place
where we distinguish READ (+READ AHEAD) and WRITE bio data directions, so
account zram RW stats here, instead of __zram_make_request(). This also
allows to account a real number of zram READ/WRITE operations, not just
requests (single RW request may cause a number of zram RW ops with separate
locking, compression/decompression, etc).

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
 drivers/block/zram/zram_drv.c | 33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index c323e05..2a7682c 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -533,14 +533,21 @@ out:
 }
 
 static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index,
-			int offset, struct bio *bio, int rw)
+			int offset, struct bio *bio)
 {
 	int ret;
+	int rw = bio_data_dir(bio);
 
-	if (rw == READ)
+	if (rw == READA)
+		rw = READ;
+
+	if (rw == READ) {
+		atomic64_inc(&zram->stats.num_reads);
 		ret = zram_bvec_read(zram, bvec, index, offset, bio);
-	else
+	} else {
+		atomic64_inc(&zram->stats.num_writes);
 		ret = zram_bvec_write(zram, bvec, index, offset);
+	}
 
 	return ret;
 }
@@ -670,22 +677,13 @@ out:
 	return ret;
 }
 
-static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
+static void __zram_make_request(struct zram *zram, struct bio *bio)
 {
 	int offset;
 	u32 index;
 	struct bio_vec bvec;
 	struct bvec_iter iter;
 
-	switch (rw) {
-	case READ:
-		atomic64_inc(&zram->stats.num_reads);
-		break;
-	case WRITE:
-		atomic64_inc(&zram->stats.num_writes);
-		break;
-	}
-
 	index = bio->bi_iter.bi_sector >> SECTORS_PER_PAGE_SHIFT;
 	offset = (bio->bi_iter.bi_sector &
 		  (SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT;
@@ -704,16 +702,15 @@ static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
 			bv.bv_len = max_transfer_size;
 			bv.bv_offset = bvec.bv_offset;
 
-			if (zram_bvec_rw(zram, &bv, index, offset, bio, rw) < 0)
+			if (zram_bvec_rw(zram, &bv, index, offset, bio) < 0)
 				goto out;
 
 			bv.bv_len = bvec.bv_len - max_transfer_size;
 			bv.bv_offset += max_transfer_size;
-			if (zram_bvec_rw(zram, &bv, index+1, 0, bio, rw) < 0)
+			if (zram_bvec_rw(zram, &bv, index + 1, 0, bio) < 0)
 				goto out;
 		} else
-			if (zram_bvec_rw(zram, &bvec, index, offset, bio, rw)
-			    < 0)
+			if (zram_bvec_rw(zram, &bvec, index, offset, bio) < 0)
 				goto out;
 
 		update_position(&index, &offset, &bvec);
@@ -743,7 +740,7 @@ static void zram_make_request(struct request_queue *queue, struct bio *bio)
 		goto error;
 	}
 
-	__zram_make_request(zram, bio, bio_data_dir(bio));
+	__zram_make_request(zram, bio);
 	up_read(&zram->init_lock);
 
 	return;
-- 
1.8.5.2.487.g7559984


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 3/3] zram: rework reported to end-user zram statistics
  2014-01-14  9:37 [PATCH 0/3] zram stats rework and code cleanup Sergey Senozhatsky
  2014-01-14  9:37 ` [PATCH 1/3] zram: drop `init_done' struct zram member Sergey Senozhatsky
  2014-01-14  9:37 ` [PATCH 2/3] zram: do not pass rw argument to __zram_make_request() Sergey Senozhatsky
@ 2014-01-14  9:37 ` Sergey Senozhatsky
  2014-01-14 10:38   ` Jerome Marchand
  2014-01-15  4:24   ` Minchan Kim
  2014-01-14  9:42 ` [PATCH 0/3] zram stats rework and code cleanup Sergey Senozhatsky
  3 siblings, 2 replies; 24+ messages in thread
From: Sergey Senozhatsky @ 2014-01-14  9:37 UTC (permalink / raw)
  To: Minchan Kim
  Cc: Jerome Marchand, Nitin Gupta, linux-kernel, Sergey Senozhatsky

1) Introduce ZRAM_ATTR_RO macro to generate zram atomic64_t stats
`show' functions and reduce code duplication.

2) Account and report back to user numbers of failed READ and WRITE
operations.

3) Remove `good' and `bad' compressed sub-requests stats. RW request may
cause a number of RW sub-requests. zram used to account `good' compressed
sub-queries (with compressed size less than 50% of original size), `bad'
compressed sub-queries (with compressed size greater that 75% of original
size), leaving sub-requests with compression size between 50% and 75% of
original size not accounted and not reported. Account each sub-request
compression size so we can calculate real device compression ratio.

4) reported zram stats:
  - num_writes  -- number of writes
  - num_reads  -- number of reads
  - pages_stored -- number of pages currently stored
  - compressed_size -- compressed size of pages stored
  - pages_zero  -- number of zero filled pages
  - failed_read -- number of failed reads
  - failed_writes -- can happen when memory is too low
  - invalid_io   -- non-page-aligned I/O requests
  - notify_free  -- number of swap slot free notifications
  - memory_used -- zs pool zs_get_total_size_bytes()

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
 drivers/block/zram/zram_drv.c | 167 ++++++++++++------------------------------
 drivers/block/zram/zram_drv.h |  17 ++---
 2 files changed, 54 insertions(+), 130 deletions(-)

diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 2a7682c..8bddaff 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -42,6 +42,17 @@ static struct zram *zram_devices;
 /* Module params (documentation at end) */
 static unsigned int num_devices = 1;
 
+#define ZRAM_ATTR_RO(name)						\
+static ssize_t zram_attr_##name##_show(struct device *d,		\
+				struct device_attribute *attr, char *b)	\
+{									\
+	struct zram *zram = dev_to_zram(d);				\
+	return sprintf(b, "%llu\n",					\
+		(u64)atomic64_read(&zram->stats.name));			\
+}									\
+static struct device_attribute dev_attr_##name =			\
+	__ATTR(name, S_IRUGO, zram_attr_##name##_show, NULL);
+
 static inline int init_done(struct zram *zram)
 {
 	return zram->meta != NULL;
@@ -52,97 +63,36 @@ static inline struct zram *dev_to_zram(struct device *dev)
 	return (struct zram *)dev_to_disk(dev)->private_data;
 }
 
-static ssize_t disksize_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct zram *zram = dev_to_zram(dev);
-
-	return sprintf(buf, "%llu\n", zram->disksize);
-}
-
-static ssize_t initstate_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct zram *zram = dev_to_zram(dev);
-
-	return sprintf(buf, "%u\n", init_done(zram));
-}
-
-static ssize_t num_reads_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct zram *zram = dev_to_zram(dev);
-
-	return sprintf(buf, "%llu\n",
-			(u64)atomic64_read(&zram->stats.num_reads));
-}
-
-static ssize_t num_writes_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct zram *zram = dev_to_zram(dev);
-
-	return sprintf(buf, "%llu\n",
-			(u64)atomic64_read(&zram->stats.num_writes));
-}
-
-static ssize_t invalid_io_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct zram *zram = dev_to_zram(dev);
-
-	return sprintf(buf, "%llu\n",
-			(u64)atomic64_read(&zram->stats.invalid_io));
-}
-
-static ssize_t notify_free_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct zram *zram = dev_to_zram(dev);
-
-	return sprintf(buf, "%llu\n",
-			(u64)atomic64_read(&zram->stats.notify_free));
-}
-
-static ssize_t zero_pages_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct zram *zram = dev_to_zram(dev);
-
-	return sprintf(buf, "%u\n", atomic_read(&zram->stats.pages_zero));
-}
-
-static ssize_t orig_data_size_show(struct device *dev,
+static ssize_t memory_used_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
+	u64 val = 0;
 	struct zram *zram = dev_to_zram(dev);
+	struct zram_meta *meta = zram->meta;
 
-	return sprintf(buf, "%llu\n",
-		(u64)(atomic_read(&zram->stats.pages_stored)) << PAGE_SHIFT);
+	down_read(&zram->init_lock);
+	if (init_done(zram))
+		val = zs_get_total_size_bytes(meta->mem_pool);
+	up_read(&zram->init_lock);
+	return sprintf(buf, "%llu\n", val);
 }
 
-static ssize_t compr_data_size_show(struct device *dev,
+static ssize_t disksize_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
 	struct zram *zram = dev_to_zram(dev);
-
-	return sprintf(buf, "%llu\n",
-			(u64)atomic64_read(&zram->stats.compr_size));
+	return sprintf(buf, "%llu\n", zram->disksize);
 }
 
-static ssize_t mem_used_total_show(struct device *dev,
+static ssize_t initstate_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
-	u64 val = 0;
+	u32 val = 0;
 	struct zram *zram = dev_to_zram(dev);
-	struct zram_meta *meta = zram->meta;
-
 	down_read(&zram->init_lock);
-	if (init_done(zram))
-		val = zs_get_total_size_bytes(meta->mem_pool);
+	val = init_done(zram);
 	up_read(&zram->init_lock);
-
-	return sprintf(buf, "%llu\n", val);
+	return sprintf(buf, "%u\n", val);
 }
 
 /* flag operations needs meta->tb_lock */
@@ -293,7 +243,6 @@ static void zram_free_page(struct zram *zram, size_t index)
 {
 	struct zram_meta *meta = zram->meta;
 	unsigned long handle = meta->table[index].handle;
-	u16 size = meta->table[index].size;
 
 	if (unlikely(!handle)) {
 		/*
@@ -302,21 +251,15 @@ static void zram_free_page(struct zram *zram, size_t index)
 		 */
 		if (zram_test_flag(meta, index, ZRAM_ZERO)) {
 			zram_clear_flag(meta, index, ZRAM_ZERO);
-			atomic_dec(&zram->stats.pages_zero);
+			atomic64_dec(&zram->stats.pages_zero);
 		}
 		return;
 	}
 
-	if (unlikely(size > max_zpage_size))
-		atomic_dec(&zram->stats.bad_compress);
-
 	zs_free(meta->mem_pool, handle);
 
-	if (size <= PAGE_SIZE / 2)
-		atomic_dec(&zram->stats.good_compress);
-
-	atomic64_sub(meta->table[index].size, &zram->stats.compr_size);
-	atomic_dec(&zram->stats.pages_stored);
+	atomic64_sub(meta->table[index].size, &zram->stats.compressed_size);
+	atomic64_dec(&zram->stats.pages_stored);
 
 	meta->table[index].handle = 0;
 	meta->table[index].size = 0;
@@ -362,7 +305,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
 static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
 			  u32 index, int offset, struct bio *bio)
 {
-	int ret;
+	int ret = -EINVAL;
 	struct page *page;
 	unsigned char *user_mem, *uncmem = NULL;
 	struct zram_meta *meta = zram->meta;
@@ -406,6 +349,8 @@ out_cleanup:
 	kunmap_atomic(user_mem);
 	if (is_partial_io(bvec))
 		kfree(uncmem);
+	if (ret)
+		atomic64_inc(&zram->stats.failed_reads);
 	return ret;
 }
 
@@ -459,7 +404,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
 		zram_set_flag(meta, index, ZRAM_ZERO);
 		write_unlock(&zram->meta->tb_lock);
 
-		atomic_inc(&zram->stats.pages_zero);
+		atomic64_inc(&zram->stats.pages_zero);
 		ret = 0;
 		goto out;
 	}
@@ -478,7 +423,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
 	}
 
 	if (unlikely(clen > max_zpage_size)) {
-		atomic_inc(&zram->stats.bad_compress);
 		clen = PAGE_SIZE;
 		src = NULL;
 		if (is_partial_io(bvec))
@@ -516,11 +460,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
 	write_unlock(&zram->meta->tb_lock);
 
 	/* Update stats */
-	atomic64_add(clen, &zram->stats.compr_size);
-	atomic_inc(&zram->stats.pages_stored);
-	if (clen <= PAGE_SIZE / 2)
-		atomic_inc(&zram->stats.good_compress);
-
+	atomic64_add(clen, &zram->stats.compressed_size);
+	atomic64_inc(&zram->stats.pages_stored);
 out:
 	if (locked)
 		mutex_unlock(&meta->buffer_lock);
@@ -586,23 +527,8 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
 
 static void zram_init_device(struct zram *zram, struct zram_meta *meta)
 {
-	if (zram->disksize > 2 * (totalram_pages << PAGE_SHIFT)) {
-		pr_info(
-		"There is little point creating a zram of greater than "
-		"twice the size of memory since we expect a 2:1 compression "
-		"ratio. Note that zram uses about 0.1%% of the size of "
-		"the disk when not in use so a huge zram is "
-		"wasteful.\n"
-		"\tMemory Size: %lu kB\n"
-		"\tSize you selected: %llu kB\n"
-		"Continuing anyway ...\n",
-		(totalram_pages << PAGE_SHIFT) >> 10, zram->disksize >> 10
-		);
-	}
-
 	/* zram devices sort of resembles non-rotational disks */
 	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
-
 	zram->meta = meta;
 	pr_debug("Initialization done!\n");
 }
@@ -774,14 +700,15 @@ static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR,
 		disksize_show, disksize_store);
 static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
 static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
-static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL);
-static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL);
-static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL);
-static DEVICE_ATTR(notify_free, S_IRUGO, notify_free_show, NULL);
-static DEVICE_ATTR(zero_pages, S_IRUGO, zero_pages_show, NULL);
-static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL);
-static DEVICE_ATTR(compr_data_size, S_IRUGO, compr_data_size_show, NULL);
-static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL);
+static DEVICE_ATTR(memory_used, S_IRUGO, memory_used_show, NULL);
+
+ZRAM_ATTR_RO(num_reads);
+ZRAM_ATTR_RO(num_writes);
+ZRAM_ATTR_RO(pages_stored);
+ZRAM_ATTR_RO(invalid_io);
+ZRAM_ATTR_RO(notify_free);
+ZRAM_ATTR_RO(pages_zero);
+ZRAM_ATTR_RO(compressed_size);
 
 static struct attribute *zram_disk_attrs[] = {
 	&dev_attr_disksize.attr,
@@ -789,12 +716,12 @@ static struct attribute *zram_disk_attrs[] = {
 	&dev_attr_reset.attr,
 	&dev_attr_num_reads.attr,
 	&dev_attr_num_writes.attr,
+	&dev_attr_pages_stored.attr,
 	&dev_attr_invalid_io.attr,
 	&dev_attr_notify_free.attr,
-	&dev_attr_zero_pages.attr,
-	&dev_attr_orig_data_size.attr,
-	&dev_attr_compr_data_size.attr,
-	&dev_attr_mem_used_total.attr,
+	&dev_attr_pages_zero.attr,
+	&dev_attr_compressed_size.attr,
+	&dev_attr_memory_used.attr,
 	NULL,
 };
 
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index e81e9cd..277023d 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -64,22 +64,19 @@ enum zram_pageflags {
 struct table {
 	unsigned long handle;
 	u16 size;	/* object size (excluding header) */
-	u8 count;	/* object ref count (not yet used) */
-	u8 flags;
+	u16 flags;
 } __aligned(4);
 
 struct zram_stats {
-	atomic64_t compr_size;	/* compressed size of pages stored */
-	atomic64_t num_reads;	/* failed + successful */
-	atomic64_t num_writes;	/* --do-- */
-	atomic64_t failed_reads;	/* should NEVER! happen */
+	atomic64_t num_writes;	/* number of writes */
+	atomic64_t num_reads;	/* number of reads */
+	atomic64_t pages_stored;	/* no. of pages currently stored */
+	atomic64_t compressed_size;	/* compressed size of pages stored */
+	atomic64_t pages_zero;		/* no. of zero filled pages */
+	atomic64_t failed_reads;	/* no. of failed reads */
 	atomic64_t failed_writes;	/* can happen when memory is too low */
 	atomic64_t invalid_io;	/* non-page-aligned I/O requests */
 	atomic64_t notify_free;	/* no. of swap slot free notifications */
-	atomic_t pages_zero;		/* no. of zero filled pages */
-	atomic_t pages_stored;	/* no. of pages currently stored */
-	atomic_t good_compress;	/* % of pages with compression ratio<=50% */
-	atomic_t bad_compress;	/* % of pages with compression ratio>=75% */
 };
 
 struct zram_meta {
-- 
1.8.5.2.487.g7559984


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH 0/3] zram stats rework and code cleanup
  2014-01-14  9:37 [PATCH 0/3] zram stats rework and code cleanup Sergey Senozhatsky
                   ` (2 preceding siblings ...)
  2014-01-14  9:37 ` [PATCH 3/3] zram: rework reported to end-user zram statistics Sergey Senozhatsky
@ 2014-01-14  9:42 ` Sergey Senozhatsky
  3 siblings, 0 replies; 24+ messages in thread
From: Sergey Senozhatsky @ 2014-01-14  9:42 UTC (permalink / raw)
  To: Minchan Kim; +Cc: Jerome Marchand, Nitin Gupta, linux-kernel

On (01/14/14 12:37), Sergey Senozhatsky wrote:
> This patchset includes code clean up and zram stats rework.
> 

forgot to mention. this patchset based on top of Minchan's
patchset.

	-ss

> Sergey Senozhatsky (3):
>   zram: drop `init_done' struct zram member
>   zram: do not pass rw argument to __zram_make_request()
>   zram: rework reported to end-user zram statistics
> 
>  drivers/block/zram/zram_drv.c | 213 ++++++++++++++----------------------------
>  drivers/block/zram/zram_drv.h |  18 ++--
>  2 files changed, 76 insertions(+), 155 deletions(-)
> 
> -- 
> 1.8.5.2.487.g7559984
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] zram: rework reported to end-user zram statistics
  2014-01-14  9:37 ` [PATCH 3/3] zram: rework reported to end-user zram statistics Sergey Senozhatsky
@ 2014-01-14 10:38   ` Jerome Marchand
  2014-01-14 10:57     ` Sergey Senozhatsky
  2014-01-14 11:10     ` Sergey Senozhatsky
  2014-01-15  4:24   ` Minchan Kim
  1 sibling, 2 replies; 24+ messages in thread
From: Jerome Marchand @ 2014-01-14 10:38 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

On 01/14/2014 10:37 AM, Sergey Senozhatsky wrote:
> 1) Introduce ZRAM_ATTR_RO macro to generate zram atomic64_t stats
> `show' functions and reduce code duplication.
> 
> 2) Account and report back to user numbers of failed READ and WRITE
> operations.
> 
> 3) Remove `good' and `bad' compressed sub-requests stats. RW request may
> cause a number of RW sub-requests. zram used to account `good' compressed
> sub-queries (with compressed size less than 50% of original size), `bad'
> compressed sub-queries (with compressed size greater that 75% of original
> size), leaving sub-requests with compression size between 50% and 75% of
> original size not accounted and not reported.

That's weird: good/bad_compress are accounted, but it seems to me that
they are to never used in any way. If so, there is indeed no reason to
keep them.

> Account each sub-request
> compression size so we can calculate real device compression ratio.

Your patch doesn't change the way pages_stored and compr[essed]_size
are accounted. What does your patch change that allow us to calculate
the "real" compression ratio?

> 
> 4) reported zram stats:
>   - num_writes  -- number of writes
>   - num_reads  -- number of reads
>   - pages_stored -- number of pages currently stored
>   - compressed_size -- compressed size of pages stored

Wouldn't it be more practical to report the original and compressed
data sizes using the same units as it is currently done?

Jerome

>   - pages_zero  -- number of zero filled pages
>   - failed_read -- number of failed reads
>   - failed_writes -- can happen when memory is too low
>   - invalid_io   -- non-page-aligned I/O requests
>   - notify_free  -- number of swap slot free notifications
>   - memory_used -- zs pool zs_get_total_size_bytes()
> 
> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> ---
>  drivers/block/zram/zram_drv.c | 167 ++++++++++++------------------------------
>  drivers/block/zram/zram_drv.h |  17 ++---
>  2 files changed, 54 insertions(+), 130 deletions(-)
> 
> diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> index 2a7682c..8bddaff 100644
> --- a/drivers/block/zram/zram_drv.c
> +++ b/drivers/block/zram/zram_drv.c
> @@ -42,6 +42,17 @@ static struct zram *zram_devices;
>  /* Module params (documentation at end) */
>  static unsigned int num_devices = 1;
>  
> +#define ZRAM_ATTR_RO(name)						\
> +static ssize_t zram_attr_##name##_show(struct device *d,		\
> +				struct device_attribute *attr, char *b)	\
> +{									\
> +	struct zram *zram = dev_to_zram(d);				\
> +	return sprintf(b, "%llu\n",					\
> +		(u64)atomic64_read(&zram->stats.name));			\
> +}									\
> +static struct device_attribute dev_attr_##name =			\
> +	__ATTR(name, S_IRUGO, zram_attr_##name##_show, NULL);
> +
>  static inline int init_done(struct zram *zram)
>  {
>  	return zram->meta != NULL;
> @@ -52,97 +63,36 @@ static inline struct zram *dev_to_zram(struct device *dev)
>  	return (struct zram *)dev_to_disk(dev)->private_data;
>  }
>  
> -static ssize_t disksize_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%llu\n", zram->disksize);
> -}
> -
> -static ssize_t initstate_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%u\n", init_done(zram));
> -}
> -
> -static ssize_t num_reads_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%llu\n",
> -			(u64)atomic64_read(&zram->stats.num_reads));
> -}
> -
> -static ssize_t num_writes_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%llu\n",
> -			(u64)atomic64_read(&zram->stats.num_writes));
> -}
> -
> -static ssize_t invalid_io_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%llu\n",
> -			(u64)atomic64_read(&zram->stats.invalid_io));
> -}
> -
> -static ssize_t notify_free_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%llu\n",
> -			(u64)atomic64_read(&zram->stats.notify_free));
> -}
> -
> -static ssize_t zero_pages_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%u\n", atomic_read(&zram->stats.pages_zero));
> -}
> -
> -static ssize_t orig_data_size_show(struct device *dev,
> +static ssize_t memory_used_show(struct device *dev,
>  		struct device_attribute *attr, char *buf)
>  {
> +	u64 val = 0;
>  	struct zram *zram = dev_to_zram(dev);
> +	struct zram_meta *meta = zram->meta;
>  
> -	return sprintf(buf, "%llu\n",
> -		(u64)(atomic_read(&zram->stats.pages_stored)) << PAGE_SHIFT);
> +	down_read(&zram->init_lock);
> +	if (init_done(zram))
> +		val = zs_get_total_size_bytes(meta->mem_pool);
> +	up_read(&zram->init_lock);
> +	return sprintf(buf, "%llu\n", val);
>  }
>  
> -static ssize_t compr_data_size_show(struct device *dev,
> +static ssize_t disksize_show(struct device *dev,
>  		struct device_attribute *attr, char *buf)
>  {
>  	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%llu\n",
> -			(u64)atomic64_read(&zram->stats.compr_size));
> +	return sprintf(buf, "%llu\n", zram->disksize);
>  }
>  
> -static ssize_t mem_used_total_show(struct device *dev,
> +static ssize_t initstate_show(struct device *dev,
>  		struct device_attribute *attr, char *buf)
>  {
> -	u64 val = 0;
> +	u32 val = 0;
>  	struct zram *zram = dev_to_zram(dev);
> -	struct zram_meta *meta = zram->meta;
> -
>  	down_read(&zram->init_lock);
> -	if (init_done(zram))
> -		val = zs_get_total_size_bytes(meta->mem_pool);
> +	val = init_done(zram);
>  	up_read(&zram->init_lock);
> -
> -	return sprintf(buf, "%llu\n", val);
> +	return sprintf(buf, "%u\n", val);
>  }
>  
>  /* flag operations needs meta->tb_lock */
> @@ -293,7 +243,6 @@ static void zram_free_page(struct zram *zram, size_t index)
>  {
>  	struct zram_meta *meta = zram->meta;
>  	unsigned long handle = meta->table[index].handle;
> -	u16 size = meta->table[index].size;
>  
>  	if (unlikely(!handle)) {
>  		/*
> @@ -302,21 +251,15 @@ static void zram_free_page(struct zram *zram, size_t index)
>  		 */
>  		if (zram_test_flag(meta, index, ZRAM_ZERO)) {
>  			zram_clear_flag(meta, index, ZRAM_ZERO);
> -			atomic_dec(&zram->stats.pages_zero);
> +			atomic64_dec(&zram->stats.pages_zero);
>  		}
>  		return;
>  	}
>  
> -	if (unlikely(size > max_zpage_size))
> -		atomic_dec(&zram->stats.bad_compress);
> -
>  	zs_free(meta->mem_pool, handle);
>  
> -	if (size <= PAGE_SIZE / 2)
> -		atomic_dec(&zram->stats.good_compress);
> -
> -	atomic64_sub(meta->table[index].size, &zram->stats.compr_size);
> -	atomic_dec(&zram->stats.pages_stored);
> +	atomic64_sub(meta->table[index].size, &zram->stats.compressed_size);
> +	atomic64_dec(&zram->stats.pages_stored);
>  
>  	meta->table[index].handle = 0;
>  	meta->table[index].size = 0;
> @@ -362,7 +305,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
>  static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
>  			  u32 index, int offset, struct bio *bio)
>  {
> -	int ret;
> +	int ret = -EINVAL;
>  	struct page *page;
>  	unsigned char *user_mem, *uncmem = NULL;
>  	struct zram_meta *meta = zram->meta;
> @@ -406,6 +349,8 @@ out_cleanup:
>  	kunmap_atomic(user_mem);
>  	if (is_partial_io(bvec))
>  		kfree(uncmem);
> +	if (ret)
> +		atomic64_inc(&zram->stats.failed_reads);
>  	return ret;
>  }
>  
> @@ -459,7 +404,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
>  		zram_set_flag(meta, index, ZRAM_ZERO);
>  		write_unlock(&zram->meta->tb_lock);
>  
> -		atomic_inc(&zram->stats.pages_zero);
> +		atomic64_inc(&zram->stats.pages_zero);
>  		ret = 0;
>  		goto out;
>  	}
> @@ -478,7 +423,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
>  	}
>  
>  	if (unlikely(clen > max_zpage_size)) {
> -		atomic_inc(&zram->stats.bad_compress);
>  		clen = PAGE_SIZE;
>  		src = NULL;
>  		if (is_partial_io(bvec))
> @@ -516,11 +460,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
>  	write_unlock(&zram->meta->tb_lock);
>  
>  	/* Update stats */
> -	atomic64_add(clen, &zram->stats.compr_size);
> -	atomic_inc(&zram->stats.pages_stored);
> -	if (clen <= PAGE_SIZE / 2)
> -		atomic_inc(&zram->stats.good_compress);
> -
> +	atomic64_add(clen, &zram->stats.compressed_size);
> +	atomic64_inc(&zram->stats.pages_stored);
>  out:
>  	if (locked)
>  		mutex_unlock(&meta->buffer_lock);
> @@ -586,23 +527,8 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
>  
>  static void zram_init_device(struct zram *zram, struct zram_meta *meta)
>  {
> -	if (zram->disksize > 2 * (totalram_pages << PAGE_SHIFT)) {
> -		pr_info(
> -		"There is little point creating a zram of greater than "
> -		"twice the size of memory since we expect a 2:1 compression "
> -		"ratio. Note that zram uses about 0.1%% of the size of "
> -		"the disk when not in use so a huge zram is "
> -		"wasteful.\n"
> -		"\tMemory Size: %lu kB\n"
> -		"\tSize you selected: %llu kB\n"
> -		"Continuing anyway ...\n",
> -		(totalram_pages << PAGE_SHIFT) >> 10, zram->disksize >> 10
> -		);
> -	}
> -
>  	/* zram devices sort of resembles non-rotational disks */
>  	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
> -
>  	zram->meta = meta;
>  	pr_debug("Initialization done!\n");
>  }
> @@ -774,14 +700,15 @@ static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR,
>  		disksize_show, disksize_store);
>  static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
>  static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
> -static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL);
> -static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL);
> -static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL);
> -static DEVICE_ATTR(notify_free, S_IRUGO, notify_free_show, NULL);
> -static DEVICE_ATTR(zero_pages, S_IRUGO, zero_pages_show, NULL);
> -static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL);
> -static DEVICE_ATTR(compr_data_size, S_IRUGO, compr_data_size_show, NULL);
> -static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL);
> +static DEVICE_ATTR(memory_used, S_IRUGO, memory_used_show, NULL);
> +
> +ZRAM_ATTR_RO(num_reads);
> +ZRAM_ATTR_RO(num_writes);
> +ZRAM_ATTR_RO(pages_stored);
> +ZRAM_ATTR_RO(invalid_io);
> +ZRAM_ATTR_RO(notify_free);
> +ZRAM_ATTR_RO(pages_zero);
> +ZRAM_ATTR_RO(compressed_size);
>  
>  static struct attribute *zram_disk_attrs[] = {
>  	&dev_attr_disksize.attr,
> @@ -789,12 +716,12 @@ static struct attribute *zram_disk_attrs[] = {
>  	&dev_attr_reset.attr,
>  	&dev_attr_num_reads.attr,
>  	&dev_attr_num_writes.attr,
> +	&dev_attr_pages_stored.attr,
>  	&dev_attr_invalid_io.attr,
>  	&dev_attr_notify_free.attr,
> -	&dev_attr_zero_pages.attr,
> -	&dev_attr_orig_data_size.attr,
> -	&dev_attr_compr_data_size.attr,
> -	&dev_attr_mem_used_total.attr,
> +	&dev_attr_pages_zero.attr,
> +	&dev_attr_compressed_size.attr,
> +	&dev_attr_memory_used.attr,
>  	NULL,
>  };
>  
> diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
> index e81e9cd..277023d 100644
> --- a/drivers/block/zram/zram_drv.h
> +++ b/drivers/block/zram/zram_drv.h
> @@ -64,22 +64,19 @@ enum zram_pageflags {
>  struct table {
>  	unsigned long handle;
>  	u16 size;	/* object size (excluding header) */
> -	u8 count;	/* object ref count (not yet used) */
> -	u8 flags;
> +	u16 flags;
>  } __aligned(4);
>  
>  struct zram_stats {
> -	atomic64_t compr_size;	/* compressed size of pages stored */
> -	atomic64_t num_reads;	/* failed + successful */
> -	atomic64_t num_writes;	/* --do-- */
> -	atomic64_t failed_reads;	/* should NEVER! happen */
> +	atomic64_t num_writes;	/* number of writes */
> +	atomic64_t num_reads;	/* number of reads */
> +	atomic64_t pages_stored;	/* no. of pages currently stored */
> +	atomic64_t compressed_size;	/* compressed size of pages stored */
> +	atomic64_t pages_zero;		/* no. of zero filled pages */
> +	atomic64_t failed_reads;	/* no. of failed reads */
>  	atomic64_t failed_writes;	/* can happen when memory is too low */
>  	atomic64_t invalid_io;	/* non-page-aligned I/O requests */
>  	atomic64_t notify_free;	/* no. of swap slot free notifications */
> -	atomic_t pages_zero;		/* no. of zero filled pages */
> -	atomic_t pages_stored;	/* no. of pages currently stored */
> -	atomic_t good_compress;	/* % of pages with compression ratio<=50% */
> -	atomic_t bad_compress;	/* % of pages with compression ratio>=75% */
>  };
>  
>  struct zram_meta {
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] zram: rework reported to end-user zram statistics
  2014-01-14 10:38   ` Jerome Marchand
@ 2014-01-14 10:57     ` Sergey Senozhatsky
  2014-01-14 12:15       ` Jerome Marchand
  2014-01-14 11:10     ` Sergey Senozhatsky
  1 sibling, 1 reply; 24+ messages in thread
From: Sergey Senozhatsky @ 2014-01-14 10:57 UTC (permalink / raw)
  To: Jerome Marchand; +Cc: Minchan Kim, Nitin Gupta, linux-kernel


Hello Jerome,

On (01/14/14 11:38), Jerome Marchand wrote:
> On 01/14/2014 10:37 AM, Sergey Senozhatsky wrote:
> > 1) Introduce ZRAM_ATTR_RO macro to generate zram atomic64_t stats
> > `show' functions and reduce code duplication.
> > 
> > 2) Account and report back to user numbers of failed READ and WRITE
> > operations.
> > 
> > 3) Remove `good' and `bad' compressed sub-requests stats. RW request may
> > cause a number of RW sub-requests. zram used to account `good' compressed
> > sub-queries (with compressed size less than 50% of original size), `bad'
> > compressed sub-queries (with compressed size greater that 75% of original
> > size), leaving sub-requests with compression size between 50% and 75% of
> > original size not accounted and not reported.
> 
> That's weird: good/bad_compress are accounted, but it seems to me that
> they are to never used in any way. If so, there is indeed no reason to
> keep them.
> 
>
> > Account each sub-request
> > compression size so we can calculate real device compression ratio.
> 
> Your patch doesn't change the way pages_stored and compr[essed]_size
> are accounted. What does your patch change that allow us to calculate
> the "real" compression ratio?

we have compressed size, number of stored pages and reported by zs pool
(as a zram memory_used attr) number of bytes used

u64 zs_get_total_size_bytes(struct zs_pool *pool)
{
        int i;
        u64 npages = 0;

        for (i = 0; i < ZS_SIZE_CLASSES; i++)
                npages += pool->size_class[i].pages_allocated;

        return npages << PAGE_SHIFT;
}

looks enough to calculate device overall data compression ratio.

	-ss

> > 
> > 4) reported zram stats:
> >   - num_writes  -- number of writes
> >   - num_reads  -- number of reads
> >   - pages_stored -- number of pages currently stored
> >   - compressed_size -- compressed size of pages stored
> 
> Wouldn't it be more practical to report the original and compressed
> data sizes using the same units as it is currently done?
> 

sorry, not sure I understand.

> Jerome
> 
> >   - pages_zero  -- number of zero filled pages
> >   - failed_read -- number of failed reads
> >   - failed_writes -- can happen when memory is too low
> >   - invalid_io   -- non-page-aligned I/O requests
> >   - notify_free  -- number of swap slot free notifications
> >   - memory_used -- zs pool zs_get_total_size_bytes()
> > 
> > Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> > ---
> >  drivers/block/zram/zram_drv.c | 167 ++++++++++++------------------------------
> >  drivers/block/zram/zram_drv.h |  17 ++---
> >  2 files changed, 54 insertions(+), 130 deletions(-)
> > 
> > diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> > index 2a7682c..8bddaff 100644
> > --- a/drivers/block/zram/zram_drv.c
> > +++ b/drivers/block/zram/zram_drv.c
> > @@ -42,6 +42,17 @@ static struct zram *zram_devices;
> >  /* Module params (documentation at end) */
> >  static unsigned int num_devices = 1;
> >  
> > +#define ZRAM_ATTR_RO(name)						\
> > +static ssize_t zram_attr_##name##_show(struct device *d,		\
> > +				struct device_attribute *attr, char *b)	\
> > +{									\
> > +	struct zram *zram = dev_to_zram(d);				\
> > +	return sprintf(b, "%llu\n",					\
> > +		(u64)atomic64_read(&zram->stats.name));			\
> > +}									\
> > +static struct device_attribute dev_attr_##name =			\
> > +	__ATTR(name, S_IRUGO, zram_attr_##name##_show, NULL);
> > +
> >  static inline int init_done(struct zram *zram)
> >  {
> >  	return zram->meta != NULL;
> > @@ -52,97 +63,36 @@ static inline struct zram *dev_to_zram(struct device *dev)
> >  	return (struct zram *)dev_to_disk(dev)->private_data;
> >  }
> >  
> > -static ssize_t disksize_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n", zram->disksize);
> > -}
> > -
> > -static ssize_t initstate_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%u\n", init_done(zram));
> > -}
> > -
> > -static ssize_t num_reads_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.num_reads));
> > -}
> > -
> > -static ssize_t num_writes_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.num_writes));
> > -}
> > -
> > -static ssize_t invalid_io_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.invalid_io));
> > -}
> > -
> > -static ssize_t notify_free_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.notify_free));
> > -}
> > -
> > -static ssize_t zero_pages_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%u\n", atomic_read(&zram->stats.pages_zero));
> > -}
> > -
> > -static ssize_t orig_data_size_show(struct device *dev,
> > +static ssize_t memory_used_show(struct device *dev,
> >  		struct device_attribute *attr, char *buf)
> >  {
> > +	u64 val = 0;
> >  	struct zram *zram = dev_to_zram(dev);
> > +	struct zram_meta *meta = zram->meta;
> >  
> > -	return sprintf(buf, "%llu\n",
> > -		(u64)(atomic_read(&zram->stats.pages_stored)) << PAGE_SHIFT);
> > +	down_read(&zram->init_lock);
> > +	if (init_done(zram))
> > +		val = zs_get_total_size_bytes(meta->mem_pool);
> > +	up_read(&zram->init_lock);
> > +	return sprintf(buf, "%llu\n", val);
> >  }
> >  
> > -static ssize_t compr_data_size_show(struct device *dev,
> > +static ssize_t disksize_show(struct device *dev,
> >  		struct device_attribute *attr, char *buf)
> >  {
> >  	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.compr_size));
> > +	return sprintf(buf, "%llu\n", zram->disksize);
> >  }
> >  
> > -static ssize_t mem_used_total_show(struct device *dev,
> > +static ssize_t initstate_show(struct device *dev,
> >  		struct device_attribute *attr, char *buf)
> >  {
> > -	u64 val = 0;
> > +	u32 val = 0;
> >  	struct zram *zram = dev_to_zram(dev);
> > -	struct zram_meta *meta = zram->meta;
> > -
> >  	down_read(&zram->init_lock);
> > -	if (init_done(zram))
> > -		val = zs_get_total_size_bytes(meta->mem_pool);
> > +	val = init_done(zram);
> >  	up_read(&zram->init_lock);
> > -
> > -	return sprintf(buf, "%llu\n", val);
> > +	return sprintf(buf, "%u\n", val);
> >  }
> >  
> >  /* flag operations needs meta->tb_lock */
> > @@ -293,7 +243,6 @@ static void zram_free_page(struct zram *zram, size_t index)
> >  {
> >  	struct zram_meta *meta = zram->meta;
> >  	unsigned long handle = meta->table[index].handle;
> > -	u16 size = meta->table[index].size;
> >  
> >  	if (unlikely(!handle)) {
> >  		/*
> > @@ -302,21 +251,15 @@ static void zram_free_page(struct zram *zram, size_t index)
> >  		 */
> >  		if (zram_test_flag(meta, index, ZRAM_ZERO)) {
> >  			zram_clear_flag(meta, index, ZRAM_ZERO);
> > -			atomic_dec(&zram->stats.pages_zero);
> > +			atomic64_dec(&zram->stats.pages_zero);
> >  		}
> >  		return;
> >  	}
> >  
> > -	if (unlikely(size > max_zpage_size))
> > -		atomic_dec(&zram->stats.bad_compress);
> > -
> >  	zs_free(meta->mem_pool, handle);
> >  
> > -	if (size <= PAGE_SIZE / 2)
> > -		atomic_dec(&zram->stats.good_compress);
> > -
> > -	atomic64_sub(meta->table[index].size, &zram->stats.compr_size);
> > -	atomic_dec(&zram->stats.pages_stored);
> > +	atomic64_sub(meta->table[index].size, &zram->stats.compressed_size);
> > +	atomic64_dec(&zram->stats.pages_stored);
> >  
> >  	meta->table[index].handle = 0;
> >  	meta->table[index].size = 0;
> > @@ -362,7 +305,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
> >  static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
> >  			  u32 index, int offset, struct bio *bio)
> >  {
> > -	int ret;
> > +	int ret = -EINVAL;
> >  	struct page *page;
> >  	unsigned char *user_mem, *uncmem = NULL;
> >  	struct zram_meta *meta = zram->meta;
> > @@ -406,6 +349,8 @@ out_cleanup:
> >  	kunmap_atomic(user_mem);
> >  	if (is_partial_io(bvec))
> >  		kfree(uncmem);
> > +	if (ret)
> > +		atomic64_inc(&zram->stats.failed_reads);
> >  	return ret;
> >  }
> >  
> > @@ -459,7 +404,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
> >  		zram_set_flag(meta, index, ZRAM_ZERO);
> >  		write_unlock(&zram->meta->tb_lock);
> >  
> > -		atomic_inc(&zram->stats.pages_zero);
> > +		atomic64_inc(&zram->stats.pages_zero);
> >  		ret = 0;
> >  		goto out;
> >  	}
> > @@ -478,7 +423,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
> >  	}
> >  
> >  	if (unlikely(clen > max_zpage_size)) {
> > -		atomic_inc(&zram->stats.bad_compress);
> >  		clen = PAGE_SIZE;
> >  		src = NULL;
> >  		if (is_partial_io(bvec))
> > @@ -516,11 +460,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
> >  	write_unlock(&zram->meta->tb_lock);
> >  
> >  	/* Update stats */
> > -	atomic64_add(clen, &zram->stats.compr_size);
> > -	atomic_inc(&zram->stats.pages_stored);
> > -	if (clen <= PAGE_SIZE / 2)
> > -		atomic_inc(&zram->stats.good_compress);
> > -
> > +	atomic64_add(clen, &zram->stats.compressed_size);
> > +	atomic64_inc(&zram->stats.pages_stored);
> >  out:
> >  	if (locked)
> >  		mutex_unlock(&meta->buffer_lock);
> > @@ -586,23 +527,8 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
> >  
> >  static void zram_init_device(struct zram *zram, struct zram_meta *meta)
> >  {
> > -	if (zram->disksize > 2 * (totalram_pages << PAGE_SHIFT)) {
> > -		pr_info(
> > -		"There is little point creating a zram of greater than "
> > -		"twice the size of memory since we expect a 2:1 compression "
> > -		"ratio. Note that zram uses about 0.1%% of the size of "
> > -		"the disk when not in use so a huge zram is "
> > -		"wasteful.\n"
> > -		"\tMemory Size: %lu kB\n"
> > -		"\tSize you selected: %llu kB\n"
> > -		"Continuing anyway ...\n",
> > -		(totalram_pages << PAGE_SHIFT) >> 10, zram->disksize >> 10
> > -		);
> > -	}
> > -
> >  	/* zram devices sort of resembles non-rotational disks */
> >  	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
> > -
> >  	zram->meta = meta;
> >  	pr_debug("Initialization done!\n");
> >  }
> > @@ -774,14 +700,15 @@ static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR,
> >  		disksize_show, disksize_store);
> >  static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
> >  static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
> > -static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL);
> > -static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL);
> > -static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL);
> > -static DEVICE_ATTR(notify_free, S_IRUGO, notify_free_show, NULL);
> > -static DEVICE_ATTR(zero_pages, S_IRUGO, zero_pages_show, NULL);
> > -static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL);
> > -static DEVICE_ATTR(compr_data_size, S_IRUGO, compr_data_size_show, NULL);
> > -static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL);
> > +static DEVICE_ATTR(memory_used, S_IRUGO, memory_used_show, NULL);
> > +
> > +ZRAM_ATTR_RO(num_reads);
> > +ZRAM_ATTR_RO(num_writes);
> > +ZRAM_ATTR_RO(pages_stored);
> > +ZRAM_ATTR_RO(invalid_io);
> > +ZRAM_ATTR_RO(notify_free);
> > +ZRAM_ATTR_RO(pages_zero);
> > +ZRAM_ATTR_RO(compressed_size);
> >  
> >  static struct attribute *zram_disk_attrs[] = {
> >  	&dev_attr_disksize.attr,
> > @@ -789,12 +716,12 @@ static struct attribute *zram_disk_attrs[] = {
> >  	&dev_attr_reset.attr,
> >  	&dev_attr_num_reads.attr,
> >  	&dev_attr_num_writes.attr,
> > +	&dev_attr_pages_stored.attr,
> >  	&dev_attr_invalid_io.attr,
> >  	&dev_attr_notify_free.attr,
> > -	&dev_attr_zero_pages.attr,
> > -	&dev_attr_orig_data_size.attr,
> > -	&dev_attr_compr_data_size.attr,
> > -	&dev_attr_mem_used_total.attr,
> > +	&dev_attr_pages_zero.attr,
> > +	&dev_attr_compressed_size.attr,
> > +	&dev_attr_memory_used.attr,
> >  	NULL,
> >  };
> >  
> > diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
> > index e81e9cd..277023d 100644
> > --- a/drivers/block/zram/zram_drv.h
> > +++ b/drivers/block/zram/zram_drv.h
> > @@ -64,22 +64,19 @@ enum zram_pageflags {
> >  struct table {
> >  	unsigned long handle;
> >  	u16 size;	/* object size (excluding header) */
> > -	u8 count;	/* object ref count (not yet used) */
> > -	u8 flags;
> > +	u16 flags;
> >  } __aligned(4);
> >  
> >  struct zram_stats {
> > -	atomic64_t compr_size;	/* compressed size of pages stored */
> > -	atomic64_t num_reads;	/* failed + successful */
> > -	atomic64_t num_writes;	/* --do-- */
> > -	atomic64_t failed_reads;	/* should NEVER! happen */
> > +	atomic64_t num_writes;	/* number of writes */
> > +	atomic64_t num_reads;	/* number of reads */
> > +	atomic64_t pages_stored;	/* no. of pages currently stored */
> > +	atomic64_t compressed_size;	/* compressed size of pages stored */
> > +	atomic64_t pages_zero;		/* no. of zero filled pages */
> > +	atomic64_t failed_reads;	/* no. of failed reads */
> >  	atomic64_t failed_writes;	/* can happen when memory is too low */
> >  	atomic64_t invalid_io;	/* non-page-aligned I/O requests */
> >  	atomic64_t notify_free;	/* no. of swap slot free notifications */
> > -	atomic_t pages_zero;		/* no. of zero filled pages */
> > -	atomic_t pages_stored;	/* no. of pages currently stored */
> > -	atomic_t good_compress;	/* % of pages with compression ratio<=50% */
> > -	atomic_t bad_compress;	/* % of pages with compression ratio>=75% */
> >  };
> >  
> >  struct zram_meta {
> > 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 2/3] zram: do not pass rw argument to __zram_make_request()
  2014-01-14  9:37 ` [PATCH 2/3] zram: do not pass rw argument to __zram_make_request() Sergey Senozhatsky
@ 2014-01-14 11:02   ` Jerome Marchand
  2014-01-14 11:13     ` Sergey Senozhatsky
  2014-01-14 11:27     ` [PATCHv2 " Sergey Senozhatsky
  0 siblings, 2 replies; 24+ messages in thread
From: Jerome Marchand @ 2014-01-14 11:02 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

On 01/14/2014 10:37 AM, Sergey Senozhatsky wrote:
> Do not pass rw argument down the __zram_make_request() -> zram_bvec_rw()
> chain, decode it in zram_bvec_rw() instead. Besides, this is the place
> where we distinguish READ (+READ AHEAD) and WRITE bio data directions, so
> account zram RW stats here, instead of __zram_make_request(). This also
> allows to account a real number of zram READ/WRITE operations, not just
> requests (single RW request may cause a number of zram RW ops with separate
> locking, compression/decompression, etc).
> 
> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> ---
>  drivers/block/zram/zram_drv.c | 33 +++++++++++++++------------------
>  1 file changed, 15 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> index c323e05..2a7682c 100644
> --- a/drivers/block/zram/zram_drv.c
> +++ b/drivers/block/zram/zram_drv.c
> @@ -533,14 +533,21 @@ out:
>  }
>  
>  static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index,
> -			int offset, struct bio *bio, int rw)
> +			int offset, struct bio *bio)
>  {
>  	int ret;
> +	int rw = bio_data_dir(bio);
>  
> -	if (rw == READ)
> +	if (rw == READA)
> +		rw = READ;

This could never happen: bio_data_dir() can only return READ or WRITE.

Jerome

> +
> +	if (rw == READ) {
> +		atomic64_inc(&zram->stats.num_reads);
>  		ret = zram_bvec_read(zram, bvec, index, offset, bio);
> -	else
> +	} else {
> +		atomic64_inc(&zram->stats.num_writes);
>  		ret = zram_bvec_write(zram, bvec, index, offset);
> +	}
>  
>  	return ret;
>  }
> @@ -670,22 +677,13 @@ out:
>  	return ret;
>  }
>  
> -static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
> +static void __zram_make_request(struct zram *zram, struct bio *bio)
>  {
>  	int offset;
>  	u32 index;
>  	struct bio_vec bvec;
>  	struct bvec_iter iter;
>  
> -	switch (rw) {
> -	case READ:
> -		atomic64_inc(&zram->stats.num_reads);
> -		break;
> -	case WRITE:
> -		atomic64_inc(&zram->stats.num_writes);
> -		break;
> -	}
> -
>  	index = bio->bi_iter.bi_sector >> SECTORS_PER_PAGE_SHIFT;
>  	offset = (bio->bi_iter.bi_sector &
>  		  (SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT;
> @@ -704,16 +702,15 @@ static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
>  			bv.bv_len = max_transfer_size;
>  			bv.bv_offset = bvec.bv_offset;
>  
> -			if (zram_bvec_rw(zram, &bv, index, offset, bio, rw) < 0)
> +			if (zram_bvec_rw(zram, &bv, index, offset, bio) < 0)
>  				goto out;
>  
>  			bv.bv_len = bvec.bv_len - max_transfer_size;
>  			bv.bv_offset += max_transfer_size;
> -			if (zram_bvec_rw(zram, &bv, index+1, 0, bio, rw) < 0)
> +			if (zram_bvec_rw(zram, &bv, index + 1, 0, bio) < 0)
>  				goto out;
>  		} else
> -			if (zram_bvec_rw(zram, &bvec, index, offset, bio, rw)
> -			    < 0)
> +			if (zram_bvec_rw(zram, &bvec, index, offset, bio) < 0)
>  				goto out;
>  
>  		update_position(&index, &offset, &bvec);
> @@ -743,7 +740,7 @@ static void zram_make_request(struct request_queue *queue, struct bio *bio)
>  		goto error;
>  	}
>  
> -	__zram_make_request(zram, bio, bio_data_dir(bio));
> +	__zram_make_request(zram, bio);
>  	up_read(&zram->init_lock);
>  
>  	return;
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/3] zram: drop `init_done' struct zram member
  2014-01-14  9:37 ` [PATCH 1/3] zram: drop `init_done' struct zram member Sergey Senozhatsky
@ 2014-01-14 11:03   ` Jerome Marchand
  2014-01-15  1:52   ` Minchan Kim
  1 sibling, 0 replies; 24+ messages in thread
From: Jerome Marchand @ 2014-01-14 11:03 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

On 01/14/2014 10:37 AM, Sergey Senozhatsky wrote:
> Introduce init_done() helper function which allows us to drop
> `init_done' struct zram member. init_done() uses the fact that
> ->init_done == 1 equals to ->meta != NULL.
> 
> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>

Acked-by: Jerome Marchand <jmarchan@redhat.com>

> ---
>  drivers/block/zram/zram_drv.c | 21 +++++++++++----------
>  drivers/block/zram/zram_drv.h |  1 -
>  2 files changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> index 011e55d..c323e05 100644
> --- a/drivers/block/zram/zram_drv.c
> +++ b/drivers/block/zram/zram_drv.c
> @@ -42,6 +42,11 @@ static struct zram *zram_devices;
>  /* Module params (documentation at end) */
>  static unsigned int num_devices = 1;
>  
> +static inline int init_done(struct zram *zram)
> +{
> +	return zram->meta != NULL;
> +}
> +
>  static inline struct zram *dev_to_zram(struct device *dev)
>  {
>  	return (struct zram *)dev_to_disk(dev)->private_data;
> @@ -60,7 +65,7 @@ static ssize_t initstate_show(struct device *dev,
>  {
>  	struct zram *zram = dev_to_zram(dev);
>  
> -	return sprintf(buf, "%u\n", zram->init_done);
> +	return sprintf(buf, "%u\n", init_done(zram));
>  }
>  
>  static ssize_t num_reads_show(struct device *dev,
> @@ -133,7 +138,7 @@ static ssize_t mem_used_total_show(struct device *dev,
>  	struct zram_meta *meta = zram->meta;
>  
>  	down_read(&zram->init_lock);
> -	if (zram->init_done)
> +	if (init_done(zram))
>  		val = zs_get_total_size_bytes(meta->mem_pool);
>  	up_read(&zram->init_lock);
>  
> @@ -546,14 +551,12 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
>  	struct zram_meta *meta;
>  
>  	down_write(&zram->init_lock);
> -	if (!zram->init_done) {
> +	if (!init_done(zram)) {
>  		up_write(&zram->init_lock);
>  		return;
>  	}
>  
>  	meta = zram->meta;
> -	zram->init_done = 0;
> -
>  	/* Free all pages that are still in this zram device */
>  	for (index = 0; index < zram->disksize >> PAGE_SHIFT; index++) {
>  		unsigned long handle = meta->table[index].handle;
> @@ -594,8 +597,6 @@ static void zram_init_device(struct zram *zram, struct zram_meta *meta)
>  	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
>  
>  	zram->meta = meta;
> -	zram->init_done = 1;
> -
>  	pr_debug("Initialization done!\n");
>  }
>  
> @@ -613,7 +614,7 @@ static ssize_t disksize_store(struct device *dev,
>  	disksize = PAGE_ALIGN(disksize);
>  	meta = zram_meta_alloc(disksize);
>  	down_write(&zram->init_lock);
> -	if (zram->init_done) {
> +	if (init_done(zram)) {
>  		up_write(&zram->init_lock);
>  		zram_meta_free(meta);
>  		pr_info("Cannot change disksize for initialized device\n");
> @@ -734,7 +735,7 @@ static void zram_make_request(struct request_queue *queue, struct bio *bio)
>  	struct zram *zram = queue->queuedata;
>  
>  	down_read(&zram->init_lock);
> -	if (unlikely(!zram->init_done))
> +	if (unlikely(!init_done(zram)))
>  		goto error;
>  
>  	if (!valid_io_request(zram, bio)) {
> @@ -857,7 +858,7 @@ static int create_device(struct zram *zram, int device_id)
>  		goto out_free_disk;
>  	}
>  
> -	zram->init_done = 0;
> +	zram->meta = NULL;
>  	return 0;
>  
>  out_free_disk:
> diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
> index ad8aa35..e81e9cd 100644
> --- a/drivers/block/zram/zram_drv.h
> +++ b/drivers/block/zram/zram_drv.h
> @@ -95,7 +95,6 @@ struct zram {
>  	struct zram_meta *meta;
>  	struct request_queue *queue;
>  	struct gendisk *disk;
> -	int init_done;
>  	/* Prevent concurrent execution of device init, reset and R/W request */
>  	struct rw_semaphore init_lock;
>  	/*
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] zram: rework reported to end-user zram statistics
  2014-01-14 10:38   ` Jerome Marchand
  2014-01-14 10:57     ` Sergey Senozhatsky
@ 2014-01-14 11:10     ` Sergey Senozhatsky
  2014-01-14 13:43       ` Jerome Marchand
  1 sibling, 1 reply; 24+ messages in thread
From: Sergey Senozhatsky @ 2014-01-14 11:10 UTC (permalink / raw)
  To: Jerome Marchand; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

On (01/14/14 11:38), Jerome Marchand wrote:
> On 01/14/2014 10:37 AM, Sergey Senozhatsky wrote:
> > 1) Introduce ZRAM_ATTR_RO macro to generate zram atomic64_t stats
> > `show' functions and reduce code duplication.
> > 
> > 2) Account and report back to user numbers of failed READ and WRITE
> > operations.
> > 
> > 3) Remove `good' and `bad' compressed sub-requests stats. RW request may
> > cause a number of RW sub-requests. zram used to account `good' compressed
> > sub-queries (with compressed size less than 50% of original size), `bad'
> > compressed sub-queries (with compressed size greater that 75% of original
> > size), leaving sub-requests with compression size between 50% and 75% of
> > original size not accounted and not reported.
> 
> That's weird: good/bad_compress are accounted, but it seems to me that
> they are to never used in any way. If so, there is indeed no reason to
> keep them.
> 
>
> > Account each sub-request
> > compression size so we can calculate real device compression ratio.
> 
> Your patch doesn't change the way pages_stored and compr[essed]_size
> are accounted. What does your patch change that allow us to calculate
> the "real" compression ratio?
> 
> > 
> > 4) reported zram stats:
> >   - num_writes  -- number of writes
> >   - num_reads  -- number of reads
> >   - pages_stored -- number of pages currently stored
> >   - compressed_size -- compressed size of pages stored
> 
> Wouldn't it be more practical to report the original and compressed
> data sizes using the same units as it is currently done?
> 

hm, do we really need pages_stored stats? what kind of unseful information it
shows to end user?.. perhaps, it's better to replace it with accounted passed
bvec->bv_len (as uncompressed_size).

	-ss

> Jerome
> 
> >   - pages_zero  -- number of zero filled pages
> >   - failed_read -- number of failed reads
> >   - failed_writes -- can happen when memory is too low
> >   - invalid_io   -- non-page-aligned I/O requests
> >   - notify_free  -- number of swap slot free notifications
> >   - memory_used -- zs pool zs_get_total_size_bytes()
> > 
> > Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> > ---
> >  drivers/block/zram/zram_drv.c | 167 ++++++++++++------------------------------
> >  drivers/block/zram/zram_drv.h |  17 ++---
> >  2 files changed, 54 insertions(+), 130 deletions(-)
> > 
> > diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> > index 2a7682c..8bddaff 100644
> > --- a/drivers/block/zram/zram_drv.c
> > +++ b/drivers/block/zram/zram_drv.c
> > @@ -42,6 +42,17 @@ static struct zram *zram_devices;
> >  /* Module params (documentation at end) */
> >  static unsigned int num_devices = 1;
> >  
> > +#define ZRAM_ATTR_RO(name)						\
> > +static ssize_t zram_attr_##name##_show(struct device *d,		\
> > +				struct device_attribute *attr, char *b)	\
> > +{									\
> > +	struct zram *zram = dev_to_zram(d);				\
> > +	return sprintf(b, "%llu\n",					\
> > +		(u64)atomic64_read(&zram->stats.name));			\
> > +}									\
> > +static struct device_attribute dev_attr_##name =			\
> > +	__ATTR(name, S_IRUGO, zram_attr_##name##_show, NULL);
> > +
> >  static inline int init_done(struct zram *zram)
> >  {
> >  	return zram->meta != NULL;
> > @@ -52,97 +63,36 @@ static inline struct zram *dev_to_zram(struct device *dev)
> >  	return (struct zram *)dev_to_disk(dev)->private_data;
> >  }
> >  
> > -static ssize_t disksize_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n", zram->disksize);
> > -}
> > -
> > -static ssize_t initstate_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%u\n", init_done(zram));
> > -}
> > -
> > -static ssize_t num_reads_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.num_reads));
> > -}
> > -
> > -static ssize_t num_writes_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.num_writes));
> > -}
> > -
> > -static ssize_t invalid_io_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.invalid_io));
> > -}
> > -
> > -static ssize_t notify_free_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.notify_free));
> > -}
> > -
> > -static ssize_t zero_pages_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%u\n", atomic_read(&zram->stats.pages_zero));
> > -}
> > -
> > -static ssize_t orig_data_size_show(struct device *dev,
> > +static ssize_t memory_used_show(struct device *dev,
> >  		struct device_attribute *attr, char *buf)
> >  {
> > +	u64 val = 0;
> >  	struct zram *zram = dev_to_zram(dev);
> > +	struct zram_meta *meta = zram->meta;
> >  
> > -	return sprintf(buf, "%llu\n",
> > -		(u64)(atomic_read(&zram->stats.pages_stored)) << PAGE_SHIFT);
> > +	down_read(&zram->init_lock);
> > +	if (init_done(zram))
> > +		val = zs_get_total_size_bytes(meta->mem_pool);
> > +	up_read(&zram->init_lock);
> > +	return sprintf(buf, "%llu\n", val);
> >  }
> >  
> > -static ssize_t compr_data_size_show(struct device *dev,
> > +static ssize_t disksize_show(struct device *dev,
> >  		struct device_attribute *attr, char *buf)
> >  {
> >  	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.compr_size));
> > +	return sprintf(buf, "%llu\n", zram->disksize);
> >  }
> >  
> > -static ssize_t mem_used_total_show(struct device *dev,
> > +static ssize_t initstate_show(struct device *dev,
> >  		struct device_attribute *attr, char *buf)
> >  {
> > -	u64 val = 0;
> > +	u32 val = 0;
> >  	struct zram *zram = dev_to_zram(dev);
> > -	struct zram_meta *meta = zram->meta;
> > -
> >  	down_read(&zram->init_lock);
> > -	if (init_done(zram))
> > -		val = zs_get_total_size_bytes(meta->mem_pool);
> > +	val = init_done(zram);
> >  	up_read(&zram->init_lock);
> > -
> > -	return sprintf(buf, "%llu\n", val);
> > +	return sprintf(buf, "%u\n", val);
> >  }
> >  
> >  /* flag operations needs meta->tb_lock */
> > @@ -293,7 +243,6 @@ static void zram_free_page(struct zram *zram, size_t index)
> >  {
> >  	struct zram_meta *meta = zram->meta;
> >  	unsigned long handle = meta->table[index].handle;
> > -	u16 size = meta->table[index].size;
> >  
> >  	if (unlikely(!handle)) {
> >  		/*
> > @@ -302,21 +251,15 @@ static void zram_free_page(struct zram *zram, size_t index)
> >  		 */
> >  		if (zram_test_flag(meta, index, ZRAM_ZERO)) {
> >  			zram_clear_flag(meta, index, ZRAM_ZERO);
> > -			atomic_dec(&zram->stats.pages_zero);
> > +			atomic64_dec(&zram->stats.pages_zero);
> >  		}
> >  		return;
> >  	}
> >  
> > -	if (unlikely(size > max_zpage_size))
> > -		atomic_dec(&zram->stats.bad_compress);
> > -
> >  	zs_free(meta->mem_pool, handle);
> >  
> > -	if (size <= PAGE_SIZE / 2)
> > -		atomic_dec(&zram->stats.good_compress);
> > -
> > -	atomic64_sub(meta->table[index].size, &zram->stats.compr_size);
> > -	atomic_dec(&zram->stats.pages_stored);
> > +	atomic64_sub(meta->table[index].size, &zram->stats.compressed_size);
> > +	atomic64_dec(&zram->stats.pages_stored);
> >  
> >  	meta->table[index].handle = 0;
> >  	meta->table[index].size = 0;
> > @@ -362,7 +305,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
> >  static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
> >  			  u32 index, int offset, struct bio *bio)
> >  {
> > -	int ret;
> > +	int ret = -EINVAL;
> >  	struct page *page;
> >  	unsigned char *user_mem, *uncmem = NULL;
> >  	struct zram_meta *meta = zram->meta;
> > @@ -406,6 +349,8 @@ out_cleanup:
> >  	kunmap_atomic(user_mem);
> >  	if (is_partial_io(bvec))
> >  		kfree(uncmem);
> > +	if (ret)
> > +		atomic64_inc(&zram->stats.failed_reads);
> >  	return ret;
> >  }
> >  
> > @@ -459,7 +404,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
> >  		zram_set_flag(meta, index, ZRAM_ZERO);
> >  		write_unlock(&zram->meta->tb_lock);
> >  
> > -		atomic_inc(&zram->stats.pages_zero);
> > +		atomic64_inc(&zram->stats.pages_zero);
> >  		ret = 0;
> >  		goto out;
> >  	}
> > @@ -478,7 +423,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
> >  	}
> >  
> >  	if (unlikely(clen > max_zpage_size)) {
> > -		atomic_inc(&zram->stats.bad_compress);
> >  		clen = PAGE_SIZE;
> >  		src = NULL;
> >  		if (is_partial_io(bvec))
> > @@ -516,11 +460,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
> >  	write_unlock(&zram->meta->tb_lock);
> >  
> >  	/* Update stats */
> > -	atomic64_add(clen, &zram->stats.compr_size);
> > -	atomic_inc(&zram->stats.pages_stored);
> > -	if (clen <= PAGE_SIZE / 2)
> > -		atomic_inc(&zram->stats.good_compress);
> > -
> > +	atomic64_add(clen, &zram->stats.compressed_size);
> > +	atomic64_inc(&zram->stats.pages_stored);
> >  out:
> >  	if (locked)
> >  		mutex_unlock(&meta->buffer_lock);
> > @@ -586,23 +527,8 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
> >  
> >  static void zram_init_device(struct zram *zram, struct zram_meta *meta)
> >  {
> > -	if (zram->disksize > 2 * (totalram_pages << PAGE_SHIFT)) {
> > -		pr_info(
> > -		"There is little point creating a zram of greater than "
> > -		"twice the size of memory since we expect a 2:1 compression "
> > -		"ratio. Note that zram uses about 0.1%% of the size of "
> > -		"the disk when not in use so a huge zram is "
> > -		"wasteful.\n"
> > -		"\tMemory Size: %lu kB\n"
> > -		"\tSize you selected: %llu kB\n"
> > -		"Continuing anyway ...\n",
> > -		(totalram_pages << PAGE_SHIFT) >> 10, zram->disksize >> 10
> > -		);
> > -	}
> > -
> >  	/* zram devices sort of resembles non-rotational disks */
> >  	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
> > -
> >  	zram->meta = meta;
> >  	pr_debug("Initialization done!\n");
> >  }
> > @@ -774,14 +700,15 @@ static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR,
> >  		disksize_show, disksize_store);
> >  static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
> >  static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
> > -static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL);
> > -static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL);
> > -static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL);
> > -static DEVICE_ATTR(notify_free, S_IRUGO, notify_free_show, NULL);
> > -static DEVICE_ATTR(zero_pages, S_IRUGO, zero_pages_show, NULL);
> > -static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL);
> > -static DEVICE_ATTR(compr_data_size, S_IRUGO, compr_data_size_show, NULL);
> > -static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL);
> > +static DEVICE_ATTR(memory_used, S_IRUGO, memory_used_show, NULL);
> > +
> > +ZRAM_ATTR_RO(num_reads);
> > +ZRAM_ATTR_RO(num_writes);
> > +ZRAM_ATTR_RO(pages_stored);
> > +ZRAM_ATTR_RO(invalid_io);
> > +ZRAM_ATTR_RO(notify_free);
> > +ZRAM_ATTR_RO(pages_zero);
> > +ZRAM_ATTR_RO(compressed_size);
> >  
> >  static struct attribute *zram_disk_attrs[] = {
> >  	&dev_attr_disksize.attr,
> > @@ -789,12 +716,12 @@ static struct attribute *zram_disk_attrs[] = {
> >  	&dev_attr_reset.attr,
> >  	&dev_attr_num_reads.attr,
> >  	&dev_attr_num_writes.attr,
> > +	&dev_attr_pages_stored.attr,
> >  	&dev_attr_invalid_io.attr,
> >  	&dev_attr_notify_free.attr,
> > -	&dev_attr_zero_pages.attr,
> > -	&dev_attr_orig_data_size.attr,
> > -	&dev_attr_compr_data_size.attr,
> > -	&dev_attr_mem_used_total.attr,
> > +	&dev_attr_pages_zero.attr,
> > +	&dev_attr_compressed_size.attr,
> > +	&dev_attr_memory_used.attr,
> >  	NULL,
> >  };
> >  
> > diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
> > index e81e9cd..277023d 100644
> > --- a/drivers/block/zram/zram_drv.h
> > +++ b/drivers/block/zram/zram_drv.h
> > @@ -64,22 +64,19 @@ enum zram_pageflags {
> >  struct table {
> >  	unsigned long handle;
> >  	u16 size;	/* object size (excluding header) */
> > -	u8 count;	/* object ref count (not yet used) */
> > -	u8 flags;
> > +	u16 flags;
> >  } __aligned(4);
> >  
> >  struct zram_stats {
> > -	atomic64_t compr_size;	/* compressed size of pages stored */
> > -	atomic64_t num_reads;	/* failed + successful */
> > -	atomic64_t num_writes;	/* --do-- */
> > -	atomic64_t failed_reads;	/* should NEVER! happen */
> > +	atomic64_t num_writes;	/* number of writes */
> > +	atomic64_t num_reads;	/* number of reads */
> > +	atomic64_t pages_stored;	/* no. of pages currently stored */
> > +	atomic64_t compressed_size;	/* compressed size of pages stored */
> > +	atomic64_t pages_zero;		/* no. of zero filled pages */
> > +	atomic64_t failed_reads;	/* no. of failed reads */
> >  	atomic64_t failed_writes;	/* can happen when memory is too low */
> >  	atomic64_t invalid_io;	/* non-page-aligned I/O requests */
> >  	atomic64_t notify_free;	/* no. of swap slot free notifications */
> > -	atomic_t pages_zero;		/* no. of zero filled pages */
> > -	atomic_t pages_stored;	/* no. of pages currently stored */
> > -	atomic_t good_compress;	/* % of pages with compression ratio<=50% */
> > -	atomic_t bad_compress;	/* % of pages with compression ratio>=75% */
> >  };
> >  
> >  struct zram_meta {
> > 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 2/3] zram: do not pass rw argument to __zram_make_request()
  2014-01-14 11:02   ` Jerome Marchand
@ 2014-01-14 11:13     ` Sergey Senozhatsky
  2014-01-14 12:27       ` Jerome Marchand
  2014-01-14 11:27     ` [PATCHv2 " Sergey Senozhatsky
  1 sibling, 1 reply; 24+ messages in thread
From: Sergey Senozhatsky @ 2014-01-14 11:13 UTC (permalink / raw)
  To: Jerome Marchand; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

On (01/14/14 12:02), Jerome Marchand wrote:
> >  static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index,
> > -			int offset, struct bio *bio, int rw)
> > +			int offset, struct bio *bio)
> >  {
> >  	int ret;
> > +	int rw = bio_data_dir(bio);
> >  
> > -	if (rw == READ)
> > +	if (rw == READA)
> > +		rw = READ;
> 
> This could never happen: bio_data_dir() can only return READ or WRITE.
> 

thanks. my bad. will replace with bio_rw().

	-ss

> Jerome
> 
> > +
> > +	if (rw == READ) {
> > +		atomic64_inc(&zram->stats.num_reads);
> >  		ret = zram_bvec_read(zram, bvec, index, offset, bio);
> > -	else
> > +	} else {
> > +		atomic64_inc(&zram->stats.num_writes);
> >  		ret = zram_bvec_write(zram, bvec, index, offset);
> > +	}
> >  
> >  	return ret;
> >  }
> > @@ -670,22 +677,13 @@ out:
> >  	return ret;
> >  }
> >  
> > -static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
> > +static void __zram_make_request(struct zram *zram, struct bio *bio)
> >  {
> >  	int offset;
> >  	u32 index;
> >  	struct bio_vec bvec;
> >  	struct bvec_iter iter;
> >  
> > -	switch (rw) {
> > -	case READ:
> > -		atomic64_inc(&zram->stats.num_reads);
> > -		break;
> > -	case WRITE:
> > -		atomic64_inc(&zram->stats.num_writes);
> > -		break;
> > -	}
> > -
> >  	index = bio->bi_iter.bi_sector >> SECTORS_PER_PAGE_SHIFT;
> >  	offset = (bio->bi_iter.bi_sector &
> >  		  (SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT;
> > @@ -704,16 +702,15 @@ static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
> >  			bv.bv_len = max_transfer_size;
> >  			bv.bv_offset = bvec.bv_offset;
> >  
> > -			if (zram_bvec_rw(zram, &bv, index, offset, bio, rw) < 0)
> > +			if (zram_bvec_rw(zram, &bv, index, offset, bio) < 0)
> >  				goto out;
> >  
> >  			bv.bv_len = bvec.bv_len - max_transfer_size;
> >  			bv.bv_offset += max_transfer_size;
> > -			if (zram_bvec_rw(zram, &bv, index+1, 0, bio, rw) < 0)
> > +			if (zram_bvec_rw(zram, &bv, index + 1, 0, bio) < 0)
> >  				goto out;
> >  		} else
> > -			if (zram_bvec_rw(zram, &bvec, index, offset, bio, rw)
> > -			    < 0)
> > +			if (zram_bvec_rw(zram, &bvec, index, offset, bio) < 0)
> >  				goto out;
> >  
> >  		update_position(&index, &offset, &bvec);
> > @@ -743,7 +740,7 @@ static void zram_make_request(struct request_queue *queue, struct bio *bio)
> >  		goto error;
> >  	}
> >  
> > -	__zram_make_request(zram, bio, bio_data_dir(bio));
> > +	__zram_make_request(zram, bio);
> >  	up_read(&zram->init_lock);
> >  
> >  	return;
> > 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv2 2/3] zram: do not pass rw argument to __zram_make_request()
  2014-01-14 11:02   ` Jerome Marchand
  2014-01-14 11:13     ` Sergey Senozhatsky
@ 2014-01-14 11:27     ` Sergey Senozhatsky
  2014-01-15  2:10       ` Minchan Kim
  1 sibling, 1 reply; 24+ messages in thread
From: Sergey Senozhatsky @ 2014-01-14 11:27 UTC (permalink / raw)
  To: Jerome Marchand; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

Do not pass rw argument down the __zram_make_request() -> zram_bvec_rw()
chain, decode it in zram_bvec_rw() instead. Besides, this is the place
where we distinguish READ (+READ AHEAD) and WRITE bio data directions, so
account zram RW stats here, instead of __zram_make_request(). This also
allows to account a real number of zram READ/WRITE operations, not just
requests (single RW request may cause a number of zram RW ops with separate
locking, compression/decompression, etc).

v2: use bio_rw() instead of bio_data_dir(). noted by Jerome Marchand.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
 drivers/block/zram/zram_drv.c | 33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index c323e05..2a7682c 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -533,14 +533,21 @@ out:
 }
 
 static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index,
-			int offset, struct bio *bio, int rw)
+			int offset, struct bio *bio)
 {
 	int ret;
+	int rw = bio_rw(bio);
 
-	if (rw == READ)
+	if (rw == READA)
+		rw = READ;
+
+	if (rw == READ) {
+		atomic64_inc(&zram->stats.num_reads);
 		ret = zram_bvec_read(zram, bvec, index, offset, bio);
-	else
+	} else {
+		atomic64_inc(&zram->stats.num_writes);
 		ret = zram_bvec_write(zram, bvec, index, offset);
+	}
 
 	return ret;
 }
@@ -670,22 +677,13 @@ out:
 	return ret;
 }
 
-static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
+static void __zram_make_request(struct zram *zram, struct bio *bio)
 {
 	int offset;
 	u32 index;
 	struct bio_vec bvec;
 	struct bvec_iter iter;
 
-	switch (rw) {
-	case READ:
-		atomic64_inc(&zram->stats.num_reads);
-		break;
-	case WRITE:
-		atomic64_inc(&zram->stats.num_writes);
-		break;
-	}
-
 	index = bio->bi_iter.bi_sector >> SECTORS_PER_PAGE_SHIFT;
 	offset = (bio->bi_iter.bi_sector &
 		  (SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT;
@@ -704,16 +702,15 @@ static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
 			bv.bv_len = max_transfer_size;
 			bv.bv_offset = bvec.bv_offset;
 
-			if (zram_bvec_rw(zram, &bv, index, offset, bio, rw) < 0)
+			if (zram_bvec_rw(zram, &bv, index, offset, bio) < 0)
 				goto out;
 
 			bv.bv_len = bvec.bv_len - max_transfer_size;
 			bv.bv_offset += max_transfer_size;
-			if (zram_bvec_rw(zram, &bv, index+1, 0, bio, rw) < 0)
+			if (zram_bvec_rw(zram, &bv, index + 1, 0, bio) < 0)
 				goto out;
 		} else
-			if (zram_bvec_rw(zram, &bvec, index, offset, bio, rw)
-			    < 0)
+			if (zram_bvec_rw(zram, &bvec, index, offset, bio) < 0)
 				goto out;
 
 		update_position(&index, &offset, &bvec);
@@ -743,7 +740,7 @@ static void zram_make_request(struct request_queue *queue, struct bio *bio)
 		goto error;
 	}
 
-	__zram_make_request(zram, bio, bio_data_dir(bio));
+	__zram_make_request(zram, bio);
 	up_read(&zram->init_lock);
 
 	return;


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] zram: rework reported to end-user zram statistics
  2014-01-14 10:57     ` Sergey Senozhatsky
@ 2014-01-14 12:15       ` Jerome Marchand
  2014-01-14 12:30         ` Sergey Senozhatsky
  0 siblings, 1 reply; 24+ messages in thread
From: Jerome Marchand @ 2014-01-14 12:15 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

On 01/14/2014 11:57 AM, Sergey Senozhatsky wrote:
> 
> Hello Jerome,
> 
> On (01/14/14 11:38), Jerome Marchand wrote:
>> On 01/14/2014 10:37 AM, Sergey Senozhatsky wrote:
>>> 1) Introduce ZRAM_ATTR_RO macro to generate zram atomic64_t stats
>>> `show' functions and reduce code duplication.
>>>
>>> 2) Account and report back to user numbers of failed READ and WRITE
>>> operations.
>>>
>>> 3) Remove `good' and `bad' compressed sub-requests stats. RW request may
>>> cause a number of RW sub-requests. zram used to account `good' compressed
>>> sub-queries (with compressed size less than 50% of original size), `bad'
>>> compressed sub-queries (with compressed size greater that 75% of original
>>> size), leaving sub-requests with compression size between 50% and 75% of
>>> original size not accounted and not reported.
>>
>> That's weird: good/bad_compress are accounted, but it seems to me that
>> they are to never used in any way. If so, there is indeed no reason to
>> keep them.
>>
>>
>>> Account each sub-request
>>> compression size so we can calculate real device compression ratio.
>>
>> Your patch doesn't change the way pages_stored and compr[essed]_size
>> are accounted. What does your patch change that allow us to calculate
>> the "real" compression ratio?
> 
> we have compressed size, number of stored pages and reported by zs pool
> (as a zram memory_used attr) number of bytes used
> 
> u64 zs_get_total_size_bytes(struct zs_pool *pool)
> {
>         int i;
>         u64 npages = 0;
> 
>         for (i = 0; i < ZS_SIZE_CLASSES; i++)
>                 npages += pool->size_class[i].pages_allocated;
> 
>         return npages << PAGE_SHIFT;
> }
> 
> looks enough to calculate device overall data compression ratio.

Yes. But don't we have all that already without your patch applied?
What does this patch change?

> 
> 	-ss
> 
>>>
>>> 4) reported zram stats:
>>>   - num_writes  -- number of writes
>>>   - num_reads  -- number of reads
>>>   - pages_stored -- number of pages currently stored
>>>   - compressed_size -- compressed size of pages stored
>>
>> Wouldn't it be more practical to report the original and compressed
>> data sizes using the same units as it is currently done?
>>
> 
> sorry, not sure I understand.

Currently users have access to orig_data_size and compr_data_size,
both in bytes. With your patch, they have access to pages_stored in
pages and compressed_size in bytes. I find the current set more
practical.

Jerome

> 
>> Jerome
>>
>>>   - pages_zero  -- number of zero filled pages
>>>   - failed_read -- number of failed reads
>>>   - failed_writes -- can happen when memory is too low
>>>   - invalid_io   -- non-page-aligned I/O requests
>>>   - notify_free  -- number of swap slot free notifications
>>>   - memory_used -- zs pool zs_get_total_size_bytes()
>>>
>>> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
>>> ---
>>>  drivers/block/zram/zram_drv.c | 167 ++++++++++++------------------------------
>>>  drivers/block/zram/zram_drv.h |  17 ++---
>>>  2 files changed, 54 insertions(+), 130 deletions(-)
>>>
>>> diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
>>> index 2a7682c..8bddaff 100644
>>> --- a/drivers/block/zram/zram_drv.c
>>> +++ b/drivers/block/zram/zram_drv.c
>>> @@ -42,6 +42,17 @@ static struct zram *zram_devices;
>>>  /* Module params (documentation at end) */
>>>  static unsigned int num_devices = 1;
>>>  
>>> +#define ZRAM_ATTR_RO(name)						\
>>> +static ssize_t zram_attr_##name##_show(struct device *d,		\
>>> +				struct device_attribute *attr, char *b)	\
>>> +{									\
>>> +	struct zram *zram = dev_to_zram(d);				\
>>> +	return sprintf(b, "%llu\n",					\
>>> +		(u64)atomic64_read(&zram->stats.name));			\
>>> +}									\
>>> +static struct device_attribute dev_attr_##name =			\
>>> +	__ATTR(name, S_IRUGO, zram_attr_##name##_show, NULL);
>>> +
>>>  static inline int init_done(struct zram *zram)
>>>  {
>>>  	return zram->meta != NULL;
>>> @@ -52,97 +63,36 @@ static inline struct zram *dev_to_zram(struct device *dev)
>>>  	return (struct zram *)dev_to_disk(dev)->private_data;
>>>  }
>>>  
>>> -static ssize_t disksize_show(struct device *dev,
>>> -		struct device_attribute *attr, char *buf)
>>> -{
>>> -	struct zram *zram = dev_to_zram(dev);
>>> -
>>> -	return sprintf(buf, "%llu\n", zram->disksize);
>>> -}
>>> -
>>> -static ssize_t initstate_show(struct device *dev,
>>> -		struct device_attribute *attr, char *buf)
>>> -{
>>> -	struct zram *zram = dev_to_zram(dev);
>>> -
>>> -	return sprintf(buf, "%u\n", init_done(zram));
>>> -}
>>> -
>>> -static ssize_t num_reads_show(struct device *dev,
>>> -		struct device_attribute *attr, char *buf)
>>> -{
>>> -	struct zram *zram = dev_to_zram(dev);
>>> -
>>> -	return sprintf(buf, "%llu\n",
>>> -			(u64)atomic64_read(&zram->stats.num_reads));
>>> -}
>>> -
>>> -static ssize_t num_writes_show(struct device *dev,
>>> -		struct device_attribute *attr, char *buf)
>>> -{
>>> -	struct zram *zram = dev_to_zram(dev);
>>> -
>>> -	return sprintf(buf, "%llu\n",
>>> -			(u64)atomic64_read(&zram->stats.num_writes));
>>> -}
>>> -
>>> -static ssize_t invalid_io_show(struct device *dev,
>>> -		struct device_attribute *attr, char *buf)
>>> -{
>>> -	struct zram *zram = dev_to_zram(dev);
>>> -
>>> -	return sprintf(buf, "%llu\n",
>>> -			(u64)atomic64_read(&zram->stats.invalid_io));
>>> -}
>>> -
>>> -static ssize_t notify_free_show(struct device *dev,
>>> -		struct device_attribute *attr, char *buf)
>>> -{
>>> -	struct zram *zram = dev_to_zram(dev);
>>> -
>>> -	return sprintf(buf, "%llu\n",
>>> -			(u64)atomic64_read(&zram->stats.notify_free));
>>> -}
>>> -
>>> -static ssize_t zero_pages_show(struct device *dev,
>>> -		struct device_attribute *attr, char *buf)
>>> -{
>>> -	struct zram *zram = dev_to_zram(dev);
>>> -
>>> -	return sprintf(buf, "%u\n", atomic_read(&zram->stats.pages_zero));
>>> -}
>>> -
>>> -static ssize_t orig_data_size_show(struct device *dev,
>>> +static ssize_t memory_used_show(struct device *dev,
>>>  		struct device_attribute *attr, char *buf)
>>>  {
>>> +	u64 val = 0;
>>>  	struct zram *zram = dev_to_zram(dev);
>>> +	struct zram_meta *meta = zram->meta;
>>>  
>>> -	return sprintf(buf, "%llu\n",
>>> -		(u64)(atomic_read(&zram->stats.pages_stored)) << PAGE_SHIFT);
>>> +	down_read(&zram->init_lock);
>>> +	if (init_done(zram))
>>> +		val = zs_get_total_size_bytes(meta->mem_pool);
>>> +	up_read(&zram->init_lock);
>>> +	return sprintf(buf, "%llu\n", val);
>>>  }
>>>  
>>> -static ssize_t compr_data_size_show(struct device *dev,
>>> +static ssize_t disksize_show(struct device *dev,
>>>  		struct device_attribute *attr, char *buf)
>>>  {
>>>  	struct zram *zram = dev_to_zram(dev);
>>> -
>>> -	return sprintf(buf, "%llu\n",
>>> -			(u64)atomic64_read(&zram->stats.compr_size));
>>> +	return sprintf(buf, "%llu\n", zram->disksize);
>>>  }
>>>  
>>> -static ssize_t mem_used_total_show(struct device *dev,
>>> +static ssize_t initstate_show(struct device *dev,
>>>  		struct device_attribute *attr, char *buf)
>>>  {
>>> -	u64 val = 0;
>>> +	u32 val = 0;
>>>  	struct zram *zram = dev_to_zram(dev);
>>> -	struct zram_meta *meta = zram->meta;
>>> -
>>>  	down_read(&zram->init_lock);
>>> -	if (init_done(zram))
>>> -		val = zs_get_total_size_bytes(meta->mem_pool);
>>> +	val = init_done(zram);
>>>  	up_read(&zram->init_lock);
>>> -
>>> -	return sprintf(buf, "%llu\n", val);
>>> +	return sprintf(buf, "%u\n", val);
>>>  }
>>>  
>>>  /* flag operations needs meta->tb_lock */
>>> @@ -293,7 +243,6 @@ static void zram_free_page(struct zram *zram, size_t index)
>>>  {
>>>  	struct zram_meta *meta = zram->meta;
>>>  	unsigned long handle = meta->table[index].handle;
>>> -	u16 size = meta->table[index].size;
>>>  
>>>  	if (unlikely(!handle)) {
>>>  		/*
>>> @@ -302,21 +251,15 @@ static void zram_free_page(struct zram *zram, size_t index)
>>>  		 */
>>>  		if (zram_test_flag(meta, index, ZRAM_ZERO)) {
>>>  			zram_clear_flag(meta, index, ZRAM_ZERO);
>>> -			atomic_dec(&zram->stats.pages_zero);
>>> +			atomic64_dec(&zram->stats.pages_zero);
>>>  		}
>>>  		return;
>>>  	}
>>>  
>>> -	if (unlikely(size > max_zpage_size))
>>> -		atomic_dec(&zram->stats.bad_compress);
>>> -
>>>  	zs_free(meta->mem_pool, handle);
>>>  
>>> -	if (size <= PAGE_SIZE / 2)
>>> -		atomic_dec(&zram->stats.good_compress);
>>> -
>>> -	atomic64_sub(meta->table[index].size, &zram->stats.compr_size);
>>> -	atomic_dec(&zram->stats.pages_stored);
>>> +	atomic64_sub(meta->table[index].size, &zram->stats.compressed_size);
>>> +	atomic64_dec(&zram->stats.pages_stored);
>>>  
>>>  	meta->table[index].handle = 0;
>>>  	meta->table[index].size = 0;
>>> @@ -362,7 +305,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
>>>  static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
>>>  			  u32 index, int offset, struct bio *bio)
>>>  {
>>> -	int ret;
>>> +	int ret = -EINVAL;
>>>  	struct page *page;
>>>  	unsigned char *user_mem, *uncmem = NULL;
>>>  	struct zram_meta *meta = zram->meta;
>>> @@ -406,6 +349,8 @@ out_cleanup:
>>>  	kunmap_atomic(user_mem);
>>>  	if (is_partial_io(bvec))
>>>  		kfree(uncmem);
>>> +	if (ret)
>>> +		atomic64_inc(&zram->stats.failed_reads);
>>>  	return ret;
>>>  }
>>>  
>>> @@ -459,7 +404,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
>>>  		zram_set_flag(meta, index, ZRAM_ZERO);
>>>  		write_unlock(&zram->meta->tb_lock);
>>>  
>>> -		atomic_inc(&zram->stats.pages_zero);
>>> +		atomic64_inc(&zram->stats.pages_zero);
>>>  		ret = 0;
>>>  		goto out;
>>>  	}
>>> @@ -478,7 +423,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
>>>  	}
>>>  
>>>  	if (unlikely(clen > max_zpage_size)) {
>>> -		atomic_inc(&zram->stats.bad_compress);
>>>  		clen = PAGE_SIZE;
>>>  		src = NULL;
>>>  		if (is_partial_io(bvec))
>>> @@ -516,11 +460,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
>>>  	write_unlock(&zram->meta->tb_lock);
>>>  
>>>  	/* Update stats */
>>> -	atomic64_add(clen, &zram->stats.compr_size);
>>> -	atomic_inc(&zram->stats.pages_stored);
>>> -	if (clen <= PAGE_SIZE / 2)
>>> -		atomic_inc(&zram->stats.good_compress);
>>> -
>>> +	atomic64_add(clen, &zram->stats.compressed_size);
>>> +	atomic64_inc(&zram->stats.pages_stored);
>>>  out:
>>>  	if (locked)
>>>  		mutex_unlock(&meta->buffer_lock);
>>> @@ -586,23 +527,8 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
>>>  
>>>  static void zram_init_device(struct zram *zram, struct zram_meta *meta)
>>>  {
>>> -	if (zram->disksize > 2 * (totalram_pages << PAGE_SHIFT)) {
>>> -		pr_info(
>>> -		"There is little point creating a zram of greater than "
>>> -		"twice the size of memory since we expect a 2:1 compression "
>>> -		"ratio. Note that zram uses about 0.1%% of the size of "
>>> -		"the disk when not in use so a huge zram is "
>>> -		"wasteful.\n"
>>> -		"\tMemory Size: %lu kB\n"
>>> -		"\tSize you selected: %llu kB\n"
>>> -		"Continuing anyway ...\n",
>>> -		(totalram_pages << PAGE_SHIFT) >> 10, zram->disksize >> 10
>>> -		);
>>> -	}
>>> -
>>>  	/* zram devices sort of resembles non-rotational disks */
>>>  	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
>>> -
>>>  	zram->meta = meta;
>>>  	pr_debug("Initialization done!\n");
>>>  }
>>> @@ -774,14 +700,15 @@ static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR,
>>>  		disksize_show, disksize_store);
>>>  static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
>>>  static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
>>> -static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL);
>>> -static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL);
>>> -static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL);
>>> -static DEVICE_ATTR(notify_free, S_IRUGO, notify_free_show, NULL);
>>> -static DEVICE_ATTR(zero_pages, S_IRUGO, zero_pages_show, NULL);
>>> -static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL);
>>> -static DEVICE_ATTR(compr_data_size, S_IRUGO, compr_data_size_show, NULL);
>>> -static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL);
>>> +static DEVICE_ATTR(memory_used, S_IRUGO, memory_used_show, NULL);
>>> +
>>> +ZRAM_ATTR_RO(num_reads);
>>> +ZRAM_ATTR_RO(num_writes);
>>> +ZRAM_ATTR_RO(pages_stored);
>>> +ZRAM_ATTR_RO(invalid_io);
>>> +ZRAM_ATTR_RO(notify_free);
>>> +ZRAM_ATTR_RO(pages_zero);
>>> +ZRAM_ATTR_RO(compressed_size);
>>>  
>>>  static struct attribute *zram_disk_attrs[] = {
>>>  	&dev_attr_disksize.attr,
>>> @@ -789,12 +716,12 @@ static struct attribute *zram_disk_attrs[] = {
>>>  	&dev_attr_reset.attr,
>>>  	&dev_attr_num_reads.attr,
>>>  	&dev_attr_num_writes.attr,
>>> +	&dev_attr_pages_stored.attr,
>>>  	&dev_attr_invalid_io.attr,
>>>  	&dev_attr_notify_free.attr,
>>> -	&dev_attr_zero_pages.attr,
>>> -	&dev_attr_orig_data_size.attr,
>>> -	&dev_attr_compr_data_size.attr,
>>> -	&dev_attr_mem_used_total.attr,
>>> +	&dev_attr_pages_zero.attr,
>>> +	&dev_attr_compressed_size.attr,
>>> +	&dev_attr_memory_used.attr,
>>>  	NULL,
>>>  };
>>>  
>>> diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
>>> index e81e9cd..277023d 100644
>>> --- a/drivers/block/zram/zram_drv.h
>>> +++ b/drivers/block/zram/zram_drv.h
>>> @@ -64,22 +64,19 @@ enum zram_pageflags {
>>>  struct table {
>>>  	unsigned long handle;
>>>  	u16 size;	/* object size (excluding header) */
>>> -	u8 count;	/* object ref count (not yet used) */
>>> -	u8 flags;
>>> +	u16 flags;
>>>  } __aligned(4);
>>>  
>>>  struct zram_stats {
>>> -	atomic64_t compr_size;	/* compressed size of pages stored */
>>> -	atomic64_t num_reads;	/* failed + successful */
>>> -	atomic64_t num_writes;	/* --do-- */
>>> -	atomic64_t failed_reads;	/* should NEVER! happen */
>>> +	atomic64_t num_writes;	/* number of writes */
>>> +	atomic64_t num_reads;	/* number of reads */
>>> +	atomic64_t pages_stored;	/* no. of pages currently stored */
>>> +	atomic64_t compressed_size;	/* compressed size of pages stored */
>>> +	atomic64_t pages_zero;		/* no. of zero filled pages */
>>> +	atomic64_t failed_reads;	/* no. of failed reads */
>>>  	atomic64_t failed_writes;	/* can happen when memory is too low */
>>>  	atomic64_t invalid_io;	/* non-page-aligned I/O requests */
>>>  	atomic64_t notify_free;	/* no. of swap slot free notifications */
>>> -	atomic_t pages_zero;		/* no. of zero filled pages */
>>> -	atomic_t pages_stored;	/* no. of pages currently stored */
>>> -	atomic_t good_compress;	/* % of pages with compression ratio<=50% */
>>> -	atomic_t bad_compress;	/* % of pages with compression ratio>=75% */
>>>  };
>>>  
>>>  struct zram_meta {
>>>
>>


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 2/3] zram: do not pass rw argument to __zram_make_request()
  2014-01-14 11:13     ` Sergey Senozhatsky
@ 2014-01-14 12:27       ` Jerome Marchand
  0 siblings, 0 replies; 24+ messages in thread
From: Jerome Marchand @ 2014-01-14 12:27 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

On 01/14/2014 12:13 PM, Sergey Senozhatsky wrote:
> On (01/14/14 12:02), Jerome Marchand wrote:
>>>  static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index,
>>> -			int offset, struct bio *bio, int rw)
>>> +			int offset, struct bio *bio)
>>>  {
>>>  	int ret;
>>> +	int rw = bio_data_dir(bio);
>>>  
>>> -	if (rw == READ)
>>> +	if (rw == READA)
>>> +		rw = READ;
>>
>> This could never happen: bio_data_dir() can only return READ or WRITE.
>>
> 
> thanks. my bad. will replace with bio_rw().

There is no point in doing that. In read-ahead case, bio_data_dir()
already returns READ. Since we don't do anything special in read-ahead
case, just keep bio_data_dir() and drop this test.

> 
> 	-ss
> 
>> Jerome
>>
>>> +
>>> +	if (rw == READ) {
>>> +		atomic64_inc(&zram->stats.num_reads);
>>>  		ret = zram_bvec_read(zram, bvec, index, offset, bio);
>>> -	else
>>> +	} else {
>>> +		atomic64_inc(&zram->stats.num_writes);
>>>  		ret = zram_bvec_write(zram, bvec, index, offset);
>>> +	}
>>>  
>>>  	return ret;
>>>  }
>>> @@ -670,22 +677,13 @@ out:
>>>  	return ret;
>>>  }
>>>  
>>> -static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
>>> +static void __zram_make_request(struct zram *zram, struct bio *bio)
>>>  {
>>>  	int offset;
>>>  	u32 index;
>>>  	struct bio_vec bvec;
>>>  	struct bvec_iter iter;
>>>  
>>> -	switch (rw) {
>>> -	case READ:
>>> -		atomic64_inc(&zram->stats.num_reads);
>>> -		break;
>>> -	case WRITE:
>>> -		atomic64_inc(&zram->stats.num_writes);
>>> -		break;
>>> -	}
>>> -
>>>  	index = bio->bi_iter.bi_sector >> SECTORS_PER_PAGE_SHIFT;
>>>  	offset = (bio->bi_iter.bi_sector &
>>>  		  (SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT;
>>> @@ -704,16 +702,15 @@ static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
>>>  			bv.bv_len = max_transfer_size;
>>>  			bv.bv_offset = bvec.bv_offset;
>>>  
>>> -			if (zram_bvec_rw(zram, &bv, index, offset, bio, rw) < 0)
>>> +			if (zram_bvec_rw(zram, &bv, index, offset, bio) < 0)
>>>  				goto out;
>>>  
>>>  			bv.bv_len = bvec.bv_len - max_transfer_size;
>>>  			bv.bv_offset += max_transfer_size;
>>> -			if (zram_bvec_rw(zram, &bv, index+1, 0, bio, rw) < 0)
>>> +			if (zram_bvec_rw(zram, &bv, index + 1, 0, bio) < 0)
>>>  				goto out;
>>>  		} else
>>> -			if (zram_bvec_rw(zram, &bvec, index, offset, bio, rw)
>>> -			    < 0)
>>> +			if (zram_bvec_rw(zram, &bvec, index, offset, bio) < 0)
>>>  				goto out;
>>>  
>>>  		update_position(&index, &offset, &bvec);
>>> @@ -743,7 +740,7 @@ static void zram_make_request(struct request_queue *queue, struct bio *bio)
>>>  		goto error;
>>>  	}
>>>  
>>> -	__zram_make_request(zram, bio, bio_data_dir(bio));
>>> +	__zram_make_request(zram, bio);
>>>  	up_read(&zram->init_lock);
>>>  
>>>  	return;
>>>
>>


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] zram: rework reported to end-user zram statistics
  2014-01-14 12:15       ` Jerome Marchand
@ 2014-01-14 12:30         ` Sergey Senozhatsky
  0 siblings, 0 replies; 24+ messages in thread
From: Sergey Senozhatsky @ 2014-01-14 12:30 UTC (permalink / raw)
  To: Jerome Marchand; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

On (01/14/14 13:15), Jerome Marchand wrote:
> On 01/14/2014 11:57 AM, Sergey Senozhatsky wrote:
> > 
> > Hello Jerome,
> > 
> > On (01/14/14 11:38), Jerome Marchand wrote:
> >> On 01/14/2014 10:37 AM, Sergey Senozhatsky wrote:
> >>> 1) Introduce ZRAM_ATTR_RO macro to generate zram atomic64_t stats
> >>> `show' functions and reduce code duplication.
> >>>
> >>> 2) Account and report back to user numbers of failed READ and WRITE
> >>> operations.
> >>>
> >>> 3) Remove `good' and `bad' compressed sub-requests stats. RW request may
> >>> cause a number of RW sub-requests. zram used to account `good' compressed
> >>> sub-queries (with compressed size less than 50% of original size), `bad'
> >>> compressed sub-queries (with compressed size greater that 75% of original
> >>> size), leaving sub-requests with compression size between 50% and 75% of
> >>> original size not accounted and not reported.
> >>
> >> That's weird: good/bad_compress are accounted, but it seems to me that
> >> they are to never used in any way. If so, there is indeed no reason to
> >> keep them.
> >>
> >>
> >>> Account each sub-request
> >>> compression size so we can calculate real device compression ratio.
> >>
> >> Your patch doesn't change the way pages_stored and compr[essed]_size
> >> are accounted. What does your patch change that allow us to calculate
> >> the "real" compression ratio?
> > 
> > we have compressed size, number of stored pages and reported by zs pool
> > (as a zram memory_used attr) number of bytes used
> > 
> > u64 zs_get_total_size_bytes(struct zs_pool *pool)
> > {
> >         int i;
> >         u64 npages = 0;
> > 
> >         for (i = 0; i < ZS_SIZE_CLASSES; i++)
> >                 npages += pool->size_class[i].pages_allocated;
> > 
> >         return npages << PAGE_SHIFT;
> > }
> > 
> > looks enough to calculate device overall data compression ratio.
> 
> Yes. But don't we have all that already without your patch applied?
> What does this patch change?
> 
>

oh. yes, bad wording. the commit message must be "*zram accounts* each
sub-request compression size so we can calculate real device compression
ratio." instead of  "Account each sub-request compression size so we can
calculate real device compression ratio.". otherwise, there is a false
feeling that patch change/introduce this functionality. will re-write
that commit message. sorry.

the patch does not change a lot of things and may be considered mainly as
a clean up patch. it:
-- removes unused and misleading bad/good stats
-- makes some attrs names more readable e.g. mem_used_total to
memory_used, compr_data_size to compressed_size
-- accounts and reports numbers of failed RW requests
-- removes ATTR_show() code duplication using ZRAM_ATTR_RO macro

	-ss

> > 
> > 	-ss
> > 
> >>>
> >>> 4) reported zram stats:
> >>>   - num_writes  -- number of writes
> >>>   - num_reads  -- number of reads
> >>>   - pages_stored -- number of pages currently stored
> >>>   - compressed_size -- compressed size of pages stored
> >>
> >> Wouldn't it be more practical to report the original and compressed
> >> data sizes using the same units as it is currently done?
> >>
> > 
> > sorry, not sure I understand.
> 
> Currently users have access to orig_data_size and compr_data_size,
> both in bytes. With your patch, they have access to pages_stored in
> pages and compressed_size in bytes. I find the current set more
> practical.
> 
> Jerome
> 
> > 
> >> Jerome
> >>
> >>>   - pages_zero  -- number of zero filled pages
> >>>   - failed_read -- number of failed reads
> >>>   - failed_writes -- can happen when memory is too low
> >>>   - invalid_io   -- non-page-aligned I/O requests
> >>>   - notify_free  -- number of swap slot free notifications
> >>>   - memory_used -- zs pool zs_get_total_size_bytes()
> >>>
> >>> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> >>> ---
> >>>  drivers/block/zram/zram_drv.c | 167 ++++++++++++------------------------------
> >>>  drivers/block/zram/zram_drv.h |  17 ++---
> >>>  2 files changed, 54 insertions(+), 130 deletions(-)
> >>>
> >>> diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> >>> index 2a7682c..8bddaff 100644
> >>> --- a/drivers/block/zram/zram_drv.c
> >>> +++ b/drivers/block/zram/zram_drv.c
> >>> @@ -42,6 +42,17 @@ static struct zram *zram_devices;
> >>>  /* Module params (documentation at end) */
> >>>  static unsigned int num_devices = 1;
> >>>  
> >>> +#define ZRAM_ATTR_RO(name)						\
> >>> +static ssize_t zram_attr_##name##_show(struct device *d,		\
> >>> +				struct device_attribute *attr, char *b)	\
> >>> +{									\
> >>> +	struct zram *zram = dev_to_zram(d);				\
> >>> +	return sprintf(b, "%llu\n",					\
> >>> +		(u64)atomic64_read(&zram->stats.name));			\
> >>> +}									\
> >>> +static struct device_attribute dev_attr_##name =			\
> >>> +	__ATTR(name, S_IRUGO, zram_attr_##name##_show, NULL);
> >>> +
> >>>  static inline int init_done(struct zram *zram)
> >>>  {
> >>>  	return zram->meta != NULL;
> >>> @@ -52,97 +63,36 @@ static inline struct zram *dev_to_zram(struct device *dev)
> >>>  	return (struct zram *)dev_to_disk(dev)->private_data;
> >>>  }
> >>>  
> >>> -static ssize_t disksize_show(struct device *dev,
> >>> -		struct device_attribute *attr, char *buf)
> >>> -{
> >>> -	struct zram *zram = dev_to_zram(dev);
> >>> -
> >>> -	return sprintf(buf, "%llu\n", zram->disksize);
> >>> -}
> >>> -
> >>> -static ssize_t initstate_show(struct device *dev,
> >>> -		struct device_attribute *attr, char *buf)
> >>> -{
> >>> -	struct zram *zram = dev_to_zram(dev);
> >>> -
> >>> -	return sprintf(buf, "%u\n", init_done(zram));
> >>> -}
> >>> -
> >>> -static ssize_t num_reads_show(struct device *dev,
> >>> -		struct device_attribute *attr, char *buf)
> >>> -{
> >>> -	struct zram *zram = dev_to_zram(dev);
> >>> -
> >>> -	return sprintf(buf, "%llu\n",
> >>> -			(u64)atomic64_read(&zram->stats.num_reads));
> >>> -}
> >>> -
> >>> -static ssize_t num_writes_show(struct device *dev,
> >>> -		struct device_attribute *attr, char *buf)
> >>> -{
> >>> -	struct zram *zram = dev_to_zram(dev);
> >>> -
> >>> -	return sprintf(buf, "%llu\n",
> >>> -			(u64)atomic64_read(&zram->stats.num_writes));
> >>> -}
> >>> -
> >>> -static ssize_t invalid_io_show(struct device *dev,
> >>> -		struct device_attribute *attr, char *buf)
> >>> -{
> >>> -	struct zram *zram = dev_to_zram(dev);
> >>> -
> >>> -	return sprintf(buf, "%llu\n",
> >>> -			(u64)atomic64_read(&zram->stats.invalid_io));
> >>> -}
> >>> -
> >>> -static ssize_t notify_free_show(struct device *dev,
> >>> -		struct device_attribute *attr, char *buf)
> >>> -{
> >>> -	struct zram *zram = dev_to_zram(dev);
> >>> -
> >>> -	return sprintf(buf, "%llu\n",
> >>> -			(u64)atomic64_read(&zram->stats.notify_free));
> >>> -}
> >>> -
> >>> -static ssize_t zero_pages_show(struct device *dev,
> >>> -		struct device_attribute *attr, char *buf)
> >>> -{
> >>> -	struct zram *zram = dev_to_zram(dev);
> >>> -
> >>> -	return sprintf(buf, "%u\n", atomic_read(&zram->stats.pages_zero));
> >>> -}
> >>> -
> >>> -static ssize_t orig_data_size_show(struct device *dev,
> >>> +static ssize_t memory_used_show(struct device *dev,
> >>>  		struct device_attribute *attr, char *buf)
> >>>  {
> >>> +	u64 val = 0;
> >>>  	struct zram *zram = dev_to_zram(dev);
> >>> +	struct zram_meta *meta = zram->meta;
> >>>  
> >>> -	return sprintf(buf, "%llu\n",
> >>> -		(u64)(atomic_read(&zram->stats.pages_stored)) << PAGE_SHIFT);
> >>> +	down_read(&zram->init_lock);
> >>> +	if (init_done(zram))
> >>> +		val = zs_get_total_size_bytes(meta->mem_pool);
> >>> +	up_read(&zram->init_lock);
> >>> +	return sprintf(buf, "%llu\n", val);
> >>>  }
> >>>  
> >>> -static ssize_t compr_data_size_show(struct device *dev,
> >>> +static ssize_t disksize_show(struct device *dev,
> >>>  		struct device_attribute *attr, char *buf)
> >>>  {
> >>>  	struct zram *zram = dev_to_zram(dev);
> >>> -
> >>> -	return sprintf(buf, "%llu\n",
> >>> -			(u64)atomic64_read(&zram->stats.compr_size));
> >>> +	return sprintf(buf, "%llu\n", zram->disksize);
> >>>  }
> >>>  
> >>> -static ssize_t mem_used_total_show(struct device *dev,
> >>> +static ssize_t initstate_show(struct device *dev,
> >>>  		struct device_attribute *attr, char *buf)
> >>>  {
> >>> -	u64 val = 0;
> >>> +	u32 val = 0;
> >>>  	struct zram *zram = dev_to_zram(dev);
> >>> -	struct zram_meta *meta = zram->meta;
> >>> -
> >>>  	down_read(&zram->init_lock);
> >>> -	if (init_done(zram))
> >>> -		val = zs_get_total_size_bytes(meta->mem_pool);
> >>> +	val = init_done(zram);
> >>>  	up_read(&zram->init_lock);
> >>> -
> >>> -	return sprintf(buf, "%llu\n", val);
> >>> +	return sprintf(buf, "%u\n", val);
> >>>  }
> >>>  
> >>>  /* flag operations needs meta->tb_lock */
> >>> @@ -293,7 +243,6 @@ static void zram_free_page(struct zram *zram, size_t index)
> >>>  {
> >>>  	struct zram_meta *meta = zram->meta;
> >>>  	unsigned long handle = meta->table[index].handle;
> >>> -	u16 size = meta->table[index].size;
> >>>  
> >>>  	if (unlikely(!handle)) {
> >>>  		/*
> >>> @@ -302,21 +251,15 @@ static void zram_free_page(struct zram *zram, size_t index)
> >>>  		 */
> >>>  		if (zram_test_flag(meta, index, ZRAM_ZERO)) {
> >>>  			zram_clear_flag(meta, index, ZRAM_ZERO);
> >>> -			atomic_dec(&zram->stats.pages_zero);
> >>> +			atomic64_dec(&zram->stats.pages_zero);
> >>>  		}
> >>>  		return;
> >>>  	}
> >>>  
> >>> -	if (unlikely(size > max_zpage_size))
> >>> -		atomic_dec(&zram->stats.bad_compress);
> >>> -
> >>>  	zs_free(meta->mem_pool, handle);
> >>>  
> >>> -	if (size <= PAGE_SIZE / 2)
> >>> -		atomic_dec(&zram->stats.good_compress);
> >>> -
> >>> -	atomic64_sub(meta->table[index].size, &zram->stats.compr_size);
> >>> -	atomic_dec(&zram->stats.pages_stored);
> >>> +	atomic64_sub(meta->table[index].size, &zram->stats.compressed_size);
> >>> +	atomic64_dec(&zram->stats.pages_stored);
> >>>  
> >>>  	meta->table[index].handle = 0;
> >>>  	meta->table[index].size = 0;
> >>> @@ -362,7 +305,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
> >>>  static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
> >>>  			  u32 index, int offset, struct bio *bio)
> >>>  {
> >>> -	int ret;
> >>> +	int ret = -EINVAL;
> >>>  	struct page *page;
> >>>  	unsigned char *user_mem, *uncmem = NULL;
> >>>  	struct zram_meta *meta = zram->meta;
> >>> @@ -406,6 +349,8 @@ out_cleanup:
> >>>  	kunmap_atomic(user_mem);
> >>>  	if (is_partial_io(bvec))
> >>>  		kfree(uncmem);
> >>> +	if (ret)
> >>> +		atomic64_inc(&zram->stats.failed_reads);
> >>>  	return ret;
> >>>  }
> >>>  
> >>> @@ -459,7 +404,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
> >>>  		zram_set_flag(meta, index, ZRAM_ZERO);
> >>>  		write_unlock(&zram->meta->tb_lock);
> >>>  
> >>> -		atomic_inc(&zram->stats.pages_zero);
> >>> +		atomic64_inc(&zram->stats.pages_zero);
> >>>  		ret = 0;
> >>>  		goto out;
> >>>  	}
> >>> @@ -478,7 +423,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
> >>>  	}
> >>>  
> >>>  	if (unlikely(clen > max_zpage_size)) {
> >>> -		atomic_inc(&zram->stats.bad_compress);
> >>>  		clen = PAGE_SIZE;
> >>>  		src = NULL;
> >>>  		if (is_partial_io(bvec))
> >>> @@ -516,11 +460,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
> >>>  	write_unlock(&zram->meta->tb_lock);
> >>>  
> >>>  	/* Update stats */
> >>> -	atomic64_add(clen, &zram->stats.compr_size);
> >>> -	atomic_inc(&zram->stats.pages_stored);
> >>> -	if (clen <= PAGE_SIZE / 2)
> >>> -		atomic_inc(&zram->stats.good_compress);
> >>> -
> >>> +	atomic64_add(clen, &zram->stats.compressed_size);
> >>> +	atomic64_inc(&zram->stats.pages_stored);
> >>>  out:
> >>>  	if (locked)
> >>>  		mutex_unlock(&meta->buffer_lock);
> >>> @@ -586,23 +527,8 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
> >>>  
> >>>  static void zram_init_device(struct zram *zram, struct zram_meta *meta)
> >>>  {
> >>> -	if (zram->disksize > 2 * (totalram_pages << PAGE_SHIFT)) {
> >>> -		pr_info(
> >>> -		"There is little point creating a zram of greater than "
> >>> -		"twice the size of memory since we expect a 2:1 compression "
> >>> -		"ratio. Note that zram uses about 0.1%% of the size of "
> >>> -		"the disk when not in use so a huge zram is "
> >>> -		"wasteful.\n"
> >>> -		"\tMemory Size: %lu kB\n"
> >>> -		"\tSize you selected: %llu kB\n"
> >>> -		"Continuing anyway ...\n",
> >>> -		(totalram_pages << PAGE_SHIFT) >> 10, zram->disksize >> 10
> >>> -		);
> >>> -	}
> >>> -
> >>>  	/* zram devices sort of resembles non-rotational disks */
> >>>  	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
> >>> -
> >>>  	zram->meta = meta;
> >>>  	pr_debug("Initialization done!\n");
> >>>  }
> >>> @@ -774,14 +700,15 @@ static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR,
> >>>  		disksize_show, disksize_store);
> >>>  static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
> >>>  static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
> >>> -static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL);
> >>> -static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL);
> >>> -static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL);
> >>> -static DEVICE_ATTR(notify_free, S_IRUGO, notify_free_show, NULL);
> >>> -static DEVICE_ATTR(zero_pages, S_IRUGO, zero_pages_show, NULL);
> >>> -static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL);
> >>> -static DEVICE_ATTR(compr_data_size, S_IRUGO, compr_data_size_show, NULL);
> >>> -static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL);
> >>> +static DEVICE_ATTR(memory_used, S_IRUGO, memory_used_show, NULL);
> >>> +
> >>> +ZRAM_ATTR_RO(num_reads);
> >>> +ZRAM_ATTR_RO(num_writes);
> >>> +ZRAM_ATTR_RO(pages_stored);
> >>> +ZRAM_ATTR_RO(invalid_io);
> >>> +ZRAM_ATTR_RO(notify_free);
> >>> +ZRAM_ATTR_RO(pages_zero);
> >>> +ZRAM_ATTR_RO(compressed_size);
> >>>  
> >>>  static struct attribute *zram_disk_attrs[] = {
> >>>  	&dev_attr_disksize.attr,
> >>> @@ -789,12 +716,12 @@ static struct attribute *zram_disk_attrs[] = {
> >>>  	&dev_attr_reset.attr,
> >>>  	&dev_attr_num_reads.attr,
> >>>  	&dev_attr_num_writes.attr,
> >>> +	&dev_attr_pages_stored.attr,
> >>>  	&dev_attr_invalid_io.attr,
> >>>  	&dev_attr_notify_free.attr,
> >>> -	&dev_attr_zero_pages.attr,
> >>> -	&dev_attr_orig_data_size.attr,
> >>> -	&dev_attr_compr_data_size.attr,
> >>> -	&dev_attr_mem_used_total.attr,
> >>> +	&dev_attr_pages_zero.attr,
> >>> +	&dev_attr_compressed_size.attr,
> >>> +	&dev_attr_memory_used.attr,
> >>>  	NULL,
> >>>  };
> >>>  
> >>> diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
> >>> index e81e9cd..277023d 100644
> >>> --- a/drivers/block/zram/zram_drv.h
> >>> +++ b/drivers/block/zram/zram_drv.h
> >>> @@ -64,22 +64,19 @@ enum zram_pageflags {
> >>>  struct table {
> >>>  	unsigned long handle;
> >>>  	u16 size;	/* object size (excluding header) */
> >>> -	u8 count;	/* object ref count (not yet used) */
> >>> -	u8 flags;
> >>> +	u16 flags;
> >>>  } __aligned(4);
> >>>  
> >>>  struct zram_stats {
> >>> -	atomic64_t compr_size;	/* compressed size of pages stored */
> >>> -	atomic64_t num_reads;	/* failed + successful */
> >>> -	atomic64_t num_writes;	/* --do-- */
> >>> -	atomic64_t failed_reads;	/* should NEVER! happen */
> >>> +	atomic64_t num_writes;	/* number of writes */
> >>> +	atomic64_t num_reads;	/* number of reads */
> >>> +	atomic64_t pages_stored;	/* no. of pages currently stored */
> >>> +	atomic64_t compressed_size;	/* compressed size of pages stored */
> >>> +	atomic64_t pages_zero;		/* no. of zero filled pages */
> >>> +	atomic64_t failed_reads;	/* no. of failed reads */
> >>>  	atomic64_t failed_writes;	/* can happen when memory is too low */
> >>>  	atomic64_t invalid_io;	/* non-page-aligned I/O requests */
> >>>  	atomic64_t notify_free;	/* no. of swap slot free notifications */
> >>> -	atomic_t pages_zero;		/* no. of zero filled pages */
> >>> -	atomic_t pages_stored;	/* no. of pages currently stored */
> >>> -	atomic_t good_compress;	/* % of pages with compression ratio<=50% */
> >>> -	atomic_t bad_compress;	/* % of pages with compression ratio>=75% */
> >>>  };
> >>>  
> >>>  struct zram_meta {
> >>>
> >>
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] zram: rework reported to end-user zram statistics
  2014-01-14 11:10     ` Sergey Senozhatsky
@ 2014-01-14 13:43       ` Jerome Marchand
  2014-01-14 13:53         ` Sergey Senozhatsky
  0 siblings, 1 reply; 24+ messages in thread
From: Jerome Marchand @ 2014-01-14 13:43 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

On 01/14/2014 12:10 PM, Sergey Senozhatsky wrote:
> On (01/14/14 11:38), Jerome Marchand wrote:
>> On 01/14/2014 10:37 AM, Sergey Senozhatsky wrote:
>>> 1) Introduce ZRAM_ATTR_RO macro to generate zram atomic64_t stats
>>> `show' functions and reduce code duplication.
>>>
>>> 2) Account and report back to user numbers of failed READ and WRITE
>>> operations.
>>>
>>> 3) Remove `good' and `bad' compressed sub-requests stats. RW request may
>>> cause a number of RW sub-requests. zram used to account `good' compressed
>>> sub-queries (with compressed size less than 50% of original size), `bad'
>>> compressed sub-queries (with compressed size greater that 75% of original
>>> size), leaving sub-requests with compression size between 50% and 75% of
>>> original size not accounted and not reported.
>>
>> That's weird: good/bad_compress are accounted, but it seems to me that
>> they are to never used in any way. If so, there is indeed no reason to
>> keep them.
>>
>>
>>> Account each sub-request
>>> compression size so we can calculate real device compression ratio.
>>
>> Your patch doesn't change the way pages_stored and compr[essed]_size
>> are accounted. What does your patch change that allow us to calculate
>> the "real" compression ratio?
>>
>>>
>>> 4) reported zram stats:
>>>   - num_writes  -- number of writes
>>>   - num_reads  -- number of reads
>>>   - pages_stored -- number of pages currently stored
>>>   - compressed_size -- compressed size of pages stored
>>
>> Wouldn't it be more practical to report the original and compressed
>> data sizes using the same units as it is currently done?
>>
> 
> hm, do we really need pages_stored stats? what kind of unseful information it
> shows to end user?.. perhaps, it's better to replace it with accounted passed
> bvec->bv_len (as uncompressed_size).
> 

That's really going to complicates things. We would need to keep track
of which sectors of a particular page has been written to. It's much
easier to keep current page granularity and consider any partial I/O
as an whole page I/O.

> 	-ss
> 
>> Jerome
>>
>>>   - pages_zero  -- number of zero filled pages
>>>   - failed_read -- number of failed reads
>>>   - failed_writes -- can happen when memory is too low
>>>   - invalid_io   -- non-page-aligned I/O requests
>>>   - notify_free  -- number of swap slot free notifications
>>>   - memory_used -- zs pool zs_get_total_size_bytes()
>>>
>>> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] zram: rework reported to end-user zram statistics
  2014-01-14 13:43       ` Jerome Marchand
@ 2014-01-14 13:53         ` Sergey Senozhatsky
  2014-01-14 14:02           ` Jerome Marchand
  0 siblings, 1 reply; 24+ messages in thread
From: Sergey Senozhatsky @ 2014-01-14 13:53 UTC (permalink / raw)
  To: Jerome Marchand; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

On (01/14/14 14:43), Jerome Marchand wrote:
[..]
> >>
> >> That's weird: good/bad_compress are accounted, but it seems to me that
> >> they are to never used in any way. If so, there is indeed no reason to
> >> keep them.
> >>
> >>
> >>> Account each sub-request
> >>> compression size so we can calculate real device compression ratio.
> >>
> >> Your patch doesn't change the way pages_stored and compr[essed]_size
> >> are accounted. What does your patch change that allow us to calculate
> >> the "real" compression ratio?
> >>
> >>>
> >>> 4) reported zram stats:
> >>>   - num_writes  -- number of writes
> >>>   - num_reads  -- number of reads
> >>>   - pages_stored -- number of pages currently stored
> >>>   - compressed_size -- compressed size of pages stored
> >>
> >> Wouldn't it be more practical to report the original and compressed
> >> data sizes using the same units as it is currently done?
> >>
> > 
> > hm, do we really need pages_stored stats? what kind of unseful information it
> > shows to end user?.. perhaps, it's better to replace it with accounted passed
> > bvec->bv_len (as uncompressed_size).
> > 
> 
> That's really going to complicates things. We would need to keep track
> of which sectors of a particular page has been written to. It's much
> easier to keep current page granularity and consider any partial I/O
> as an whole page I/O.
> 

fair enough. thank you.

2/3 and 3/3 were changed according to your comments:
- 2/3 drop READA check
- 3/3 update commit message.

ready to re-publish. may I add your ACK to all 3 patches or just to 1/3?

	-ss

> > 
> >> Jerome
> >>
> >>>   - pages_zero  -- number of zero filled pages
> >>>   - failed_read -- number of failed reads
> >>>   - failed_writes -- can happen when memory is too low
> >>>   - invalid_io   -- non-page-aligned I/O requests
> >>>   - notify_free  -- number of swap slot free notifications
> >>>   - memory_used -- zs pool zs_get_total_size_bytes()
> >>>
> >>> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] zram: rework reported to end-user zram statistics
  2014-01-14 13:53         ` Sergey Senozhatsky
@ 2014-01-14 14:02           ` Jerome Marchand
  2014-01-14 14:09             ` Sergey Senozhatsky
  0 siblings, 1 reply; 24+ messages in thread
From: Jerome Marchand @ 2014-01-14 14:02 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

On 01/14/2014 02:53 PM, Sergey Senozhatsky wrote:
> On (01/14/14 14:43), Jerome Marchand wrote:
> [..]
>>>>
>>>> That's weird: good/bad_compress are accounted, but it seems to me that
>>>> they are to never used in any way. If so, there is indeed no reason to
>>>> keep them.
>>>>
>>>>
>>>>> Account each sub-request
>>>>> compression size so we can calculate real device compression ratio.
>>>>
>>>> Your patch doesn't change the way pages_stored and compr[essed]_size
>>>> are accounted. What does your patch change that allow us to calculate
>>>> the "real" compression ratio?
>>>>
>>>>>
>>>>> 4) reported zram stats:
>>>>>   - num_writes  -- number of writes
>>>>>   - num_reads  -- number of reads
>>>>>   - pages_stored -- number of pages currently stored
>>>>>   - compressed_size -- compressed size of pages stored
>>>>
>>>> Wouldn't it be more practical to report the original and compressed
>>>> data sizes using the same units as it is currently done?
>>>>
>>>
>>> hm, do we really need pages_stored stats? what kind of unseful information it
>>> shows to end user?.. perhaps, it's better to replace it with accounted passed
>>> bvec->bv_len (as uncompressed_size).
>>>
>>
>> That's really going to complicates things. We would need to keep track
>> of which sectors of a particular page has been written to. It's much
>> easier to keep current page granularity and consider any partial I/O
>> as an whole page I/O.
>>
> 
> fair enough. thank you.
> 
> 2/3 and 3/3 were changed according to your comments:
> - 2/3 drop READA check
> - 3/3 update commit message.
> 
> ready to re-publish. may I add your ACK to all 3 patches or just to 1/3?

The READA thing was my only concern for 2/3, so yes for this one.
Concerning the third patch, I'd like to see what other people think
about which stats we want to report.

> 
> 	-ss
> 
>>>
>>>> Jerome
>>>>
>>>>>   - pages_zero  -- number of zero filled pages
>>>>>   - failed_read -- number of failed reads
>>>>>   - failed_writes -- can happen when memory is too low
>>>>>   - invalid_io   -- non-page-aligned I/O requests
>>>>>   - notify_free  -- number of swap slot free notifications
>>>>>   - memory_used -- zs pool zs_get_total_size_bytes()
>>>>>
>>>>> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
>>
>>


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] zram: rework reported to end-user zram statistics
  2014-01-14 14:02           ` Jerome Marchand
@ 2014-01-14 14:09             ` Sergey Senozhatsky
  2014-01-14 14:20               ` Jerome Marchand
  0 siblings, 1 reply; 24+ messages in thread
From: Sergey Senozhatsky @ 2014-01-14 14:09 UTC (permalink / raw)
  To: Jerome Marchand; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

On (01/14/14 15:02), Jerome Marchand wrote:
> On 01/14/2014 02:53 PM, Sergey Senozhatsky wrote:
> > On (01/14/14 14:43), Jerome Marchand wrote:
> > [..]
> >>>>
> >>>> That's weird: good/bad_compress are accounted, but it seems to me that
> >>>> they are to never used in any way. If so, there is indeed no reason to
> >>>> keep them.
> >>>>
> >>>>
> >>>>> Account each sub-request
> >>>>> compression size so we can calculate real device compression ratio.
> >>>>
> >>>> Your patch doesn't change the way pages_stored and compr[essed]_size
> >>>> are accounted. What does your patch change that allow us to calculate
> >>>> the "real" compression ratio?
> >>>>
> >>>>>
> >>>>> 4) reported zram stats:
> >>>>>   - num_writes  -- number of writes
> >>>>>   - num_reads  -- number of reads
> >>>>>   - pages_stored -- number of pages currently stored
> >>>>>   - compressed_size -- compressed size of pages stored
> >>>>
> >>>> Wouldn't it be more practical to report the original and compressed
> >>>> data sizes using the same units as it is currently done?
> >>>>
> >>>
> >>> hm, do we really need pages_stored stats? what kind of unseful information it
> >>> shows to end user?.. perhaps, it's better to replace it with accounted passed
> >>> bvec->bv_len (as uncompressed_size).
> >>>
> >>
> >> That's really going to complicates things. We would need to keep track
> >> of which sectors of a particular page has been written to. It's much
> >> easier to keep current page granularity and consider any partial I/O
> >> as an whole page I/O.
> >>
> > 
> > fair enough. thank you.
> > 
> > 2/3 and 3/3 were changed according to your comments:
> > - 2/3 drop READA check
> > - 3/3 update commit message.
> > 
> > ready to re-publish. may I add your ACK to all 3 patches or just to 1/3?
> 
> The READA thing was my only concern for 2/3, so yes for this one.
> Concerning the third patch, I'd like to see what other people think
> about which stats we want to report.
> 

good. so I hold on for a bit to minimize the traffic and see what other
people think. thank you.

	-ss

> >>>
> >>>> Jerome
> >>>>
> >>>>>   - pages_zero  -- number of zero filled pages
> >>>>>   - failed_read -- number of failed reads
> >>>>>   - failed_writes -- can happen when memory is too low
> >>>>>   - invalid_io   -- non-page-aligned I/O requests
> >>>>>   - notify_free  -- number of swap slot free notifications
> >>>>>   - memory_used -- zs pool zs_get_total_size_bytes()
> >>>>>
> >>>>> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> >>
> >>
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] zram: rework reported to end-user zram statistics
  2014-01-14 14:09             ` Sergey Senozhatsky
@ 2014-01-14 14:20               ` Jerome Marchand
  0 siblings, 0 replies; 24+ messages in thread
From: Jerome Marchand @ 2014-01-14 14:20 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Minchan Kim, Nitin Gupta, linux-kernel

On 01/14/2014 03:09 PM, Sergey Senozhatsky wrote:
> On (01/14/14 15:02), Jerome Marchand wrote:
>> On 01/14/2014 02:53 PM, Sergey Senozhatsky wrote:
>>> On (01/14/14 14:43), Jerome Marchand wrote:
>>> [..]
>>>>>>
>>>>>> That's weird: good/bad_compress are accounted, but it seems to me that
>>>>>> they are to never used in any way. If so, there is indeed no reason to
>>>>>> keep them.
>>>>>>
>>>>>>
>>>>>>> Account each sub-request
>>>>>>> compression size so we can calculate real device compression ratio.
>>>>>>
>>>>>> Your patch doesn't change the way pages_stored and compr[essed]_size
>>>>>> are accounted. What does your patch change that allow us to calculate
>>>>>> the "real" compression ratio?
>>>>>>
>>>>>>>
>>>>>>> 4) reported zram stats:
>>>>>>>   - num_writes  -- number of writes
>>>>>>>   - num_reads  -- number of reads
>>>>>>>   - pages_stored -- number of pages currently stored
>>>>>>>   - compressed_size -- compressed size of pages stored
>>>>>>
>>>>>> Wouldn't it be more practical to report the original and compressed
>>>>>> data sizes using the same units as it is currently done?
>>>>>>
>>>>>
>>>>> hm, do we really need pages_stored stats? what kind of unseful information it
>>>>> shows to end user?.. perhaps, it's better to replace it with accounted passed
>>>>> bvec->bv_len (as uncompressed_size).
>>>>>
>>>>
>>>> That's really going to complicates things. We would need to keep track
>>>> of which sectors of a particular page has been written to. It's much
>>>> easier to keep current page granularity and consider any partial I/O
>>>> as an whole page I/O.
>>>>
>>>
>>> fair enough. thank you.
>>>
>>> 2/3 and 3/3 were changed according to your comments:
>>> - 2/3 drop READA check
>>> - 3/3 update commit message.
>>>
>>> ready to re-publish. may I add your ACK to all 3 patches or just to 1/3?
>>
>> The READA thing was my only concern for 2/3, so yes for this one.
>> Concerning the third patch, I'd like to see what other people think
>> about which stats we want to report.
>>
> 
> good. so I hold on for a bit to minimize the traffic and see what other
> people think. thank you.
> 
> 	-ss
> 
>>>>>
>>>>>> Jerome
>>>>>>
>>>>>>>   - pages_zero  -- number of zero filled pages
>>>>>>>   - failed_read -- number of failed reads
>>>>>>>   - failed_writes -- can happen when memory is too low
>>>>>>>   - invalid_io   -- non-page-aligned I/O requests
>>>>>>>   - notify_free  -- number of swap slot free notifications
>>>>>>>   - memory_used -- zs pool zs_get_total_size_bytes()

I also wonder if we should add size of meta-data to memory_used,
especially the table size which is probably not always negligible.

Jerome

>>>>>>>
>>>>>>> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
>>>>
>>>>
>>


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/3] zram: drop `init_done' struct zram member
  2014-01-14  9:37 ` [PATCH 1/3] zram: drop `init_done' struct zram member Sergey Senozhatsky
  2014-01-14 11:03   ` Jerome Marchand
@ 2014-01-15  1:52   ` Minchan Kim
  1 sibling, 0 replies; 24+ messages in thread
From: Minchan Kim @ 2014-01-15  1:52 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Jerome Marchand, Nitin Gupta, linux-kernel

On Tue, Jan 14, 2014 at 12:37:38PM +0300, Sergey Senozhatsky wrote:
> Introduce init_done() helper function which allows us to drop
> `init_done' struct zram member. init_done() uses the fact that
> ->init_done == 1 equals to ->meta != NULL.
> 
> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Acked-by: Minchan Kim <minchan@kernel.org>

-- 
Kind regards,
Minchan Kim

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv2 2/3] zram: do not pass rw argument to __zram_make_request()
  2014-01-14 11:27     ` [PATCHv2 " Sergey Senozhatsky
@ 2014-01-15  2:10       ` Minchan Kim
  0 siblings, 0 replies; 24+ messages in thread
From: Minchan Kim @ 2014-01-15  2:10 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Jerome Marchand, Nitin Gupta, linux-kernel

Hello Sergey,

On Tue, Jan 14, 2014 at 02:27:23PM +0300, Sergey Senozhatsky wrote:
> Do not pass rw argument down the __zram_make_request() -> zram_bvec_rw()
> chain, decode it in zram_bvec_rw() instead. Besides, this is the place
> where we distinguish READ (+READ AHEAD) and WRITE bio data directions, so
> account zram RW stats here, instead of __zram_make_request(). This also
> allows to account a real number of zram READ/WRITE operations, not just
> requests (single RW request may cause a number of zram RW ops with separate
> locking, compression/decompression, etc).
> 
> v2: use bio_rw() instead of bio_data_dir(). noted by Jerome Marchand.

We don't have any special logic for READA so please use bio_data_dir
instead of bio_rw.

And please Ccing Andrew Morton when you send a updated patch.
Thanks.

> 
> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> ---
>  drivers/block/zram/zram_drv.c | 33 +++++++++++++++------------------
>  1 file changed, 15 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> index c323e05..2a7682c 100644
> --- a/drivers/block/zram/zram_drv.c
> +++ b/drivers/block/zram/zram_drv.c
> @@ -533,14 +533,21 @@ out:
>  }
>  
>  static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index,
> -			int offset, struct bio *bio, int rw)
> +			int offset, struct bio *bio)
>  {
>  	int ret;
> +	int rw = bio_rw(bio);
>  
> -	if (rw == READ)
> +	if (rw == READA)
> +		rw = READ;
> +
> +	if (rw == READ) {
> +		atomic64_inc(&zram->stats.num_reads);
>  		ret = zram_bvec_read(zram, bvec, index, offset, bio);
> -	else
> +	} else {
> +		atomic64_inc(&zram->stats.num_writes);
>  		ret = zram_bvec_write(zram, bvec, index, offset);
> +	}
>  
>  	return ret;
>  }
> @@ -670,22 +677,13 @@ out:
>  	return ret;
>  }
>  
> -static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
> +static void __zram_make_request(struct zram *zram, struct bio *bio)
>  {
>  	int offset;
>  	u32 index;
>  	struct bio_vec bvec;
>  	struct bvec_iter iter;
>  
> -	switch (rw) {
> -	case READ:
> -		atomic64_inc(&zram->stats.num_reads);
> -		break;
> -	case WRITE:
> -		atomic64_inc(&zram->stats.num_writes);
> -		break;
> -	}
> -
>  	index = bio->bi_iter.bi_sector >> SECTORS_PER_PAGE_SHIFT;
>  	offset = (bio->bi_iter.bi_sector &
>  		  (SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT;
> @@ -704,16 +702,15 @@ static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
>  			bv.bv_len = max_transfer_size;
>  			bv.bv_offset = bvec.bv_offset;
>  
> -			if (zram_bvec_rw(zram, &bv, index, offset, bio, rw) < 0)
> +			if (zram_bvec_rw(zram, &bv, index, offset, bio) < 0)
>  				goto out;
>  
>  			bv.bv_len = bvec.bv_len - max_transfer_size;
>  			bv.bv_offset += max_transfer_size;
> -			if (zram_bvec_rw(zram, &bv, index+1, 0, bio, rw) < 0)
> +			if (zram_bvec_rw(zram, &bv, index + 1, 0, bio) < 0)
>  				goto out;
>  		} else
> -			if (zram_bvec_rw(zram, &bvec, index, offset, bio, rw)
> -			    < 0)
> +			if (zram_bvec_rw(zram, &bvec, index, offset, bio) < 0)
>  				goto out;
>  
>  		update_position(&index, &offset, &bvec);
> @@ -743,7 +740,7 @@ static void zram_make_request(struct request_queue *queue, struct bio *bio)
>  		goto error;
>  	}
>  
> -	__zram_make_request(zram, bio, bio_data_dir(bio));
> +	__zram_make_request(zram, bio);
>  	up_read(&zram->init_lock);
>  
>  	return;
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

-- 
Kind regards,
Minchan Kim

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] zram: rework reported to end-user zram statistics
  2014-01-14  9:37 ` [PATCH 3/3] zram: rework reported to end-user zram statistics Sergey Senozhatsky
  2014-01-14 10:38   ` Jerome Marchand
@ 2014-01-15  4:24   ` Minchan Kim
  2014-01-15  9:10     ` Sergey Senozhatsky
  1 sibling, 1 reply; 24+ messages in thread
From: Minchan Kim @ 2014-01-15  4:24 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Jerome Marchand, Nitin Gupta, linux-kernel

Hello Sergey,

On Tue, Jan 14, 2014 at 12:37:40PM +0300, Sergey Senozhatsky wrote:
> 1) Introduce ZRAM_ATTR_RO macro to generate zram atomic64_t stats
> `show' functions and reduce code duplication.
> 
> 2) Account and report back to user numbers of failed READ and WRITE
> operations.
> 
> 3) Remove `good' and `bad' compressed sub-requests stats. RW request may
> cause a number of RW sub-requests. zram used to account `good' compressed
> sub-queries (with compressed size less than 50% of original size), `bad'
> compressed sub-queries (with compressed size greater that 75% of original
> size), leaving sub-requests with compression size between 50% and 75% of
> original size not accounted and not reported. Account each sub-request
> compression size so we can calculate real device compression ratio.
> 
> 4) reported zram stats:
>   - num_writes  -- number of writes
>   - num_reads  -- number of reads
>   - pages_stored -- number of pages currently stored
>   - compressed_size -- compressed size of pages stored
>   - pages_zero  -- number of zero filled pages
>   - failed_read -- number of failed reads
>   - failed_writes -- can happen when memory is too low
>   - invalid_io   -- non-page-aligned I/O requests
>   - notify_free  -- number of swap slot free notifications
>   - memory_used -- zs pool zs_get_total_size_bytes()
> 
> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>

So this patch includes some clean up and behavior changes?
Please seaprate them and each patch in behavior change includes
why it's bad or good(ie, motivation).

It could make reviewer/maintainer happy, even you because
some of them could be picked up and other things could be dropped.
Sorry for the bothering you.

Thanks.

> ---
>  drivers/block/zram/zram_drv.c | 167 ++++++++++++------------------------------
>  drivers/block/zram/zram_drv.h |  17 ++---
>  2 files changed, 54 insertions(+), 130 deletions(-)
> 
> diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> index 2a7682c..8bddaff 100644
> --- a/drivers/block/zram/zram_drv.c
> +++ b/drivers/block/zram/zram_drv.c
> @@ -42,6 +42,17 @@ static struct zram *zram_devices;
>  /* Module params (documentation at end) */
>  static unsigned int num_devices = 1;
>  
> +#define ZRAM_ATTR_RO(name)						\
> +static ssize_t zram_attr_##name##_show(struct device *d,		\
> +				struct device_attribute *attr, char *b)	\
> +{									\
> +	struct zram *zram = dev_to_zram(d);				\
> +	return sprintf(b, "%llu\n",					\
> +		(u64)atomic64_read(&zram->stats.name));			\
> +}									\
> +static struct device_attribute dev_attr_##name =			\
> +	__ATTR(name, S_IRUGO, zram_attr_##name##_show, NULL);
> +
>  static inline int init_done(struct zram *zram)
>  {
>  	return zram->meta != NULL;
> @@ -52,97 +63,36 @@ static inline struct zram *dev_to_zram(struct device *dev)
>  	return (struct zram *)dev_to_disk(dev)->private_data;
>  }
>  
> -static ssize_t disksize_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%llu\n", zram->disksize);
> -}
> -
> -static ssize_t initstate_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%u\n", init_done(zram));
> -}
> -
> -static ssize_t num_reads_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%llu\n",
> -			(u64)atomic64_read(&zram->stats.num_reads));
> -}
> -
> -static ssize_t num_writes_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%llu\n",
> -			(u64)atomic64_read(&zram->stats.num_writes));
> -}
> -
> -static ssize_t invalid_io_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%llu\n",
> -			(u64)atomic64_read(&zram->stats.invalid_io));
> -}
> -
> -static ssize_t notify_free_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%llu\n",
> -			(u64)atomic64_read(&zram->stats.notify_free));
> -}
> -
> -static ssize_t zero_pages_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%u\n", atomic_read(&zram->stats.pages_zero));
> -}
> -
> -static ssize_t orig_data_size_show(struct device *dev,
> +static ssize_t memory_used_show(struct device *dev,
>  		struct device_attribute *attr, char *buf)
>  {
> +	u64 val = 0;
>  	struct zram *zram = dev_to_zram(dev);
> +	struct zram_meta *meta = zram->meta;
>  
> -	return sprintf(buf, "%llu\n",
> -		(u64)(atomic_read(&zram->stats.pages_stored)) << PAGE_SHIFT);
> +	down_read(&zram->init_lock);
> +	if (init_done(zram))
> +		val = zs_get_total_size_bytes(meta->mem_pool);
> +	up_read(&zram->init_lock);
> +	return sprintf(buf, "%llu\n", val);
>  }
>  
> -static ssize_t compr_data_size_show(struct device *dev,
> +static ssize_t disksize_show(struct device *dev,
>  		struct device_attribute *attr, char *buf)
>  {
>  	struct zram *zram = dev_to_zram(dev);
> -
> -	return sprintf(buf, "%llu\n",
> -			(u64)atomic64_read(&zram->stats.compr_size));
> +	return sprintf(buf, "%llu\n", zram->disksize);
>  }
>  
> -static ssize_t mem_used_total_show(struct device *dev,
> +static ssize_t initstate_show(struct device *dev,
>  		struct device_attribute *attr, char *buf)
>  {
> -	u64 val = 0;
> +	u32 val = 0;
>  	struct zram *zram = dev_to_zram(dev);
> -	struct zram_meta *meta = zram->meta;
> -
>  	down_read(&zram->init_lock);
> -	if (init_done(zram))
> -		val = zs_get_total_size_bytes(meta->mem_pool);
> +	val = init_done(zram);
>  	up_read(&zram->init_lock);
> -
> -	return sprintf(buf, "%llu\n", val);
> +	return sprintf(buf, "%u\n", val);
>  }
>  
>  /* flag operations needs meta->tb_lock */
> @@ -293,7 +243,6 @@ static void zram_free_page(struct zram *zram, size_t index)
>  {
>  	struct zram_meta *meta = zram->meta;
>  	unsigned long handle = meta->table[index].handle;
> -	u16 size = meta->table[index].size;
>  
>  	if (unlikely(!handle)) {
>  		/*
> @@ -302,21 +251,15 @@ static void zram_free_page(struct zram *zram, size_t index)
>  		 */
>  		if (zram_test_flag(meta, index, ZRAM_ZERO)) {
>  			zram_clear_flag(meta, index, ZRAM_ZERO);
> -			atomic_dec(&zram->stats.pages_zero);
> +			atomic64_dec(&zram->stats.pages_zero);
>  		}
>  		return;
>  	}
>  
> -	if (unlikely(size > max_zpage_size))
> -		atomic_dec(&zram->stats.bad_compress);
> -
>  	zs_free(meta->mem_pool, handle);
>  
> -	if (size <= PAGE_SIZE / 2)
> -		atomic_dec(&zram->stats.good_compress);
> -
> -	atomic64_sub(meta->table[index].size, &zram->stats.compr_size);
> -	atomic_dec(&zram->stats.pages_stored);
> +	atomic64_sub(meta->table[index].size, &zram->stats.compressed_size);
> +	atomic64_dec(&zram->stats.pages_stored);
>  
>  	meta->table[index].handle = 0;
>  	meta->table[index].size = 0;
> @@ -362,7 +305,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
>  static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
>  			  u32 index, int offset, struct bio *bio)
>  {
> -	int ret;
> +	int ret = -EINVAL;
>  	struct page *page;
>  	unsigned char *user_mem, *uncmem = NULL;
>  	struct zram_meta *meta = zram->meta;
> @@ -406,6 +349,8 @@ out_cleanup:
>  	kunmap_atomic(user_mem);
>  	if (is_partial_io(bvec))
>  		kfree(uncmem);
> +	if (ret)
> +		atomic64_inc(&zram->stats.failed_reads);
>  	return ret;
>  }
>  
> @@ -459,7 +404,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
>  		zram_set_flag(meta, index, ZRAM_ZERO);
>  		write_unlock(&zram->meta->tb_lock);
>  
> -		atomic_inc(&zram->stats.pages_zero);
> +		atomic64_inc(&zram->stats.pages_zero);
>  		ret = 0;
>  		goto out;
>  	}
> @@ -478,7 +423,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
>  	}
>  
>  	if (unlikely(clen > max_zpage_size)) {
> -		atomic_inc(&zram->stats.bad_compress);
>  		clen = PAGE_SIZE;
>  		src = NULL;
>  		if (is_partial_io(bvec))
> @@ -516,11 +460,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
>  	write_unlock(&zram->meta->tb_lock);
>  
>  	/* Update stats */
> -	atomic64_add(clen, &zram->stats.compr_size);
> -	atomic_inc(&zram->stats.pages_stored);
> -	if (clen <= PAGE_SIZE / 2)
> -		atomic_inc(&zram->stats.good_compress);
> -
> +	atomic64_add(clen, &zram->stats.compressed_size);
> +	atomic64_inc(&zram->stats.pages_stored);
>  out:
>  	if (locked)
>  		mutex_unlock(&meta->buffer_lock);
> @@ -586,23 +527,8 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
>  
>  static void zram_init_device(struct zram *zram, struct zram_meta *meta)
>  {
> -	if (zram->disksize > 2 * (totalram_pages << PAGE_SHIFT)) {
> -		pr_info(
> -		"There is little point creating a zram of greater than "
> -		"twice the size of memory since we expect a 2:1 compression "
> -		"ratio. Note that zram uses about 0.1%% of the size of "
> -		"the disk when not in use so a huge zram is "
> -		"wasteful.\n"
> -		"\tMemory Size: %lu kB\n"
> -		"\tSize you selected: %llu kB\n"
> -		"Continuing anyway ...\n",
> -		(totalram_pages << PAGE_SHIFT) >> 10, zram->disksize >> 10
> -		);
> -	}
> -
>  	/* zram devices sort of resembles non-rotational disks */
>  	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
> -
>  	zram->meta = meta;
>  	pr_debug("Initialization done!\n");
>  }
> @@ -774,14 +700,15 @@ static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR,
>  		disksize_show, disksize_store);
>  static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
>  static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
> -static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL);
> -static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL);
> -static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL);
> -static DEVICE_ATTR(notify_free, S_IRUGO, notify_free_show, NULL);
> -static DEVICE_ATTR(zero_pages, S_IRUGO, zero_pages_show, NULL);
> -static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL);
> -static DEVICE_ATTR(compr_data_size, S_IRUGO, compr_data_size_show, NULL);
> -static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL);
> +static DEVICE_ATTR(memory_used, S_IRUGO, memory_used_show, NULL);
> +
> +ZRAM_ATTR_RO(num_reads);
> +ZRAM_ATTR_RO(num_writes);
> +ZRAM_ATTR_RO(pages_stored);
> +ZRAM_ATTR_RO(invalid_io);
> +ZRAM_ATTR_RO(notify_free);
> +ZRAM_ATTR_RO(pages_zero);
> +ZRAM_ATTR_RO(compressed_size);
>  
>  static struct attribute *zram_disk_attrs[] = {
>  	&dev_attr_disksize.attr,
> @@ -789,12 +716,12 @@ static struct attribute *zram_disk_attrs[] = {
>  	&dev_attr_reset.attr,
>  	&dev_attr_num_reads.attr,
>  	&dev_attr_num_writes.attr,
> +	&dev_attr_pages_stored.attr,
>  	&dev_attr_invalid_io.attr,
>  	&dev_attr_notify_free.attr,
> -	&dev_attr_zero_pages.attr,
> -	&dev_attr_orig_data_size.attr,
> -	&dev_attr_compr_data_size.attr,
> -	&dev_attr_mem_used_total.attr,
> +	&dev_attr_pages_zero.attr,
> +	&dev_attr_compressed_size.attr,
> +	&dev_attr_memory_used.attr,
>  	NULL,
>  };
>  
> diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
> index e81e9cd..277023d 100644
> --- a/drivers/block/zram/zram_drv.h
> +++ b/drivers/block/zram/zram_drv.h
> @@ -64,22 +64,19 @@ enum zram_pageflags {
>  struct table {
>  	unsigned long handle;
>  	u16 size;	/* object size (excluding header) */
> -	u8 count;	/* object ref count (not yet used) */
> -	u8 flags;
> +	u16 flags;
>  } __aligned(4);
>  
>  struct zram_stats {
> -	atomic64_t compr_size;	/* compressed size of pages stored */
> -	atomic64_t num_reads;	/* failed + successful */
> -	atomic64_t num_writes;	/* --do-- */
> -	atomic64_t failed_reads;	/* should NEVER! happen */
> +	atomic64_t num_writes;	/* number of writes */
> +	atomic64_t num_reads;	/* number of reads */
> +	atomic64_t pages_stored;	/* no. of pages currently stored */
> +	atomic64_t compressed_size;	/* compressed size of pages stored */
> +	atomic64_t pages_zero;		/* no. of zero filled pages */
> +	atomic64_t failed_reads;	/* no. of failed reads */
>  	atomic64_t failed_writes;	/* can happen when memory is too low */
>  	atomic64_t invalid_io;	/* non-page-aligned I/O requests */
>  	atomic64_t notify_free;	/* no. of swap slot free notifications */
> -	atomic_t pages_zero;		/* no. of zero filled pages */
> -	atomic_t pages_stored;	/* no. of pages currently stored */
> -	atomic_t good_compress;	/* % of pages with compression ratio<=50% */
> -	atomic_t bad_compress;	/* % of pages with compression ratio>=75% */
>  };
>  
>  struct zram_meta {
> -- 
> 1.8.5.2.487.g7559984
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

-- 
Kind regards,
Minchan Kim

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] zram: rework reported to end-user zram statistics
  2014-01-15  4:24   ` Minchan Kim
@ 2014-01-15  9:10     ` Sergey Senozhatsky
  0 siblings, 0 replies; 24+ messages in thread
From: Sergey Senozhatsky @ 2014-01-15  9:10 UTC (permalink / raw)
  To: Minchan Kim; +Cc: Jerome Marchand, Nitin Gupta, linux-kernel

On (01/15/14 13:24), Minchan Kim wrote:
> Hello Sergey,
> 
> On Tue, Jan 14, 2014 at 12:37:40PM +0300, Sergey Senozhatsky wrote:
> > 1) Introduce ZRAM_ATTR_RO macro to generate zram atomic64_t stats
> > `show' functions and reduce code duplication.
> > 
> > 2) Account and report back to user numbers of failed READ and WRITE
> > operations.
> > 
> > 3) Remove `good' and `bad' compressed sub-requests stats. RW request may
> > cause a number of RW sub-requests. zram used to account `good' compressed
> > sub-queries (with compressed size less than 50% of original size), `bad'
> > compressed sub-queries (with compressed size greater that 75% of original
> > size), leaving sub-requests with compression size between 50% and 75% of
> > original size not accounted and not reported. Account each sub-request
> > compression size so we can calculate real device compression ratio.
> > 
> > 4) reported zram stats:
> >   - num_writes  -- number of writes
> >   - num_reads  -- number of reads
> >   - pages_stored -- number of pages currently stored
> >   - compressed_size -- compressed size of pages stored
> >   - pages_zero  -- number of zero filled pages
> >   - failed_read -- number of failed reads
> >   - failed_writes -- can happen when memory is too low
> >   - invalid_io   -- non-page-aligned I/O requests
> >   - notify_free  -- number of swap slot free notifications
> >   - memory_used -- zs pool zs_get_total_size_bytes()
> > 
> > Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> 
>

Hello Minchan,
I wouldn't say that it changes behaviour. The only things that is new
is that zram now accounts failed RW requests. the rest is a part of
clean up.

	-ss

> So this patch includes some clean up and behavior changes?
> Please seaprate them and each patch in behavior change includes
> why it's bad or good(ie, motivation).
> 
> It could make reviewer/maintainer happy, even you because
> some of them could be picked up and other things could be dropped.
> Sorry for the bothering you.
> 
> Thanks.
> 
> > ---
> >  drivers/block/zram/zram_drv.c | 167 ++++++++++++------------------------------
> >  drivers/block/zram/zram_drv.h |  17 ++---
> >  2 files changed, 54 insertions(+), 130 deletions(-)
> > 
> > diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> > index 2a7682c..8bddaff 100644
> > --- a/drivers/block/zram/zram_drv.c
> > +++ b/drivers/block/zram/zram_drv.c
> > @@ -42,6 +42,17 @@ static struct zram *zram_devices;
> >  /* Module params (documentation at end) */
> >  static unsigned int num_devices = 1;
> >  
> > +#define ZRAM_ATTR_RO(name)						\
> > +static ssize_t zram_attr_##name##_show(struct device *d,		\
> > +				struct device_attribute *attr, char *b)	\
> > +{									\
> > +	struct zram *zram = dev_to_zram(d);				\
> > +	return sprintf(b, "%llu\n",					\
> > +		(u64)atomic64_read(&zram->stats.name));			\
> > +}									\
> > +static struct device_attribute dev_attr_##name =			\
> > +	__ATTR(name, S_IRUGO, zram_attr_##name##_show, NULL);
> > +
> >  static inline int init_done(struct zram *zram)
> >  {
> >  	return zram->meta != NULL;
> > @@ -52,97 +63,36 @@ static inline struct zram *dev_to_zram(struct device *dev)
> >  	return (struct zram *)dev_to_disk(dev)->private_data;
> >  }
> >  
> > -static ssize_t disksize_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n", zram->disksize);
> > -}
> > -
> > -static ssize_t initstate_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%u\n", init_done(zram));
> > -}
> > -
> > -static ssize_t num_reads_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.num_reads));
> > -}
> > -
> > -static ssize_t num_writes_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.num_writes));
> > -}
> > -
> > -static ssize_t invalid_io_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.invalid_io));
> > -}
> > -
> > -static ssize_t notify_free_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.notify_free));
> > -}
> > -
> > -static ssize_t zero_pages_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%u\n", atomic_read(&zram->stats.pages_zero));
> > -}
> > -
> > -static ssize_t orig_data_size_show(struct device *dev,
> > +static ssize_t memory_used_show(struct device *dev,
> >  		struct device_attribute *attr, char *buf)
> >  {
> > +	u64 val = 0;
> >  	struct zram *zram = dev_to_zram(dev);
> > +	struct zram_meta *meta = zram->meta;
> >  
> > -	return sprintf(buf, "%llu\n",
> > -		(u64)(atomic_read(&zram->stats.pages_stored)) << PAGE_SHIFT);
> > +	down_read(&zram->init_lock);
> > +	if (init_done(zram))
> > +		val = zs_get_total_size_bytes(meta->mem_pool);
> > +	up_read(&zram->init_lock);
> > +	return sprintf(buf, "%llu\n", val);
> >  }
> >  
> > -static ssize_t compr_data_size_show(struct device *dev,
> > +static ssize_t disksize_show(struct device *dev,
> >  		struct device_attribute *attr, char *buf)
> >  {
> >  	struct zram *zram = dev_to_zram(dev);
> > -
> > -	return sprintf(buf, "%llu\n",
> > -			(u64)atomic64_read(&zram->stats.compr_size));
> > +	return sprintf(buf, "%llu\n", zram->disksize);
> >  }
> >  
> > -static ssize_t mem_used_total_show(struct device *dev,
> > +static ssize_t initstate_show(struct device *dev,
> >  		struct device_attribute *attr, char *buf)
> >  {
> > -	u64 val = 0;
> > +	u32 val = 0;
> >  	struct zram *zram = dev_to_zram(dev);
> > -	struct zram_meta *meta = zram->meta;
> > -
> >  	down_read(&zram->init_lock);
> > -	if (init_done(zram))
> > -		val = zs_get_total_size_bytes(meta->mem_pool);
> > +	val = init_done(zram);
> >  	up_read(&zram->init_lock);
> > -
> > -	return sprintf(buf, "%llu\n", val);
> > +	return sprintf(buf, "%u\n", val);
> >  }
> >  
> >  /* flag operations needs meta->tb_lock */
> > @@ -293,7 +243,6 @@ static void zram_free_page(struct zram *zram, size_t index)
> >  {
> >  	struct zram_meta *meta = zram->meta;
> >  	unsigned long handle = meta->table[index].handle;
> > -	u16 size = meta->table[index].size;
> >  
> >  	if (unlikely(!handle)) {
> >  		/*
> > @@ -302,21 +251,15 @@ static void zram_free_page(struct zram *zram, size_t index)
> >  		 */
> >  		if (zram_test_flag(meta, index, ZRAM_ZERO)) {
> >  			zram_clear_flag(meta, index, ZRAM_ZERO);
> > -			atomic_dec(&zram->stats.pages_zero);
> > +			atomic64_dec(&zram->stats.pages_zero);
> >  		}
> >  		return;
> >  	}
> >  
> > -	if (unlikely(size > max_zpage_size))
> > -		atomic_dec(&zram->stats.bad_compress);
> > -
> >  	zs_free(meta->mem_pool, handle);
> >  
> > -	if (size <= PAGE_SIZE / 2)
> > -		atomic_dec(&zram->stats.good_compress);
> > -
> > -	atomic64_sub(meta->table[index].size, &zram->stats.compr_size);
> > -	atomic_dec(&zram->stats.pages_stored);
> > +	atomic64_sub(meta->table[index].size, &zram->stats.compressed_size);
> > +	atomic64_dec(&zram->stats.pages_stored);
> >  
> >  	meta->table[index].handle = 0;
> >  	meta->table[index].size = 0;
> > @@ -362,7 +305,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
> >  static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
> >  			  u32 index, int offset, struct bio *bio)
> >  {
> > -	int ret;
> > +	int ret = -EINVAL;
> >  	struct page *page;
> >  	unsigned char *user_mem, *uncmem = NULL;
> >  	struct zram_meta *meta = zram->meta;
> > @@ -406,6 +349,8 @@ out_cleanup:
> >  	kunmap_atomic(user_mem);
> >  	if (is_partial_io(bvec))
> >  		kfree(uncmem);
> > +	if (ret)
> > +		atomic64_inc(&zram->stats.failed_reads);
> >  	return ret;
> >  }
> >  
> > @@ -459,7 +404,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
> >  		zram_set_flag(meta, index, ZRAM_ZERO);
> >  		write_unlock(&zram->meta->tb_lock);
> >  
> > -		atomic_inc(&zram->stats.pages_zero);
> > +		atomic64_inc(&zram->stats.pages_zero);
> >  		ret = 0;
> >  		goto out;
> >  	}
> > @@ -478,7 +423,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
> >  	}
> >  
> >  	if (unlikely(clen > max_zpage_size)) {
> > -		atomic_inc(&zram->stats.bad_compress);
> >  		clen = PAGE_SIZE;
> >  		src = NULL;
> >  		if (is_partial_io(bvec))
> > @@ -516,11 +460,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
> >  	write_unlock(&zram->meta->tb_lock);
> >  
> >  	/* Update stats */
> > -	atomic64_add(clen, &zram->stats.compr_size);
> > -	atomic_inc(&zram->stats.pages_stored);
> > -	if (clen <= PAGE_SIZE / 2)
> > -		atomic_inc(&zram->stats.good_compress);
> > -
> > +	atomic64_add(clen, &zram->stats.compressed_size);
> > +	atomic64_inc(&zram->stats.pages_stored);
> >  out:
> >  	if (locked)
> >  		mutex_unlock(&meta->buffer_lock);
> > @@ -586,23 +527,8 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
> >  
> >  static void zram_init_device(struct zram *zram, struct zram_meta *meta)
> >  {
> > -	if (zram->disksize > 2 * (totalram_pages << PAGE_SHIFT)) {
> > -		pr_info(
> > -		"There is little point creating a zram of greater than "
> > -		"twice the size of memory since we expect a 2:1 compression "
> > -		"ratio. Note that zram uses about 0.1%% of the size of "
> > -		"the disk when not in use so a huge zram is "
> > -		"wasteful.\n"
> > -		"\tMemory Size: %lu kB\n"
> > -		"\tSize you selected: %llu kB\n"
> > -		"Continuing anyway ...\n",
> > -		(totalram_pages << PAGE_SHIFT) >> 10, zram->disksize >> 10
> > -		);
> > -	}
> > -
> >  	/* zram devices sort of resembles non-rotational disks */
> >  	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
> > -
> >  	zram->meta = meta;
> >  	pr_debug("Initialization done!\n");
> >  }
> > @@ -774,14 +700,15 @@ static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR,
> >  		disksize_show, disksize_store);
> >  static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
> >  static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
> > -static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL);
> > -static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL);
> > -static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL);
> > -static DEVICE_ATTR(notify_free, S_IRUGO, notify_free_show, NULL);
> > -static DEVICE_ATTR(zero_pages, S_IRUGO, zero_pages_show, NULL);
> > -static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL);
> > -static DEVICE_ATTR(compr_data_size, S_IRUGO, compr_data_size_show, NULL);
> > -static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL);
> > +static DEVICE_ATTR(memory_used, S_IRUGO, memory_used_show, NULL);
> > +
> > +ZRAM_ATTR_RO(num_reads);
> > +ZRAM_ATTR_RO(num_writes);
> > +ZRAM_ATTR_RO(pages_stored);
> > +ZRAM_ATTR_RO(invalid_io);
> > +ZRAM_ATTR_RO(notify_free);
> > +ZRAM_ATTR_RO(pages_zero);
> > +ZRAM_ATTR_RO(compressed_size);
> >  
> >  static struct attribute *zram_disk_attrs[] = {
> >  	&dev_attr_disksize.attr,
> > @@ -789,12 +716,12 @@ static struct attribute *zram_disk_attrs[] = {
> >  	&dev_attr_reset.attr,
> >  	&dev_attr_num_reads.attr,
> >  	&dev_attr_num_writes.attr,
> > +	&dev_attr_pages_stored.attr,
> >  	&dev_attr_invalid_io.attr,
> >  	&dev_attr_notify_free.attr,
> > -	&dev_attr_zero_pages.attr,
> > -	&dev_attr_orig_data_size.attr,
> > -	&dev_attr_compr_data_size.attr,
> > -	&dev_attr_mem_used_total.attr,
> > +	&dev_attr_pages_zero.attr,
> > +	&dev_attr_compressed_size.attr,
> > +	&dev_attr_memory_used.attr,
> >  	NULL,
> >  };
> >  
> > diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
> > index e81e9cd..277023d 100644
> > --- a/drivers/block/zram/zram_drv.h
> > +++ b/drivers/block/zram/zram_drv.h
> > @@ -64,22 +64,19 @@ enum zram_pageflags {
> >  struct table {
> >  	unsigned long handle;
> >  	u16 size;	/* object size (excluding header) */
> > -	u8 count;	/* object ref count (not yet used) */
> > -	u8 flags;
> > +	u16 flags;
> >  } __aligned(4);
> >  
> >  struct zram_stats {
> > -	atomic64_t compr_size;	/* compressed size of pages stored */
> > -	atomic64_t num_reads;	/* failed + successful */
> > -	atomic64_t num_writes;	/* --do-- */
> > -	atomic64_t failed_reads;	/* should NEVER! happen */
> > +	atomic64_t num_writes;	/* number of writes */
> > +	atomic64_t num_reads;	/* number of reads */
> > +	atomic64_t pages_stored;	/* no. of pages currently stored */
> > +	atomic64_t compressed_size;	/* compressed size of pages stored */
> > +	atomic64_t pages_zero;		/* no. of zero filled pages */
> > +	atomic64_t failed_reads;	/* no. of failed reads */
> >  	atomic64_t failed_writes;	/* can happen when memory is too low */
> >  	atomic64_t invalid_io;	/* non-page-aligned I/O requests */
> >  	atomic64_t notify_free;	/* no. of swap slot free notifications */
> > -	atomic_t pages_zero;		/* no. of zero filled pages */
> > -	atomic_t pages_stored;	/* no. of pages currently stored */
> > -	atomic_t good_compress;	/* % of pages with compression ratio<=50% */
> > -	atomic_t bad_compress;	/* % of pages with compression ratio>=75% */
> >  };
> >  
> >  struct zram_meta {
> > -- 
> > 1.8.5.2.487.g7559984
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/
> 
> -- 
> Kind regards,
> Minchan Kim
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2014-01-15  9:13 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-14  9:37 [PATCH 0/3] zram stats rework and code cleanup Sergey Senozhatsky
2014-01-14  9:37 ` [PATCH 1/3] zram: drop `init_done' struct zram member Sergey Senozhatsky
2014-01-14 11:03   ` Jerome Marchand
2014-01-15  1:52   ` Minchan Kim
2014-01-14  9:37 ` [PATCH 2/3] zram: do not pass rw argument to __zram_make_request() Sergey Senozhatsky
2014-01-14 11:02   ` Jerome Marchand
2014-01-14 11:13     ` Sergey Senozhatsky
2014-01-14 12:27       ` Jerome Marchand
2014-01-14 11:27     ` [PATCHv2 " Sergey Senozhatsky
2014-01-15  2:10       ` Minchan Kim
2014-01-14  9:37 ` [PATCH 3/3] zram: rework reported to end-user zram statistics Sergey Senozhatsky
2014-01-14 10:38   ` Jerome Marchand
2014-01-14 10:57     ` Sergey Senozhatsky
2014-01-14 12:15       ` Jerome Marchand
2014-01-14 12:30         ` Sergey Senozhatsky
2014-01-14 11:10     ` Sergey Senozhatsky
2014-01-14 13:43       ` Jerome Marchand
2014-01-14 13:53         ` Sergey Senozhatsky
2014-01-14 14:02           ` Jerome Marchand
2014-01-14 14:09             ` Sergey Senozhatsky
2014-01-14 14:20               ` Jerome Marchand
2014-01-15  4:24   ` Minchan Kim
2014-01-15  9:10     ` Sergey Senozhatsky
2014-01-14  9:42 ` [PATCH 0/3] zram stats rework and code cleanup Sergey Senozhatsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).