8 #include <linux/kernel.h>
9 #include <linux/types.h>
15 #ifdef CONFIG_FRONTSWAP
21 #include <asm/xen/hypercall.h>
22 #include <asm/xen/page.h>
23 #include <asm/xen/hypervisor.h>
26 #define TMEM_CONTROL 0
27 #define TMEM_NEW_POOL 1
28 #define TMEM_DESTROY_POOL 2
29 #define TMEM_NEW_PAGE 3
30 #define TMEM_PUT_PAGE 4
31 #define TMEM_GET_PAGE 5
32 #define TMEM_FLUSH_PAGE 6
33 #define TMEM_FLUSH_OBJECT 7
39 #define TMEM_POOL_PERSIST 1
40 #define TMEM_POOL_SHARED 2
41 #define TMEM_POOL_PAGESIZE_SHIFT 4
42 #define TMEM_VERSION_SHIFT 24
54 #define TMEM_POOL_PRIVATE_UUID { 0, 0 }
57 #define TMEM_POOL_PERSIST 1
58 #define TMEM_POOL_SHARED 2
78 rc = HYPERVISOR_tmem_op(&op);
86 int rc = 0, pageshift;
88 for (pageshift = 0; pagesize != 1; pageshift++)
96 rc = HYPERVISOR_tmem_op(&
op);
111 static int xen_tmem_get_page(
u32 pool_id,
struct tmem_oid oid,
112 u32 index,
unsigned long pfn)
120 static int xen_tmem_flush_page(
u32 pool_id,
struct tmem_oid oid,
u32 index)
126 static int xen_tmem_flush_object(
u32 pool_id,
struct tmem_oid oid)
133 static int __init enable_tmem(
char *
s)
140 #ifdef CONFIG_CLEANCACHE
141 static int xen_tmem_destroy_pool(
u32 pool_id)
166 pgoff_t index,
struct page *page)
178 ret = xen_tmem_get_page((
u32)pool, oid, ind, pfn);
207 static void tmem_cleancache_flush_fs(
int pool)
211 (
void)xen_tmem_destroy_pool((
u32)pool);
214 static int tmem_cleancache_init_fs(
size_t pagesize)
218 return xen_tmem_new_pool(uuid_private, 0, pagesize);
221 static int tmem_cleancache_init_shared_fs(
char *uuid,
size_t pagesize)
226 shared_uuid.uuid_hi = *(
u64 *)(&uuid[8]);
232 static int __init no_cleancache(
char *
s)
234 use_cleancache =
false;
237 __setup(
"nocleancache", no_cleancache);
240 .put_page = tmem_cleancache_put_page,
241 .get_page = tmem_cleancache_get_page,
242 .invalidate_page = tmem_cleancache_flush_page,
243 .invalidate_inode = tmem_cleancache_flush_inode,
244 .invalidate_fs = tmem_cleancache_flush_fs,
245 .init_shared_fs = tmem_cleancache_init_shared_fs,
246 .init_fs = tmem_cleancache_init_fs
250 #ifdef CONFIG_FRONTSWAP
254 static int tmem_frontswap_poolid;
261 #define SWIZ_MASK ((1 << SWIZ_BITS) - 1)
262 #define _oswiz(_type, _ind) ((_type << SWIZ_BITS) | (_ind & SWIZ_MASK))
263 #define iswiz(_ind) (_ind >> SWIZ_BITS)
279 int pool = tmem_frontswap_poolid;
287 ret = xen_tmem_put_page(pool, oswiz(type, ind),
iswiz(ind), pfn);
299 static int tmem_frontswap_load(
unsigned type,
pgoff_t offset,
305 int pool = tmem_frontswap_poolid;
312 ret = xen_tmem_get_page(pool, oswiz(type, ind),
iswiz(ind), pfn);
321 static void tmem_frontswap_flush_page(
unsigned type,
pgoff_t offset)
325 int pool = tmem_frontswap_poolid;
331 (
void) xen_tmem_flush_page(pool, oswiz(type, ind),
iswiz(ind));
335 static void tmem_frontswap_flush_area(
unsigned type)
337 int pool = tmem_frontswap_poolid;
343 (
void)xen_tmem_flush_object(pool, oswiz(type, ind));
346 static void tmem_frontswap_init(
unsigned ignored)
351 if (tmem_frontswap_poolid < 0)
352 tmem_frontswap_poolid =
358 static int __init no_frontswap(
char *
s)
360 use_frontswap =
false;
363 __setup(
"nofrontswap", no_frontswap);
366 .store = tmem_frontswap_store,
367 .load = tmem_frontswap_load,
368 .invalidate_page = tmem_frontswap_flush_page,
369 .invalidate_area = tmem_frontswap_flush_area,
370 .init = tmem_frontswap_init
374 static int __init xen_tmem_init(
void)
378 #ifdef CONFIG_FRONTSWAP
379 if (tmem_enabled && use_frontswap) {
384 tmem_frontswap_poolid = -1;
386 s =
" (WARNING: frontswap_ops overridden)";
388 "Xen Transcendent Memory\n");
391 #ifdef CONFIG_CLEANCACHE
393 if (tmem_enabled && use_cleancache) {
398 s =
" (WARNING: cleancache_ops overridden)";
400 "Xen Transcendent Memory%s\n", s);