[PATCH 2/4] zswap: Enable or disable sharing of duplicate pages at runtime
From: Srividya Desireddy
Date: Wed Aug 17 2016 - 06:27:46 EST
From: Srividya Desireddy <srividya.dr@xxxxxxxxxxx>
Date: Wed, 17 Aug 2016 14:32:24 +0530
Subject: [PATCH 2/4] zswap: Enable or disable sharing of duplicate pages at
runtime
Enable or disable the sharing of duplicate zswap pages at runtime.
To enable sharing of duplicate zswap pages set 'same_page_sharing' sysfs
attribute. By default it is disabled.
In zswap_frontswap_store(), duplicate pages are searched in zswap only
when same_page_sharing is set. When zswap same page sharing is
disabled at runtime it will stop sharing the new duplicate pages. However,
the existing duplicate pages will keep sharing the compressed memory pool
until they are faulted back or invalidated.
Signed-off-by: Srividya Desireddy <srividya.dr@xxxxxxxxxxx>
---
mm/zswap.c | 42 +++++++++++++++++++++++++-----------------
1 file changed, 25 insertions(+), 17 deletions(-)
diff --git a/mm/zswap.c b/mm/zswap.c
index f7efede..ae39c77 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -116,6 +116,10 @@ module_param_cb(zpool, &zswap_zpool_param_ops, &zswap_zpool_type, 0644);
static unsigned int zswap_max_pool_percent = 20;
module_param_named(max_pool_percent, zswap_max_pool_percent, uint, 0644);
+/* Enable/disable zswap same page sharing feature (disabled by default) */
+static bool zswap_same_page_sharing;
+module_param_named(same_page_sharing, zswap_same_page_sharing, bool, 0644);
+
/*********************************
* data structures
**********************************/
@@ -1180,20 +1184,22 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
src = kmap_atomic(page);
- checksum = jhash2((const u32 *)src, PAGE_SIZE / 4, 17);
- spin_lock(&tree->lock);
- zhandle = zswap_same_page_search(tree, src, checksum);
- if (zhandle) {
- entry->offset = offset;
- entry->zhandle = zhandle;
- entry->pool = zhandle->pool;
- entry->zhandle->ref_count++;
+ if (zswap_same_page_sharing) {
+ checksum = jhash2((const u32 *)src, PAGE_SIZE / 4, 17);
+ spin_lock(&tree->lock);
+ zhandle = zswap_same_page_search(tree, src, checksum);
+ if (zhandle) {
+ entry->offset = offset;
+ entry->zhandle = zhandle;
+ entry->pool = zhandle->pool;
+ entry->zhandle->ref_count++;
+ spin_unlock(&tree->lock);
+ kunmap_atomic(src);
+ atomic_inc(&zswap_duplicate_pages);
+ goto insert_entry;
+ }
spin_unlock(&tree->lock);
- kunmap_atomic(src);
- atomic_inc(&zswap_duplicate_pages);
- goto insert_entry;
}
- spin_unlock(&tree->lock);
/* if entry is successfully added, it keeps the reference */
entry->pool = zswap_pool_current_get();
@@ -1245,12 +1251,14 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
entry->zhandle = zhandle;
entry->zhandle->handle = handle;
entry->zhandle->length = dlen;
- entry->zhandle->checksum = checksum;
- entry->zhandle->pool = entry->pool;
- spin_lock(&tree->lock);
- ret = zswap_handle_rb_insert(&tree->zhandleroot, entry->zhandle,
+ if (zswap_same_page_sharing) {
+ entry->zhandle->checksum = checksum;
+ entry->zhandle->pool = entry->pool;
+ spin_lock(&tree->lock);
+ ret = zswap_handle_rb_insert(&tree->zhandleroot, entry->zhandle,
&duphandle);
- spin_unlock(&tree->lock);
+ spin_unlock(&tree->lock);
+ }
insert_entry:
/* map */
--
1.7.9.5