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