[RFC 09/10] KVM: support guest side cleancache

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <levinsasha928@xxxxxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux