it's not same compressed pages and deduplicated pages
so we shouldn't count duplicated pages as compressed pages.

Signed-off-by: Minchan Kim <[email protected]>
---
 drivers/block/zram/zram_dedup.c |  4 ----
 drivers/block/zram/zram_drv.c   | 24 +++++++++++++++++++-----
 drivers/block/zram/zram_drv.h   |  1 +
 3 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/block/zram/zram_dedup.c b/drivers/block/zram/zram_dedup.c
index 14c4988f8ff7..c15848cc1b31 100644
--- a/drivers/block/zram/zram_dedup.c
+++ b/drivers/block/zram/zram_dedup.c
@@ -101,9 +101,6 @@ static unsigned long zram_dedup_put(struct zram *zram,
        entry->refcount--;
        if (!entry->refcount)
                rb_erase(&entry->rb_node, &hash->rb_root);
-       else
-               atomic64_sub(entry->len, &zram->stats.dup_data_size);
-
        spin_unlock(&hash->lock);
 
        return entry->refcount;
@@ -127,7 +124,6 @@ static struct zram_entry *__zram_dedup_get(struct zram 
*zram,
 
 again:
        entry->refcount++;
-       atomic64_add(entry->len, &zram->stats.dup_data_size);
        spin_unlock(&hash->lock);
 
        if (prev)
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index b885356551e9..8152e405117b 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -624,15 +624,22 @@ static void zram_free_page(struct zram *zram, size_t 
index)
                return;
        }
 
+       if (zram_dedup_enabled(zram) &&
+                       zram_test_flag(zram, index, ZRAM_DUP)) {
+               zram_clear_flag(zram, index, ZRAM_DUP);
+               atomic64_sub(entry->len, &zram->stats.dup_data_size);
+               goto out;
+       }
+
        if (!entry)
                return;
 
-       zram_entry_free(zram, entry);
-
        atomic64_sub(zram_get_obj_size(zram, index),
                        &zram->stats.compr_data_size);
-       atomic64_dec(&zram->stats.pages_stored);
+out:
+       zram_entry_free(zram, entry);
 
+       atomic64_dec(&zram->stats.pages_stored);
        zram_set_entry(zram, index, NULL);
        zram_set_obj_size(zram, index, 0);
 }
@@ -794,7 +801,15 @@ static int __zram_bvec_write(struct zram *zram, struct 
bio_vec *bvec, u32 index)
        entry = zram_dedup_find(zram, page, &checksum);
        if (entry) {
                comp_len = entry->len;
-               goto found_dup;
+               zram_slot_lock(zram, index);
+               zram_free_page(zram, index);
+               zram_set_flag(zram, index, ZRAM_DUP);
+               zram_set_entry(zram, index, entry);
+               zram_set_obj_size(zram, index, comp_len);
+               zram_slot_unlock(zram, index);
+               atomic64_add(comp_len, &zram->stats.dup_data_size);
+               atomic64_inc(&zram->stats.pages_stored);
+               return 0;
        }
 
        zstrm = zcomp_stream_get(zram->comp);
@@ -818,7 +833,6 @@ static int __zram_bvec_write(struct zram *zram, struct 
bio_vec *bvec, u32 index)
        zs_unmap_object(zram->mem_pool, zram_entry_handle(zram, entry));
        zram_dedup_insert(zram, entry, checksum);
 
-found_dup:
        /*
         * Free memory associated with this sector
         * before overwriting unused sectors.
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index 0091e23873c1..8ccfdcd8f674 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -64,6 +64,7 @@ static const size_t max_zpage_size = PAGE_SIZE / 4 * 3;
 enum zram_pageflags {
        /* Page consists entirely of zeros */
        ZRAM_SAME = ZRAM_FLAG_SHIFT,
+       ZRAM_DUP,
        ZRAM_ACCESS,    /* page is now accessed */
 
        __NR_ZRAM_PAGEFLAGS,
-- 
2.7.4

Reply via email to