diff mbox

[v5,6/7] KVM: Enabling guest page hinting via static key

Message ID 20171128200324.4432-7-nilal@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Nitesh Lal Nov. 28, 2017, 8:03 p.m. UTC
From: Nitesh Narayan Lal <nilal@redhat.com>

This patch enables the guest page hinting support
to enable or disable based on the STATIC key which
could be set via sysctl.

Signed-off-by: Nitesh Narayan Lal <nilal@redhat.com>
---
 drivers/virtio/virtio_balloon.c | 15 ++++++++++-----
 include/linux/gfp.h             | 16 ++++++++++++++--
 include/linux/page_hinting.h    |  7 +++++++
 kernel/sysctl.c                 |  9 +++++++++
 virt/kvm/page_hinting.c         | 29 +++++++++++++++++++++++++----
 5 files changed, 65 insertions(+), 11 deletions(-)

Comments

kernel test robot Nov. 29, 2017, 1:01 p.m. UTC | #1
Hi Nitesh,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on kvm/linux-next]
[also build test ERROR on v4.15-rc1 next-20171128]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/nilal-redhat-com/KVM-Guest-page-hinting/20171129-180331
base:   https://git.kernel.org/pub/scm/virt/kvm/kvm.git linux-next
config: powerpc-allyesconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=powerpc 

All errors (new ones prefixed by >>):

   In file included from include/linux/mm.h:10:0,
                    from include/linux/mman.h:5,
                    from arch/powerpc/kernel/asm-offsets.c:22:
>> include/linux/gfp.h:453:20: error: static declaration of 'arch_free_page' follows non-static declaration
    static inline void arch_free_page(struct page *page, int order)
                       ^~~~~~~~~~~~~~
   In file included from arch/powerpc/include/asm/book3s/64/mmu-hash.h:16:0,
                    from arch/powerpc/include/asm/book3s/64/mmu.h:30,
                    from arch/powerpc/include/asm/mmu.h:305,
                    from arch/powerpc/include/asm/lppaca.h:36,
                    from arch/powerpc/include/asm/paca.h:21,
                    from arch/powerpc/include/asm/current.h:16,
                    from include/linux/sched.h:12,
                    from arch/powerpc/kernel/asm-offsets.c:17:
   arch/powerpc/include/asm/page.h:325:6: note: previous declaration of 'arch_free_page' was here
    void arch_free_page(struct page *page, int order);
         ^~~~~~~~~~~~~~
   make[2]: *** [arch/powerpc/kernel/asm-offsets.s] Error 1
   make[2]: Target '__build' not remade because of errors.
   make[1]: *** [prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [sub-make] Error 2

vim +/arch_free_page +453 include/linux/gfp.h

   452	
 > 453	static inline void arch_free_page(struct page *page, int order)
   454	{
   455		if (!static_branch_unlikely(&guest_page_hinting_key))
   456			return;
   457		guest_free_page(page, order);
   458	}
   459	#endif
   460	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot Nov. 29, 2017, 3:45 p.m. UTC | #2
Hi Nitesh,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on kvm/linux-next]
[also build test ERROR on v4.15-rc1 next-20171128]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/nilal-redhat-com/KVM-Guest-page-hinting/20171129-180331
base:   https://git.kernel.org/pub/scm/virt/kvm/kvm.git linux-next
config: s390-allyesconfig (attached as .config)
compiler: s390x-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=s390 

All errors (new ones prefixed by >>):

   In file included from include/linux/mm.h:10:0,
                    from include/linux/kvm_host.h:17,
                    from arch/s390/kernel/asm-offsets.c:11:
