This patch adds support for guest-side cleancache. This is the part which 
communicates
with the host regarding cleancache TMEM actions.

Signed-off-by: Sasha Levin <[email protected]>
---
 arch/x86/kvm/tmem/Kconfig      |    9 +++
 arch/x86/kvm/tmem/Makefile     |    1 +
 arch/x86/kvm/tmem/cleancache.c |  120 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 130 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/kvm/tmem/cleancache.c

diff --git a/arch/x86/kvm/tmem/Kconfig b/arch/x86/kvm/tmem/Kconfig
index 85ec25b..4734db2 100644
--- a/arch/x86/kvm/tmem/Kconfig
+++ b/arch/x86/kvm/tmem/Kconfig
@@ -22,4 +22,13 @@ config KVM_TMEM_HOST
 config KVM_TMEM_GUEST
        bool
 
+config KVM_TMEM_GUEST_CLEANCACHE
+       bool "Guest-side cleancache support"
+       depends on CLEANCACHE
+       select KVM_TMEM_GUEST
+       ---help---
+       This options enables guest to use cleanswap with the KVM host acting
+       as the TMEM target, which means that cleanswap may be used across
+       VMs (and even hosts).
+
 endif # KVM_TMEM
diff --git a/arch/x86/kvm/tmem/Makefile b/arch/x86/kvm/tmem/Makefile
index 1b15e20..b972c2b 100644
--- a/arch/x86/kvm/tmem/Makefile
+++ b/arch/x86/kvm/tmem/Makefile
@@ -2,3 +2,4 @@ ccflags-y += -Idrivers/staging/zcache/
 
 obj-$(CONFIG_KVM_TMEM_HOST)                    += host.o
 obj-$(CONFIG_KVM_TMEM_GUEST)                   += guest.o
+obj-$(CONFIG_KVM_TMEM_GUEST_CLEANCACHE)                += cleancache.o
diff --git a/arch/x86/kvm/tmem/cleancache.c b/arch/x86/kvm/tmem/cleancache.c
new file mode 100644
index 0000000..97eee44
--- /dev/null
+++ b/arch/x86/kvm/tmem/cleancache.c
@@ -0,0 +1,120 @@
+/*
+ * KVM TMEM cleancache guest side interface
+ *
+ * Copyright (c) 2012 Sasha Levin
+ *
+ */
+
+#include <linux/cleancache.h>
+#include <linux/kvm_types.h>
+#include <linux/kvm_para.h>
+
+#include "tmem.h"
+#include "guest.h"
+
+#include <zcache.h>
+
+static void tmem_cleancache_put_page(int pool, struct cleancache_filekey key,
+                                       pgoff_t index, struct page *page)
+{
+       __u32 i = (__u32)index;
+       struct tmem_oid oid = *(struct tmem_oid *)&key;
+       unsigned long pfn = page_to_pfn(page);
+
+       if (pool < 0)
+               return;
+
+       kvm_tmem_put_page((__u32)pool, oid, i, pfn);
+}
+
+static int tmem_cleancache_get_page(int pool, struct cleancache_filekey key,
+                                       pgoff_t index, struct page *page)
+{
+       __u32 i = (__u32)index;
+       struct tmem_oid oid = *(struct tmem_oid *)&key;
+       unsigned long pfn = page_to_pfn(page);
+
+       if (pool < 0)
+               return -1;
+
+       return kvm_tmem_get_page((__u32)pool, oid, i, pfn);
+}
+
+static void tmem_cleancache_flush_page(int pool, struct cleancache_filekey key,
+                                       pgoff_t index)
+{
+       __u32 i = (__u32)index;
+       struct tmem_oid oid = *(struct tmem_oid *)&key;
+
+       if (pool < 0)
+               return;
+
+       kvm_tmem_flush_page((__u32)pool, oid, i);
+}
+
+static void tmem_cleancache_flush_inode(int pool, struct cleancache_filekey 
key)
+{
+       struct tmem_oid oid = *(struct tmem_oid *)&key;
+
+       if (pool < 0)
+               return;
+
+       kvm_tmem_flush_object((__u32)pool, oid);
+}
+
+static void tmem_cleancache_flush_fs(int pool)
+{
+       if (pool < 0)
+               return;
+
+       kvm_tmem_destroy_pool((__u32)pool);
+}
+
+static int tmem_cleancache_init_fs(size_t pagesize)
+{
+       return kvm_tmem_new_pool(KVM_CLIENT, 0, pagesize);
+}
+
+static int tmem_cleancache_init_shared_fs(char *uuid, size_t pagesize)
+{
+       return kvm_tmem_new_pool(KVM_CLIENT, TMEM_POOL_SHARED, pagesize);
+}
+
+static int use_kvmcleancache = 1;
+
+static int __init no_kvmcleancache(char *s)
+{
+       use_kvmcleancache = 0;
+       return 1;
+}
+
+__setup("nokvmcleancache", no_kvmcleancache);
+
+static struct cleancache_ops tmem_cleancache_ops = {
+       .put_page = tmem_cleancache_put_page,
+       .get_page = tmem_cleancache_get_page,
+       .invalidate_page = tmem_cleancache_flush_page,
+       .invalidate_inode = tmem_cleancache_flush_inode,
+       .invalidate_fs = tmem_cleancache_flush_fs,
+       .init_shared_fs = tmem_cleancache_init_shared_fs,
+       .init_fs = tmem_cleancache_init_fs
+};
+
+static int __init kvm_tmem_cleancache_init(void)
+{
+       struct cleancache_ops old_ops;
+
+       BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid));
+
+       if (!use_kvmcleancache || !kvm_para_available())
+               return 0;
+
+       old_ops = cleancache_register_ops(&tmem_cleancache_ops);
+
+       printk(KERN_INFO "cleancache enabled, RAM provided by KVM TMEM %s\n",
+               old_ops.init_fs?" (WARNING: cleancache_ops overridden)":"");
+
+       return 0;
+}
+
+module_init(kvm_tmem_cleancache_init)
-- 
1.7.8.6

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to