aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/frontswap.h2
-rw-r--r--mm/frontswap.c23
2 files changed, 24 insertions, 1 deletions
diff --git a/include/linux/frontswap.h b/include/linux/frontswap.h
index 0e4e2eec5c1d..30442547b9e6 100644
--- a/include/linux/frontswap.h
+++ b/include/linux/frontswap.h
@@ -19,6 +19,8 @@ extern struct frontswap_ops
19extern void frontswap_shrink(unsigned long); 19extern void frontswap_shrink(unsigned long);
20extern unsigned long frontswap_curr_pages(void); 20extern unsigned long frontswap_curr_pages(void);
21extern void frontswap_writethrough(bool); 21extern void frontswap_writethrough(bool);
22#define FRONTSWAP_HAS_EXCLUSIVE_GETS
23extern void frontswap_tmem_exclusive_gets(bool);
22 24
23extern void __frontswap_init(unsigned type); 25extern void __frontswap_init(unsigned type);
24extern int __frontswap_store(struct page *page); 26extern int __frontswap_store(struct page *page);
diff --git a/mm/frontswap.c b/mm/frontswap.c
index 0547a35f798b..2890e67d6026 100644
--- a/mm/frontswap.c
+++ b/mm/frontswap.c
@@ -44,6 +44,13 @@ EXPORT_SYMBOL(frontswap_enabled);
44 */ 44 */
45static bool frontswap_writethrough_enabled __read_mostly; 45static bool frontswap_writethrough_enabled __read_mostly;
46 46
47/*
48 * If enabled, the underlying tmem implementation is capable of doing
49 * exclusive gets, so frontswap_load, on a successful tmem_get must
50 * mark the page as no longer in frontswap AND mark it dirty.
51 */
52static bool frontswap_tmem_exclusive_gets_enabled __read_mostly;
53
47#ifdef CONFIG_DEBUG_FS 54#ifdef CONFIG_DEBUG_FS
48/* 55/*
49 * Counters available via /sys/kernel/debug/frontswap (if debugfs is 56 * Counters available via /sys/kernel/debug/frontswap (if debugfs is
@@ -97,6 +104,15 @@ void frontswap_writethrough(bool enable)
97EXPORT_SYMBOL(frontswap_writethrough); 104EXPORT_SYMBOL(frontswap_writethrough);
98 105
99/* 106/*
107 * Enable/disable frontswap exclusive gets (see above).
108 */
109void frontswap_tmem_exclusive_gets(bool enable)
110{
111 frontswap_tmem_exclusive_gets_enabled = enable;
112}
113EXPORT_SYMBOL(frontswap_tmem_exclusive_gets);
114
115/*
100 * Called when a swap device is swapon'd. 116 * Called when a swap device is swapon'd.
101 */ 117 */
102void __frontswap_init(unsigned type) 118void __frontswap_init(unsigned type)
@@ -174,8 +190,13 @@ int __frontswap_load(struct page *page)
174 BUG_ON(sis == NULL); 190 BUG_ON(sis == NULL);
175 if (frontswap_test(sis, offset)) 191 if (frontswap_test(sis, offset))
176 ret = frontswap_ops.load(type, offset, page); 192 ret = frontswap_ops.load(type, offset, page);
177 if (ret == 0) 193 if (ret == 0) {
178 inc_frontswap_loads(); 194 inc_frontswap_loads();
195 if (frontswap_tmem_exclusive_gets_enabled) {
196 SetPageDirty(page);
197 frontswap_clear(sis, offset);
198 }
199 }
179 return ret; 200 return ret;
180} 201}
181EXPORT_SYMBOL(__frontswap_load); 202EXPORT_SYMBOL(__frontswap_load);