xen: allocate page for shared info page from low memory
Subsystems (2)
Juergen Gross
maintainerPATCH 1/1 xen: allocate page for shared info page from low memory
In a HVM guest the kernel allocates the page for mapping the shared info structure via extend_brk() today. This will lead to a drop of performance as the underlying EPT entry will have to be split up into 4kB entries as the single shared info page is located in hypervisor memory.
The issue has been detected by using the libmicro munmap test:
unmapping 8kB of memory was faster by nearly a factor of two when no pv interfaces were active in the HVM guest.
So instead of taking a page from memory which might be mapped via large EPT entries use a page which is already mapped via a 4kB EPT
entry: we can take a page from the first 1MB of memory as the video memory at 640kB disallows using larger EPT entries.
--- arch/x86/xen/enlighten_hvm.c | 31 ++++++++++++++++++++++++------- arch/x86/xen/enlighten_pv.c | 2 -- 2 files changed, 24 insertions(+), 9 deletions(-)
arch/x86/xen/enlighten_hvm.c +24 -7
@@ -1,5 +1,6 @@#include <linux/cpu.h> #include <linux/kexec.h> +#include <linux/memblock.h> #include <xen/features.h> #include <xen/events.h>
@@ -10,9 +11,11 @@#include <asm/reboot.h> #include <asm/setup.h> #include <asm/hypervisor.h> +#include <asm/e820/api.h> #include <asm/xen/cpuid.h> #include <asm/xen/hypervisor.h> +#include <asm/xen/page.h> #include "xen-ops.h" #include "mmu.h"
@@ -22,20 +25,34 @@ void __ref xen_hvm_init_shared_info(void) {int cpu;struct xen_add_to_physmap xatp; -static struct shared_info *shared_info_page; +u64 pa; + +if (HYPERVISOR_shared_info == &xen_dummy_shared_info) { +/* +* Search for a free page starting at 4kB physical address. +* Low memory is preferred to avoid an EPT large page split up +* by the mapping. +* Starting below X86_RESERVE_LOW (usually 64kB) is fine as +* the BIOS used for HVM guests is well behaved and won't +* clobber memory other than the first 4kB. +*/ +for (pa =PAGE_SIZE ; + !e820__mapped_all (pa, pa +PAGE_SIZE ,E820_TYPE_RAM ) || +memblock_is_reserved (pa); + pa +=PAGE_SIZE ) + ; + +memblock_reserve (pa,PAGE_SIZE ); + HYPERVISOR_shared_info =__va (pa); + } -if (!shared_info_page) - shared_info_page = (struct shared_info *) -extend_brk (PAGE_SIZE ,PAGE_SIZE ); xatp.domid =DOMID_SELF ; xatp.idx =0 ; xatp.space = XENMAPSPACE_shared_info; - xatp.gpfn =__pa (shared_info_page) >>PAGE_SHIFT ; + xatp.gpfn =virt_to_pfn (HYPERVISOR_shared_info);if (HYPERVISOR_memory_op (XENMEM_add_to_physmap, &xatp))BUG (); - HYPERVISOR_shared_info = (struct shared_info *)shared_info_page; -/* xen_vcpu is a pointer to the vcpu_info struct in the shared_info * page, we use it in the event channel upcall and in some pvclock * related functions. We don't need the vcpu_info placement
arch/x86/xen/enlighten_pv.c +0 -2
@@ -89,8 +89,6 @@void *xen_initial_gdt; -RESERVE_BRK (shared_info_page_brk,PAGE_SIZE ); -static int xen_cpu_up_prepare_pv (unsigned int cpu);static int xen_cpu_dead_pv (unsigned int cpu);
Signature · 1 line
2.12.3
Boris Ostrovsky
reviewerQuoted 55 lines · Juergen Gross
In a HVM guest the kernel allocates the page for mapping the shared info structure via
extend_brk()today. This will lead to a drop of performance as the underlying EPT entry will have to be split up into 4kB entries as the single shared info page is located in hypervisor memory.The issue has been detected by using the libmicro munmap test:
unmapping 8kB of memory was faster by nearly a factor of two when no pv interfaces were active in the HVM guest.So instead of taking a page from memory which might be mapped via large EPT entries use a page which is already mapped via a 4kB EPT
entry: we can take a page from the first 1MB of memory as the video memory at 640kB disallows using larger EPT entries.Signed-off-by Juergen Gross <[email protected]>--- arch/x86/xen/enlighten_hvm.c | 31 ++++++++++++++++++++++++------- arch/x86/xen/enlighten_pv.c | 2 -- 2 files changed, 24 insertions(+), 9 deletions(-)arch/x86/xen/enlighten_hvm.c +9
-1@@ -1,5 +1,6 @@#include <linux/cpu.h> #include <linux/kexec.h> +#include <linux/memblock.h> #include <xen/features.h> #include <xen/events.h> @@ -10,9 +11,11 @@#include <asm/reboot.h> #include <asm/setup.h> #include <asm/hypervisor.h> +#include <asm/e820/api.h> #include <asm/xen/cpuid.h> #include <asm/xen/hypervisor.h> +#include <asm/xen/page.h> #include "xen-ops.h" #include "mmu.h" @@ -22,20 +25,34 @@ void __ref xen_hvm_init_shared_info(void) {int cpu;struct xen_add_to_physmap xatp; -static struct shared_info *shared_info_page; +u64 pa; + +if (HYPERVISOR_shared_info == &xen_dummy_shared_info) { +/* +* Search for a free page starting at 4kB physical address. +* Low memory is preferred to avoid an EPT large page split up
arch/x86/xen/enlighten_hvm.c void __ref xen_hvm_init_shared_info(void) · line 43
Quoted 10 lines
arch/x86/xen/enlighten_hvm.c +10
-0+* by the mapping. +* Starting below X86_RESERVE_LOW (usually 64kB) is fine as +* the BIOS used for HVM guests is well behaved and won't +* clobber memory other than the first 4kB. +*/ +for (pa =PAGE_SIZE ; + !e820__mapped_all (pa, pa +PAGE_SIZE ,E820_TYPE_RAM ) || +memblock_is_reserved (pa); + pa +=PAGE_SIZE ) + ;
Is it possible to never find a page here?
-boris
Quoted 26 lines
arch/x86/xen/enlighten_hvm.c +5
-6+ +memblock_reserve (pa,PAGE_SIZE ); + HYPERVISOR_shared_info =__va (pa); + } -if (!shared_info_page) - shared_info_page = (struct shared_info *) -extend_brk (PAGE_SIZE ,PAGE_SIZE ); xatp.domid =DOMID_SELF ; xatp.idx =0 ; xatp.space = XENMAPSPACE_shared_info; - xatp.gpfn =__pa (shared_info_page) >>PAGE_SHIFT ; + xatp.gpfn =virt_to_pfn (HYPERVISOR_shared_info);if (HYPERVISOR_memory_op (XENMEM_add_to_physmap, &xatp))BUG (); - HYPERVISOR_shared_info = (struct shared_info *)shared_info_page; -/* xen_vcpu is a pointer to the vcpu_info struct in the shared_info * page, we use it in the event channel upcall and in some pvclock * related functions. We don't need the vcpu_info placement arch/x86/xen/enlighten_pv.c +0
-0
arch/x86/xen/enlighten_pv.c line 94
Quoted 8 lines
arch/x86/xen/enlighten_pv.c +0
-2@@ -89,8 +89,6 @@void *xen_initial_gdt; -RESERVE_BRK (shared_info_page_brk,PAGE_SIZE ); -static int xen_cpu_up_prepare_pv (unsigned int cpu);static int xen_cpu_dead_pv (unsigned int cpu);
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xen.org/xen-devel
Boris Ostrovsky
reviewerQuoted 55 lines · Juergen Gross
In a HVM guest the kernel allocates the page for mapping the shared info structure via
extend_brk()today. This will lead to a drop of performance as the underlying EPT entry will have to be split up into 4kB entries as the single shared info page is located in hypervisor memory.The issue has been detected by using the libmicro munmap test:
unmapping 8kB of memory was faster by nearly a factor of two when no pv interfaces were active in the HVM guest.So instead of taking a page from memory which might be mapped via large EPT entries use a page which is already mapped via a 4kB EPT
entry: we can take a page from the first 1MB of memory as the video memory at 640kB disallows using larger EPT entries.Signed-off-by Juergen Gross <[email protected]>--- arch/x86/xen/enlighten_hvm.c | 31 ++++++++++++++++++++++++------- arch/x86/xen/enlighten_pv.c | 2 -- 2 files changed, 24 insertions(+), 9 deletions(-)arch/x86/xen/enlighten_hvm.c +9
-1@@ -1,5 +1,6 @@#include <linux/cpu.h> #include <linux/kexec.h> +#include <linux/memblock.h> #include <xen/features.h> #include <xen/events.h> @@ -10,9 +11,11 @@#include <asm/reboot.h> #include <asm/setup.h> #include <asm/hypervisor.h> +#include <asm/e820/api.h> #include <asm/xen/cpuid.h> #include <asm/xen/hypervisor.h> +#include <asm/xen/page.h> #include "xen-ops.h" #include "mmu.h" @@ -22,20 +25,34 @@ void __ref xen_hvm_init_shared_info(void) {int cpu;struct xen_add_to_physmap xatp; -static struct shared_info *shared_info_page; +u64 pa; + +if (HYPERVISOR_shared_info == &xen_dummy_shared_info) { +/* +* Search for a free page starting at 4kB physical address. +* Low memory is preferred to avoid an EPT large page split up
arch/x86/xen/enlighten_hvm.c void __ref xen_hvm_init_shared_info(void) · line 43
Quoted 10 lines
arch/x86/xen/enlighten_hvm.c +10
-0+* by the mapping. +* Starting below X86_RESERVE_LOW (usually 64kB) is fine as +* the BIOS used for HVM guests is well behaved and won't +* clobber memory other than the first 4kB. +*/ +for (pa =PAGE_SIZE ; + !e820__mapped_all (pa, pa +PAGE_SIZE ,E820_TYPE_RAM ) || +memblock_is_reserved (pa); + pa +=PAGE_SIZE ) + ;
Is it possible to never find a page here?
-boris
Quoted 34 lines
arch/x86/xen/enlighten_hvm.c +5
-6+ +memblock_reserve (pa,PAGE_SIZE ); + HYPERVISOR_shared_info =__va (pa); + } -if (!shared_info_page) - shared_info_page = (struct shared_info *) -extend_brk (PAGE_SIZE ,PAGE_SIZE ); xatp.domid =DOMID_SELF ; xatp.idx =0 ; xatp.space = XENMAPSPACE_shared_info; - xatp.gpfn =__pa (shared_info_page) >>PAGE_SHIFT ; + xatp.gpfn =virt_to_pfn (HYPERVISOR_shared_info);if (HYPERVISOR_memory_op (XENMEM_add_to_physmap, &xatp))BUG (); - HYPERVISOR_shared_info = (struct shared_info *)shared_info_page; -/* xen_vcpu is a pointer to the vcpu_info struct in the shared_info * page, we use it in the event channel upcall and in some pvclock * related functions. We don't need the vcpu_info placement arch/x86/xen/enlighten_pv.c +0
-2@@ -89,8 +89,6 @@void *xen_initial_gdt; -RESERVE_BRK (shared_info_page_brk,PAGE_SIZE ); -static int xen_cpu_up_prepare_pv (unsigned int cpu);static int xen_cpu_dead_pv (unsigned int cpu);
Juergen Gross
maintainerQuoted 60 lines · Boris Ostrovsky
Quoted 59 lines · Juergen Gross
In a HVM guest the kernel allocates the page for mapping the shared info structure via
extend_brk()today. This will lead to a drop of performance as the underlying EPT entry will have to be split up into 4kB entries as the single shared info page is located in hypervisor memory.The issue has been detected by using the libmicro munmap test:
unmapping 8kB of memory was faster by nearly a factor of two when no pv interfaces were active in the HVM guest.So instead of taking a page from memory which might be mapped via large EPT entries use a page which is already mapped via a 4kB EPT
entry: we can take a page from the first 1MB of memory as the video memory at 640kB disallows using larger EPT entries.Signed-off-by Juergen Gross <[email protected]>--- arch/x86/xen/enlighten_hvm.c | 31 ++++++++++++++++++++++++------- arch/x86/xen/enlighten_pv.c | 2 -- 2 files changed, 24 insertions(+), 9 deletions(-)arch/x86/xen/enlighten_hvm.c +13
-1@@ -1,5 +1,6 @@#include <linux/cpu.h> #include <linux/kexec.h> +#include <linux/memblock.h> #include <xen/features.h> #include <xen/events.h> @@ -10,9 +11,11 @@#include <asm/reboot.h> #include <asm/setup.h> #include <asm/hypervisor.h> +#include <asm/e820/api.h> #include <asm/xen/cpuid.h> #include <asm/xen/hypervisor.h> +#include <asm/xen/page.h> #include "xen-ops.h" #include "mmu.h" @@ -22,20 +25,34 @@ void __ref xen_hvm_init_shared_info(void) {int cpu;struct xen_add_to_physmap xatp; -static struct shared_info *shared_info_page; +u64 pa; + +if (HYPERVISOR_shared_info == &xen_dummy_shared_info) { +/* +* Search for a free page starting at 4kB physical address. +* Low memory is preferred to avoid an EPT large page split up +* by the mapping. +* Starting below X86_RESERVE_LOW (usually 64kB) is fine as +* the BIOS used for HVM guests is well behaved and won't +* clobber memory other than the first 4kB.
Quoted 8 lines
arch/x86/xen/enlighten_hvm.c void __ref xen_hvm_init_shared_info(void) · line 43
Quoted 6 lines
arch/x86/xen/enlighten_hvm.c +6
-0+*/ +for (pa =PAGE_SIZE ; + !e820__mapped_all (pa, pa +PAGE_SIZE ,E820_TYPE_RAM ) || +memblock_is_reserved (pa); + pa +=PAGE_SIZE ) + ;Is it possible to never find a page here?
Only if there is no memory available at all. :-)
TBH: I expect this to _always_ succeed at the first loop iteration.
Juergen
Quoted 68 lines · Juergen Gross
Quoted 59 lines · Boris Ostrovsky
Quoted 58 lines · Juergen Gross
In a HVM guest the kernel allocates the page for mapping the shared info structure via
extend_brk()today. This will lead to a drop of performance as the underlying EPT entry will have to be split up into 4kB entries as the single shared info page is located in hypervisor memory.The issue has been detected by using the libmicro munmap test:
unmapping 8kB of memory was faster by nearly a factor of two when no pv interfaces were active in the HVM guest.So instead of taking a page from memory which might be mapped via large EPT entries use a page which is already mapped via a 4kB EPT
entry: we can take a page from the first 1MB of memory as the video memory at 640kB disallows using larger EPT entries.Signed-off-by Juergen Gross <[email protected]>--- arch/x86/xen/enlighten_hvm.c | 31 ++++++++++++++++++++++++------- arch/x86/xen/enlighten_pv.c | 2 -- 2 files changed, 24 insertions(+), 9 deletions(-)arch/x86/xen/enlighten_hvm.c +12
-1@@ -1,5 +1,6 @@#include <linux/cpu.h> #include <linux/kexec.h> +#include <linux/memblock.h> #include <xen/features.h> #include <xen/events.h> @@ -10,9 +11,11 @@#include <asm/reboot.h> #include <asm/setup.h> #include <asm/hypervisor.h> +#include <asm/e820/api.h> #include <asm/xen/cpuid.h> #include <asm/xen/hypervisor.h> +#include <asm/xen/page.h> #include "xen-ops.h" #include "mmu.h" @@ -22,20 +25,34 @@ void __ref xen_hvm_init_shared_info(void) {int cpu;struct xen_add_to_physmap xatp; -static struct shared_info *shared_info_page; +u64 pa; + +if (HYPERVISOR_shared_info == &xen_dummy_shared_info) { +/* +* Search for a free page starting at 4kB physical address. +* Low memory is preferred to avoid an EPT large page split up +* by the mapping. +* Starting below X86_RESERVE_LOW (usually 64kB) is fine as +* the BIOS used for HVM guests is well behaved and won't Quoted 8 lines
arch/x86/xen/enlighten_hvm.c void __ref xen_hvm_init_shared_info(void) · line 43
Quoted 7 lines
arch/x86/xen/enlighten_hvm.c +7
-0+* clobber memory other than the first 4kB. +*/ +for (pa =PAGE_SIZE ; + !e820__mapped_all (pa, pa +PAGE_SIZE ,E820_TYPE_RAM ) || +memblock_is_reserved (pa); + pa +=PAGE_SIZE ) + ;Is it possible to never find a page here?
Quoted 3 lines
Only if there is no memory available at all. :-)
TBH: I expect this to _always_ succeed at the first loop iteration.
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xen.org/xen-devel
Quoted 68 lines · Juergen Gross
Quoted 59 lines · Boris Ostrovsky
Quoted 58 lines · Juergen Gross
In a HVM guest the kernel allocates the page for mapping the shared info structure via
extend_brk()today. This will lead to a drop of performance as the underlying EPT entry will have to be split up into 4kB entries as the single shared info page is located in hypervisor memory.The issue has been detected by using the libmicro munmap test:
unmapping 8kB of memory was faster by nearly a factor of two when no pv interfaces were active in the HVM guest.So instead of taking a page from memory which might be mapped via large EPT entries use a page which is already mapped via a 4kB EPT
entry: we can take a page from the first 1MB of memory as the video memory at 640kB disallows using larger EPT entries.Signed-off-by Juergen Gross <[email protected]>--- arch/x86/xen/enlighten_hvm.c | 31 ++++++++++++++++++++++++------- arch/x86/xen/enlighten_pv.c | 2 -- 2 files changed, 24 insertions(+), 9 deletions(-)arch/x86/xen/enlighten_hvm.c +12
-1@@ -1,5 +1,6 @@#include <linux/cpu.h> #include <linux/kexec.h> +#include <linux/memblock.h> #include <xen/features.h> #include <xen/events.h> @@ -10,9 +11,11 @@#include <asm/reboot.h> #include <asm/setup.h> #include <asm/hypervisor.h> +#include <asm/e820/api.h> #include <asm/xen/cpuid.h> #include <asm/xen/hypervisor.h> +#include <asm/xen/page.h> #include "xen-ops.h" #include "mmu.h" @@ -22,20 +25,34 @@ void __ref xen_hvm_init_shared_info(void) {int cpu;struct xen_add_to_physmap xatp; -static struct shared_info *shared_info_page; +u64 pa; + +if (HYPERVISOR_shared_info == &xen_dummy_shared_info) { +/* +* Search for a free page starting at 4kB physical address. +* Low memory is preferred to avoid an EPT large page split up +* by the mapping. +* Starting below X86_RESERVE_LOW (usually 64kB) is fine as +* the BIOS used for HVM guests is well behaved and won't Quoted 8 lines
arch/x86/xen/enlighten_hvm.c void __ref xen_hvm_init_shared_info(void) · line 43
Quoted 7 lines
arch/x86/xen/enlighten_hvm.c +7
-0+* clobber memory other than the first 4kB. +*/ +for (pa =PAGE_SIZE ; + !e820__mapped_all (pa, pa +PAGE_SIZE ,E820_TYPE_RAM ) || +memblock_is_reserved (pa); + pa +=PAGE_SIZE ) + ;Is it possible to never find a page here?
Quoted 3 lines
Only if there is no memory available at all. :-)
TBH: I expect this to _always_ succeed at the first loop iteration.
Boris Ostrovsky
reviewerQuoted 70 lines · Juergen Gross
Quoted 60 lines · Boris Ostrovsky
Quoted 59 lines · Juergen Gross
In a HVM guest the kernel allocates the page for mapping the shared info structure via
extend_brk()today. This will lead to a drop of performance as the underlying EPT entry will have to be split up into 4kB entries as the single shared info page is located in hypervisor memory.The issue has been detected by using the libmicro munmap test:
unmapping 8kB of memory was faster by nearly a factor of two when no pv interfaces were active in the HVM guest.So instead of taking a page from memory which might be mapped via large EPT entries use a page which is already mapped via a 4kB EPT
entry: we can take a page from the first 1MB of memory as the video memory at 640kB disallows using larger EPT entries.Signed-off-by Juergen Gross <[email protected]>--- arch/x86/xen/enlighten_hvm.c | 31 ++++++++++++++++++++++++------- arch/x86/xen/enlighten_pv.c | 2 -- 2 files changed, 24 insertions(+), 9 deletions(-)arch/x86/xen/enlighten_hvm.c +13
-1@@ -1,5 +1,6 @@#include <linux/cpu.h> #include <linux/kexec.h> +#include <linux/memblock.h> #include <xen/features.h> #include <xen/events.h> @@ -10,9 +11,11 @@#include <asm/reboot.h> #include <asm/setup.h> #include <asm/hypervisor.h> +#include <asm/e820/api.h> #include <asm/xen/cpuid.h> #include <asm/xen/hypervisor.h> +#include <asm/xen/page.h> #include "xen-ops.h" #include "mmu.h" @@ -22,20 +25,34 @@ void __ref xen_hvm_init_shared_info(void) {int cpu;struct xen_add_to_physmap xatp; -static struct shared_info *shared_info_page; +u64 pa; + +if (HYPERVISOR_shared_info == &xen_dummy_shared_info) { +/* +* Search for a free page starting at 4kB physical address. +* Low memory is preferred to avoid an EPT large page split up +* by the mapping. +* Starting below X86_RESERVE_LOW (usually 64kB) is fine as +* the BIOS used for HVM guests is well behaved and won't +* clobber memory other than the first 4kB. Quoted 8 lines
arch/x86/xen/enlighten_hvm.c void __ref xen_hvm_init_shared_info(void) · line 43
Quoted 6 lines
arch/x86/xen/enlighten_hvm.c +6
-0+*/ +for (pa =PAGE_SIZE ; + !e820__mapped_all (pa, pa +PAGE_SIZE ,E820_TYPE_RAM ) || +memblock_is_reserved (pa); + pa +=PAGE_SIZE ) + ;Is it possible to never find a page here?
Quoted 3 lines
Only if there is no memory available at all. :-)
TBH: I expect this to _always_ succeed at the first loop iteration.
This patch seems to break (64-bit only) guests on dumpdata here. No problems on other machines.
So far all I know is that we did get the first page (0x1000) but not much more. I will poke at this more on Monday.
-boris
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xen.org/xen-devel
Boris Ostrovsky
reviewerQuoted 70 lines · Juergen Gross
Quoted 60 lines · Boris Ostrovsky
Quoted 59 lines · Juergen Gross
In a HVM guest the kernel allocates the page for mapping the shared info structure via
extend_brk()today. This will lead to a drop of performance as the underlying EPT entry will have to be split up into 4kB entries as the single shared info page is located in hypervisor memory.The issue has been detected by using the libmicro munmap test:
unmapping 8kB of memory was faster by nearly a factor of two when no pv interfaces were active in the HVM guest.So instead of taking a page from memory which might be mapped via large EPT entries use a page which is already mapped via a 4kB EPT
entry: we can take a page from the first 1MB of memory as the video memory at 640kB disallows using larger EPT entries.Signed-off-by Juergen Gross <[email protected]>--- arch/x86/xen/enlighten_hvm.c | 31 ++++++++++++++++++++++++------- arch/x86/xen/enlighten_pv.c | 2 -- 2 files changed, 24 insertions(+), 9 deletions(-)arch/x86/xen/enlighten_hvm.c +13
-1@@ -1,5 +1,6 @@#include <linux/cpu.h> #include <linux/kexec.h> +#include <linux/memblock.h> #include <xen/features.h> #include <xen/events.h> @@ -10,9 +11,11 @@#include <asm/reboot.h> #include <asm/setup.h> #include <asm/hypervisor.h> +#include <asm/e820/api.h> #include <asm/xen/cpuid.h> #include <asm/xen/hypervisor.h> +#include <asm/xen/page.h> #include "xen-ops.h" #include "mmu.h" @@ -22,20 +25,34 @@ void __ref xen_hvm_init_shared_info(void) {int cpu;struct xen_add_to_physmap xatp; -static struct shared_info *shared_info_page; +u64 pa; + +if (HYPERVISOR_shared_info == &xen_dummy_shared_info) { +/* +* Search for a free page starting at 4kB physical address. +* Low memory is preferred to avoid an EPT large page split up +* by the mapping. +* Starting below X86_RESERVE_LOW (usually 64kB) is fine as +* the BIOS used for HVM guests is well behaved and won't +* clobber memory other than the first 4kB. Quoted 8 lines
arch/x86/xen/enlighten_hvm.c void __ref xen_hvm_init_shared_info(void) · line 43
Quoted 6 lines
arch/x86/xen/enlighten_hvm.c +6
-0+*/ +for (pa =PAGE_SIZE ; + !e820__mapped_all (pa, pa +PAGE_SIZE ,E820_TYPE_RAM ) || +memblock_is_reserved (pa); + pa +=PAGE_SIZE ) + ;Is it possible to never find a page here?
Quoted 3 lines
Only if there is no memory available at all. :-)
TBH: I expect this to _always_ succeed at the first loop iteration.
This patch seems to break (64-bit only) guests on dumpdata here. No problems on other machines.
So far all I know is that we did get the first page (0x1000) but not much more. I will poke at this more on Monday.
-boris
Boris Ostrovsky
reviewerQuoted 70 lines · Boris Ostrovsky
Quoted 67 lines · Juergen Gross
Quoted 65 lines · Boris Ostrovsky
Quoted 52 lines · Juergen Gross
In a HVM guest the kernel allocates the page for mapping the shared info structure via
extend_brk()today. This will lead to a drop of performance as the underlying EPT entry will have to be split up into 4kB entries as the single shared info page is located in hypervisor memory.The issue has been detected by using the libmicro munmap test:
unmapping 8kB of memory was faster by nearly a factor of two when no pv interfaces were active in the HVM guest.So instead of taking a page from memory which might be mapped via large EPT entries use a page which is already mapped via a 4kB EPT
entry: we can take a page from the first 1MB of memory as the video memory at 640kB disallows using larger EPT entries.Signed-off-by Juergen Gross <[email protected]>--- arch/x86/xen/enlighten_hvm.c | 31 ++++++++++++++++++++++++------- arch/x86/xen/enlighten_pv.c | 2 -- 2 files changed, 24 insertions(+), 9 deletions(-)arch/x86/xen/enlighten_hvm.c +9
-1@@ -1,5 +1,6 @@#include <linux/cpu.h> #include <linux/kexec.h> +#include <linux/memblock.h> #include <xen/features.h> #include <xen/events.h> @@ -10,9 +11,11 @@#include <asm/reboot.h> #include <asm/setup.h> #include <asm/hypervisor.h> +#include <asm/e820/api.h> #include <asm/xen/cpuid.h> #include <asm/xen/hypervisor.h> +#include <asm/xen/page.h> #include "xen-ops.h" #include "mmu.h" @@ -22,20 +25,34 @@ void __ref xen_hvm_init_shared_info(void) {int cpu;struct xen_add_to_physmap xatp; -static struct shared_info *shared_info_page; +u64 pa; + +if (HYPERVISOR_shared_info == &xen_dummy_shared_info) { +/* +* Search for a free page starting at 4kB physical address. +* Low memory is preferred to avoid an EPT large page split up arch/x86/xen/enlighten_hvm.c void __ref xen_hvm_init_shared_info(void) · line 43
Quoted 10 lines
arch/x86/xen/enlighten_hvm.c +10
-0+* by the mapping. +* Starting below X86_RESERVE_LOW (usually 64kB) is fine as +* the BIOS used for HVM guests is well behaved and won't +* clobber memory other than the first 4kB. +*/ +for (pa =PAGE_SIZE ; + !e820__mapped_all (pa, pa +PAGE_SIZE ,E820_TYPE_RAM ) || +memblock_is_reserved (pa); + pa +=PAGE_SIZE ) + ;Is it possible to never find a page here?
Quoted 7 lines
Quoted 3 lines
Only if there is no memory available at all. :-)
TBH: I expect this to _always_ succeed at the first loop iteration.
This patch seems to break (64-bit only) guests on dumpdata here. No problems on other machines.
So far all I know is that we did get the first page (
0x1000) but not much more. I will poke at this more on Monday.
So the problem is due to KASLR --- we can't use __va() before kernel_randomize_memory() is called since it will change __PAGE_OFFSET. (Setting CONFIG_RANDOMIZE_BASE will cause failure.)
-boris
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xen.org/xen-devel
Boris Ostrovsky
reviewerQuoted 70 lines · Boris Ostrovsky
Quoted 67 lines · Juergen Gross
Quoted 65 lines · Boris Ostrovsky
Quoted 52 lines · Juergen Gross
In a HVM guest the kernel allocates the page for mapping the shared info structure via
extend_brk()today. This will lead to a drop of performance as the underlying EPT entry will have to be split up into 4kB entries as the single shared info page is located in hypervisor memory.The issue has been detected by using the libmicro munmap test:
unmapping 8kB of memory was faster by nearly a factor of two when no pv interfaces were active in the HVM guest.So instead of taking a page from memory which might be mapped via large EPT entries use a page which is already mapped via a 4kB EPT
entry: we can take a page from the first 1MB of memory as the video memory at 640kB disallows using larger EPT entries.Signed-off-by Juergen Gross <[email protected]>--- arch/x86/xen/enlighten_hvm.c | 31 ++++++++++++++++++++++++------- arch/x86/xen/enlighten_pv.c | 2 -- 2 files changed, 24 insertions(+), 9 deletions(-)arch/x86/xen/enlighten_hvm.c +9
-1@@ -1,5 +1,6 @@#include <linux/cpu.h> #include <linux/kexec.h> +#include <linux/memblock.h> #include <xen/features.h> #include <xen/events.h> @@ -10,9 +11,11 @@#include <asm/reboot.h> #include <asm/setup.h> #include <asm/hypervisor.h> +#include <asm/e820/api.h> #include <asm/xen/cpuid.h> #include <asm/xen/hypervisor.h> +#include <asm/xen/page.h> #include "xen-ops.h" #include "mmu.h" @@ -22,20 +25,34 @@ void __ref xen_hvm_init_shared_info(void) {int cpu;struct xen_add_to_physmap xatp; -static struct shared_info *shared_info_page; +u64 pa; + +if (HYPERVISOR_shared_info == &xen_dummy_shared_info) { +/* +* Search for a free page starting at 4kB physical address. +* Low memory is preferred to avoid an EPT large page split up arch/x86/xen/enlighten_hvm.c void __ref xen_hvm_init_shared_info(void) · line 43
Quoted 10 lines
arch/x86/xen/enlighten_hvm.c +10
-0+* by the mapping. +* Starting below X86_RESERVE_LOW (usually 64kB) is fine as +* the BIOS used for HVM guests is well behaved and won't +* clobber memory other than the first 4kB. +*/ +for (pa =PAGE_SIZE ; + !e820__mapped_all (pa, pa +PAGE_SIZE ,E820_TYPE_RAM ) || +memblock_is_reserved (pa); + pa +=PAGE_SIZE ) + ;Is it possible to never find a page here?
Quoted 7 lines
Quoted 3 lines
Only if there is no memory available at all. :-)
TBH: I expect this to _always_ succeed at the first loop iteration.
This patch seems to break (64-bit only) guests on dumpdata here. No problems on other machines.
So far all I know is that we did get the first page (
0x1000) but not much more. I will poke at this more on Monday.
So the problem is due to KASLR --- we can't use __va() before kernel_randomize_memory() is called since it will change __PAGE_OFFSET. (Setting CONFIG_RANDOMIZE_BASE will cause failure.)
-boris
Juergen Gross
maintainerQuoted 60 lines · Boris Ostrovsky
Quoted 59 lines · Juergen Gross
In a HVM guest the kernel allocates the page for mapping the shared info structure via
extend_brk()today. This will lead to a drop of performance as the underlying EPT entry will have to be split up into 4kB entries as the single shared info page is located in hypervisor memory.The issue has been detected by using the libmicro munmap test:
unmapping 8kB of memory was faster by nearly a factor of two when no pv interfaces were active in the HVM guest.So instead of taking a page from memory which might be mapped via large EPT entries use a page which is already mapped via a 4kB EPT
entry: we can take a page from the first 1MB of memory as the video memory at 640kB disallows using larger EPT entries.Signed-off-by Juergen Gross <[email protected]>--- arch/x86/xen/enlighten_hvm.c | 31 ++++++++++++++++++++++++------- arch/x86/xen/enlighten_pv.c | 2 -- 2 files changed, 24 insertions(+), 9 deletions(-)arch/x86/xen/enlighten_hvm.c +13
-1@@ -1,5 +1,6 @@#include <linux/cpu.h> #include <linux/kexec.h> +#include <linux/memblock.h> #include <xen/features.h> #include <xen/events.h> @@ -10,9 +11,11 @@#include <asm/reboot.h> #include <asm/setup.h> #include <asm/hypervisor.h> +#include <asm/e820/api.h> #include <asm/xen/cpuid.h> #include <asm/xen/hypervisor.h> +#include <asm/xen/page.h> #include "xen-ops.h" #include "mmu.h" @@ -22,20 +25,34 @@ void __ref xen_hvm_init_shared_info(void) {int cpu;struct xen_add_to_physmap xatp; -static struct shared_info *shared_info_page; +u64 pa; + +if (HYPERVISOR_shared_info == &xen_dummy_shared_info) { +/* +* Search for a free page starting at 4kB physical address. +* Low memory is preferred to avoid an EPT large page split up +* by the mapping. +* Starting below X86_RESERVE_LOW (usually 64kB) is fine as +* the BIOS used for HVM guests is well behaved and won't +* clobber memory other than the first 4kB.
Quoted 8 lines
arch/x86/xen/enlighten_hvm.c void __ref xen_hvm_init_shared_info(void) · line 43
Quoted 6 lines
arch/x86/xen/enlighten_hvm.c +6
-0+*/ +for (pa =PAGE_SIZE ; + !e820__mapped_all (pa, pa +PAGE_SIZE ,E820_TYPE_RAM ) || +memblock_is_reserved (pa); + pa +=PAGE_SIZE ) + ;Is it possible to never find a page here?
Only if there is no memory available at all. :-)
TBH: I expect this to _always_ succeed at the first loop iteration.
Juergen
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xen.org/xen-devel