>> include/linux/gfp.h:446:20: error: static declaration of 'arch_alloc_page' follows non-static declaration
    static inline void arch_alloc_page(struct page *page, int order)
                       ^~~~~~~~~~~~~~~
   In file included from arch/s390/include/asm/thread_info.h:24:0,
                    from include/linux/thread_info.h:38,
                    from arch/s390/include/asm/preempt.h:6,
                    from include/linux/preempt.h:81,
                    from include/linux/hardirq.h:5,
                    from include/linux/kvm_host.h:10,
                    from arch/s390/kernel/asm-offsets.c:11:
   arch/s390/include/asm/page.h:140:6: note: previous declaration of 'arch_alloc_page' was here
    void arch_alloc_page(struct page *page, int order);
         ^~~~~~~~~~~~~~~
   In file included from include/linux/mm.h:10:0,
                    from include/linux/kvm_host.h:17,
                    from arch/s390/kernel/asm-offsets.c:11:
   include/linux/gfp.h:453:20: error: static declaration of 'arch_free_page' follows non-static declaration
    static inline void arch_free_page(struct page *page, int order)
                       ^~~~~~~~~~~~~~
   In file included from arch/s390/include/asm/thread_info.h:24:0,
                    from include/linux/thread_info.h:38,
                    from arch/s390/include/asm/preempt.h:6,
                    from include/linux/preempt.h:81,
                    from include/linux/hardirq.h:5,
                    from include/linux/kvm_host.h:10,
                    from arch/s390/kernel/asm-offsets.c:11:
   arch/s390/include/asm/page.h:139:6: note: previous declaration of 'arch_free_page' was here
    void arch_free_page(struct page *page, int order);
         ^~~~~~~~~~~~~~
   make[2]: *** [arch/s390/kernel/asm-offsets.s] Error 1
   make[2]: Target '__build' not remade because of errors.
   make[1]: *** [prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [sub-make] Error 2

vim +/arch_alloc_page +446 include/linux/gfp.h

   442	
   443	#ifdef	CONFIG_KVM_FREE_PAGE_HINTING
   444	#define HAVE_ARCH_ALLOC_PAGE
   445	#define HAVE_ARCH_FREE_PAGE
 > 446	static inline void arch_alloc_page(struct page *page, int order)
   447	{
   448		if (!static_branch_unlikely(&guest_page_hinting_key))
   449			return;
   450		guest_alloc_page(page, order);
   451	}
   452	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox

Patch

diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index f9e25b7..17d6565 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -32,7 +32,6 @@ 
 #include <linux/mm.h>
 #include <linux/mount.h>
 #include <linux/magic.h>
-#include <linux/page_hinting.h>
 
 /*
  * Balloon device works in 4K page units.  So each page is pointed to by
@@ -124,6 +123,14 @@  static void hinting_ack(struct virtqueue *vq)
 
 	wake_up(&vb->acked);
 }
+
+static void enable_hinting(struct virtio_balloon *vb)
+{
+	guest_page_hinting_flag = 1;
+	static_branch_enable(&guest_page_hinting_key);
+	request_hypercall = (void *)&virtballoon_page_hinting;
+	balloon_ptr = vb;
+}
 #endif
 
 static u32 page_to_balloon_pfn(struct page *page)
@@ -642,10 +649,8 @@  static int virtballoon_probe(struct virtio_device *vdev)
 
 	virtio_device_ready(vdev);
 
-	if (virtio_has_feature(vb->vdev, VIRTIO_GUEST_PAGE_HINTING_VQ)) {
-		request_hypercall = (void *)&virtballoon_page_hinting;
-		balloon_ptr = vb;
-	}
+	if (virtio_has_feature(vb->vdev, VIRTIO_GUEST_PAGE_HINTING_VQ))
+		enable_hinting(vb);
 
 	if (towards_target(vb))
 		virtballoon_changed(vdev);
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index e02369b..2212e08 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -7,6 +7,7 @@ 
 #include <linux/stddef.h>
 #include <linux/linkage.h>
 #include <linux/topology.h>
+#include <linux/page_hinting.h>
 
 struct vm_area_struct;
 
@@ -442,8 +443,19 @@  static inline struct zonelist *node_zonelist(int nid, gfp_t flags)
 #ifdef	CONFIG_KVM_FREE_PAGE_HINTING
 #define HAVE_ARCH_ALLOC_PAGE
 #define HAVE_ARCH_FREE_PAGE
-void arch_free_page(struct page *page, int order);
-void arch_alloc_page(struct page *page, int order);
+static inline void arch_alloc_page(struct page *page, int order)
+{
+	if (!static_branch_unlikely(&guest_page_hinting_key))
+		return;
+	guest_alloc_page(page, order);
+}
+
+static inline void arch_free_page(struct page *page, int order)
+{
+	if (!static_branch_unlikely(&guest_page_hinting_key))
+		return;
+	guest_free_page(page, order);
+}
 #endif
 
 #ifndef HAVE_ARCH_FREE_PAGE
diff --git a/include/linux/page_hinting.h b/include/linux/page_hinting.h
index 0bfb646..dd30644 100644
--- a/include/linux/page_hinting.h
+++ b/include/linux/page_hinting.h
@@ -14,3 +14,10 @@  struct hypervisor_pages {
 extern struct hypervisor_pages hypervisor_pagelist[MAX_FGPT_ENTRIES];
 extern void (*request_hypercall)(void *, int);
 extern void *balloon_ptr;
+
+extern struct static_key_false guest_page_hinting_key;
+int guest_page_hinting_sysctl(struct ctl_table *table, int write,
+			      void __user *buffer, size_t *lenp, loff_t *ppos);
+extern int guest_page_hinting_flag;
+void guest_alloc_page(struct page *page, int order);
+void guest_free_page(struct page *page, int order);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 4a13a38..2effa94 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1654,6 +1654,15 @@  static struct ctl_table vm_table[] = {
 		.extra2		= (void *)&mmap_rnd_compat_bits_max,
 	},
 #endif
+#ifdef CONFIG_KVM_FREE_PAGE_HINTING
+	{
+		.procname	= "guest-page-hinting",
+		.data		= &guest_page_hinting_flag,
+		.maxlen		= sizeof(guest_page_hinting_flag),
+		.mode		= 0644,
+		.proc_handler   = guest_page_hinting_sysctl,
+	},
+#endif
 	{ }
 };
 
diff --git a/virt/kvm/page_hinting.c b/virt/kvm/page_hinting.c
index 22c892b..f66ad63 100644
--- a/virt/kvm/page_hinting.c
+++ b/virt/kvm/page_hinting.c
@@ -5,7 +5,6 @@ 
 #include <linux/sort.h>
 #include <linux/kernel.h>
 #include <trace/events/kmem.h>
-#include <linux/page_hinting.h>
 
 #define HYPERLIST_THRESHOLD	500
 /*
@@ -30,6 +29,29 @@  void (*request_hypercall)(void *, int);
 EXPORT_SYMBOL(request_hypercall);
 void *balloon_ptr;
 EXPORT_SYMBOL(balloon_ptr);
+struct static_key_false guest_page_hinting_key  = STATIC_KEY_FALSE_INIT;
+EXPORT_SYMBOL(guest_page_hinting_key);
+static DEFINE_MUTEX(hinting_mutex);
+int guest_page_hinting_flag;
+EXPORT_SYMBOL(guest_page_hinting_flag);
+
+int guest_page_hinting_sysctl(struct ctl_table *table, int write,
+			      void __user *buffer, size_t *lenp,
+			      loff_t *ppos)
+{
+	int ret;
+
+	mutex_lock(&hinting_mutex);
+
+	ret = proc_dointvec(table, write, buffer, lenp, ppos);
+
+	if (guest_page_hinting_flag)
+		static_key_enable(&guest_page_hinting_key.key);
+	else
+		static_key_disable(&guest_page_hinting_key.key);
+	mutex_unlock(&hinting_mutex);
+	return ret;
+}
 
 static void empty_hyperlist(void)
 {
@@ -254,7 +276,7 @@  void arch_free_page_slowpath(void)
 	write_sequnlock(&guest_page_lock);
 }
 
-void arch_alloc_page(struct page *page, int order)
+void guest_alloc_page(struct page *page, int order)
 {
 	unsigned int seq;
 
@@ -270,12 +292,11 @@  void arch_alloc_page(struct page *page, int order)
 	trace_guest_alloc_page(page, order);
 }
 
-void arch_free_page(struct page *page, int order)
+void guest_free_page(struct page *page, int order)
 {
 	int *free_page_idx = &get_cpu_var(kvm_pt_idx);
 	struct kvm_free_pages *free_page_obj;
 	unsigned long flags;
-
 	/*
 	 * use of global variables may trigger a race condition between irq and
 	 * process context causing unwanted overwrites. This will be replaced