From c129ef6d0f76a809b0a96fd52b9509856722e74b Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 19 Jul 2012 18:51:22 -0400 Subject: mm: frontswap: remove unneeded headers Signed-off-by: Sasha Levin [v1: Rebased with tracing removed] Signed-off-by: Konrad Rzeszutek Wilk diff --git a/mm/frontswap.c b/mm/frontswap.c index 7fb9538..5318b3a 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -11,15 +11,11 @@ * This work is licensed under the terms of the GNU GPL, version 2. */ -#include #include #include #include -#include #include -#include #include -#include #include #include #include -- cgit v0.10.2 From 88610238d9a0a5998c4deba201332dd1e35b4199 Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Sat, 16 Jun 2012 20:37:48 +0800 Subject: mm/frontswap: cleanup doc and comment error Signed-off-by: Wanpeng Li Signed-off-by: Konrad Rzeszutek Wilk diff --git a/Documentation/vm/frontswap.txt b/Documentation/vm/frontswap.txt index 37067cf..5ef2d13 100644 --- a/Documentation/vm/frontswap.txt +++ b/Documentation/vm/frontswap.txt @@ -25,7 +25,7 @@ with the specified swap device number (aka "type"). A "store" will copy the page to transcendent memory and associate it with the type and offset associated with the page. A "load" will copy the page, if found, from transcendent memory into kernel memory, but will NOT remove the page -from from transcendent memory. An "invalidate_page" will remove the page +from transcendent memory. An "invalidate_page" will remove the page from transcendent memory and an "invalidate_area" will remove ALL pages associated with the swap type (e.g., like swapoff) and notify the "device" to refuse further stores with that swap type. @@ -99,7 +99,7 @@ server configured with a large amount of RAM... without pre-configuring how much of the RAM is available for each of the clients! In the virtual case, the whole point of virtualization is to statistically -multiplex physical resources acrosst the varying demands of multiple +multiplex physical resources across the varying demands of multiple virtual machines. This is really hard to do with RAM and efforts to do it well with no kernel changes have essentially failed (except in some well-publicized special-case workloads). diff --git a/mm/frontswap.c b/mm/frontswap.c index 5318b3a..6b3e71a 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -120,7 +120,7 @@ static inline void __frontswap_clear(struct swap_info_struct *sis, pgoff_t offse * "Store" data from a page to frontswap and associate it with the page's * swaptype and offset. Page must be locked and in the swap cache. * If frontswap already contains a page with matching swaptype and - * offset, the frontswap implmentation may either overwrite the data and + * offset, the frontswap implementation may either overwrite the data and * return success or invalidate the page from frontswap and return failure. */ int __frontswap_store(struct page *page) -- cgit v0.10.2 From 6b982fcf0260b8371604fcf6a12c6beecb731c57 Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Mon, 30 Jul 2012 14:47:44 -0500 Subject: mm/frontswap: fix uninit'ed variable warning Fixes uninitialized variable warning on 'type' in frontswap_shrink(). type is set before use by __frontswap_unuse_pages() called by __frontswap_shrink() called by frontswap_shrink() before use by try_to_unuse(). Signed-off-by: Seth Jennings Signed-off-by: Konrad Rzeszutek Wilk diff --git a/mm/frontswap.c b/mm/frontswap.c index 6b3e71a..89dc399 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -292,7 +292,7 @@ static int __frontswap_shrink(unsigned long target_pages, void frontswap_shrink(unsigned long target_pages) { unsigned long pages_to_unuse = 0; - int type, ret; + int uninitialized_var(type), ret; /* * we don't want to hold swap_lock while doing a very -- cgit v0.10.2 From a00bb1e9fc0925c0061e9d844523a3a47a7e2f7f Mon Sep 17 00:00:00 2001 From: Zhenzhong Duan Date: Fri, 21 Sep 2012 16:40:30 +0800 Subject: mm: frontswap: fix a wrong if condition in frontswap_shrink pages_to_unuse is set to 0 to unuse all frontswap pages But that doesn't happen since a wrong condition in frontswap_shrink cancel it. -v2: Add comment to explain return value of __frontswap_shrink, as suggested by Dan Carpenter, thanks Signed-off-by: Zhenzhong Duan Signed-off-by: Konrad Rzeszutek Wilk diff --git a/mm/frontswap.c b/mm/frontswap.c index 89dc399..0547a35 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -263,6 +263,11 @@ static int __frontswap_unuse_pages(unsigned long total, unsigned long *unused, return ret; } +/* + * Used to check if it's necessory and feasible to unuse pages. + * Return 1 when nothing to do, 0 when need to shink pages, + * error code when there is an error. + */ static int __frontswap_shrink(unsigned long target_pages, unsigned long *pages_to_unuse, int *type) @@ -275,7 +280,7 @@ static int __frontswap_shrink(unsigned long target_pages, if (total_pages <= target_pages) { /* Nothing to do */ *pages_to_unuse = 0; - return 0; + return 1; } total_pages_to_unuse = total_pages - target_pages; return __frontswap_unuse_pages(total_pages_to_unuse, pages_to_unuse, type); @@ -302,7 +307,7 @@ void frontswap_shrink(unsigned long target_pages) spin_lock(&swap_lock); ret = __frontswap_shrink(target_pages, &pages_to_unuse, &type); spin_unlock(&swap_lock); - if (ret == 0 && pages_to_unuse) + if (ret == 0) try_to_unuse(type, true, pages_to_unuse); return; } -- cgit v0.10.2 From e3483a5f3a8ef448c229a2aceca9b2ad6a46b8ec Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Thu, 20 Sep 2012 12:16:52 -0700 Subject: frontswap: support exclusive gets if tmem backend is capable Tmem, as originally specified, assumes that "get" operations performed on persistent pools never flush the page of data out of tmem on a successful get, waiting instead for a flush operation. This is intended to mimic the model of a swap disk, where a disk read is non-destructive. Unlike a disk, however, freeing up the RAM can be valuable. Over the years that frontswap was in the review process, several reviewers (and notably Hugh Dickins in 2010) pointed out that this would result, at least temporarily, in two copies of the data in RAM: one (compressed for zcache) copy in tmem, and one copy in the swap cache. We wondered if this could be done differently, at least optionally. This patch allows tmem backends to instruct the frontswap code that this backend performs exclusive gets. Zcache2 already contains hooks to support this feature. Other backends are completely unaffected unless/until they are updated to support this feature. While it is not clear that exclusive gets are a performance win on all workloads at all times, this small patch allows for experimentation by backends. P.S. Let's not quibble about the naming of "get" vs "read" vs "load" etc. The naming is currently horribly inconsistent between cleancache and frontswap and existing tmem backends, so will need to be straightened out as a separate patch. "Get" is used by the tmem architecture spec, existing backends, and all documentation and presentation material so I am using it in this patch. Signed-off-by: Dan Magenheimer Signed-off-by: Konrad Rzeszutek Wilk diff --git a/include/linux/frontswap.h b/include/linux/frontswap.h index 0e4e2ee..3044254 100644 --- a/include/linux/frontswap.h +++ b/include/linux/frontswap.h @@ -19,6 +19,8 @@ extern struct frontswap_ops extern void frontswap_shrink(unsigned long); extern unsigned long frontswap_curr_pages(void); extern void frontswap_writethrough(bool); +#define FRONTSWAP_HAS_EXCLUSIVE_GETS +extern void frontswap_tmem_exclusive_gets(bool); extern void __frontswap_init(unsigned type); extern int __frontswap_store(struct page *page); diff --git a/mm/frontswap.c b/mm/frontswap.c index 0547a35..2890e67 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -44,6 +44,13 @@ EXPORT_SYMBOL(frontswap_enabled); */ static bool frontswap_writethrough_enabled __read_mostly; +/* + * If enabled, the underlying tmem implementation is capable of doing + * exclusive gets, so frontswap_load, on a successful tmem_get must + * mark the page as no longer in frontswap AND mark it dirty. + */ +static bool frontswap_tmem_exclusive_gets_enabled __read_mostly; + #ifdef CONFIG_DEBUG_FS /* * Counters available via /sys/kernel/debug/frontswap (if debugfs is @@ -97,6 +104,15 @@ void frontswap_writethrough(bool enable) EXPORT_SYMBOL(frontswap_writethrough); /* + * Enable/disable frontswap exclusive gets (see above). + */ +void frontswap_tmem_exclusive_gets(bool enable) +{ + frontswap_tmem_exclusive_gets_enabled = enable; +} +EXPORT_SYMBOL(frontswap_tmem_exclusive_gets); + +/* * Called when a swap device is swapon'd. */ void __frontswap_init(unsigned type) @@ -174,8 +190,13 @@ int __frontswap_load(struct page *page) BUG_ON(sis == NULL); if (frontswap_test(sis, offset)) ret = frontswap_ops.load(type, offset, page); - if (ret == 0) + if (ret == 0) { inc_frontswap_loads(); + if (frontswap_tmem_exclusive_gets_enabled) { + SetPageDirty(page); + frontswap_clear(sis, offset); + } + } return ret; } EXPORT_SYMBOL(__frontswap_load); -- cgit v0.10.2