diff options
-rw-r--r-- | include/linux/frontswap.h | 2 | ||||
-rw-r--r-- | mm/frontswap.c | 23 |
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 | |||
19 | extern void frontswap_shrink(unsigned long); | 19 | extern void frontswap_shrink(unsigned long); |
20 | extern unsigned long frontswap_curr_pages(void); | 20 | extern unsigned long frontswap_curr_pages(void); |
21 | extern void frontswap_writethrough(bool); | 21 | extern void frontswap_writethrough(bool); |
22 | #define FRONTSWAP_HAS_EXCLUSIVE_GETS | ||
23 | extern void frontswap_tmem_exclusive_gets(bool); | ||
22 | 24 | ||
23 | extern void __frontswap_init(unsigned type); | 25 | extern void __frontswap_init(unsigned type); |
24 | extern int __frontswap_store(struct page *page); | 26 | extern 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 | */ |
45 | static bool frontswap_writethrough_enabled __read_mostly; | 45 | static 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 | */ | ||
52 | static 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) | |||
97 | EXPORT_SYMBOL(frontswap_writethrough); | 104 | EXPORT_SYMBOL(frontswap_writethrough); |
98 | 105 | ||
99 | /* | 106 | /* |
107 | * Enable/disable frontswap exclusive gets (see above). | ||
108 | */ | ||
109 | void frontswap_tmem_exclusive_gets(bool enable) | ||
110 | { | ||
111 | frontswap_tmem_exclusive_gets_enabled = enable; | ||
112 | } | ||
113 | EXPORT_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 | */ |
102 | void __frontswap_init(unsigned type) | 118 | void __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 | } |
181 | EXPORT_SYMBOL(__frontswap_load); | 202 | EXPORT_SYMBOL(__frontswap_load); |