Skip to content
This repository has been archived by the owner on Feb 11, 2024. It is now read-only.

Commit

Permalink
zram: Do not subtract deduplicated data from compressed size when fre…
Browse files Browse the repository at this point in the history
…eing pages

In the function __zram_bvec_write, when we match that the checksum of the
current data is already in the list, we will skip the compression operation
and allocate the zram entry directly, and will not calculate the size of the
duplicate data in the storage page compression size .

In the function zram_free_page, the deduplicated data size is directly
subtracted from the stored page compression size indiscriminately, which will
inevitably lead to statistical errors, and compr_data_size will continue to
decrease, so that it will be less than 0 after a period of time. The data is
written into the structure of u64, causing the data to exceed the value.

Therefore, we add a flag to record which pages have been deduplicated, and no
longer subtract the size of these pages from compr_data_size when freeing pages.

Change-Id: Idedf4b7ddd5e2f6afb5dde8a2f8c55c4b1aec481
  • Loading branch information
Mandi-Sa authored and YumeMichi committed Nov 3, 2023
1 parent 215309b commit edf528a
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions drivers/block/zram/zram_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1283,14 +1283,16 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize)
static void zram_free_page(struct zram *zram, size_t index)
{
struct zram_entry *entry;
bool is_deduped;

#ifdef CONFIG_ZRAM_MEMORY_TRACKING
zram->table[index].ac_time = 0;
#endif
if (zram_test_flag(zram, index, ZRAM_IDLE))
zram_clear_flag(zram, index, ZRAM_IDLE);

if (zram_test_flag(zram, index, ZRAM_DEDUPED))
is_deduped = zram_test_flag(zram, index, ZRAM_DEDUPED);
if (is_deduped)
zram_clear_flag(zram, index, ZRAM_DEDUPED);

if (zram_test_flag(zram, index, ZRAM_HUGE)) {
Expand Down Expand Up @@ -1320,8 +1322,9 @@ static void zram_free_page(struct zram *zram, size_t index)

zram_entry_free(zram, entry);

atomic64_sub(zram_get_obj_size(zram, index),
&zram->stats.compr_data_size);
if (!is_deduped)
atomic64_sub(zram_get_obj_size(zram, index),
&zram->stats.compr_data_size);
out:
atomic64_dec(&zram->stats.pages_stored);
zram_set_entry(zram, index, NULL);
Expand Down

0 comments on commit edf528a

Please sign in to comment.