From 1e36436a10b7bbfc0345a0d630abb412112d2bcb Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 19 May 2006 15:58:46 +0100 Subject: [PATCH 1/5] [NET] front: Remove duplicate maybe_wake_tx Since network_tx_buf_gc unconditionally calls network_maybe_wake_tx at the end, there is no need to call it again right after a call to network_tx_buf_gc. Signed-off-by: Herbert Xu --- linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c index a85684d402..431841523d 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c @@ -1045,8 +1045,6 @@ static void network_connect(struct net_device *dev) notify_remote_via_irq(np->irq); network_tx_buf_gc(dev); - network_maybe_wake_tx(dev); - spin_unlock(&np->rx_lock); spin_unlock_irq(&np->tx_lock); } From e7c2054604b95579fcbd10bb2cfc5765e9c192e7 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 19 May 2006 16:01:08 +0100 Subject: [PATCH 2/5] [XM-TEST] Use explicit (IP id==packet size) on hping2 tests to avoid problems with IP id==0 Signed-off-by: Jim Dykman --- tools/xm-test/tests/network/03_network_local_tcp_pos.py | 4 ++-- tools/xm-test/tests/network/04_network_local_udp_pos.py | 4 ++-- tools/xm-test/tests/network/06_network_dom0_tcp_pos.py | 2 +- tools/xm-test/tests/network/07_network_dom0_udp_pos.py | 2 +- tools/xm-test/tests/network/12_network_domU_tcp_pos.py | 2 +- tools/xm-test/tests/network/13_network_domU_udp_pos.py | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/xm-test/tests/network/03_network_local_tcp_pos.py b/tools/xm-test/tests/network/03_network_local_tcp_pos.py index 8e3f80f847..b3b0bf103f 100644 --- a/tools/xm-test/tests/network/03_network_local_tcp_pos.py +++ b/tools/xm-test/tests/network/03_network_local_tcp_pos.py @@ -44,7 +44,7 @@ try: lofails="" for size in trysizes: out = console.runCmd("hping2 127.0.0.1 -E /dev/urandom -q -c 20 " - + "--fast -d " + str(size)) + + "--fast -d " + str(size) + " -N " + str(size)) if out["return"]: lofails += " " + str(size) @@ -54,7 +54,7 @@ try: ip = netdev.getNetDevIP() for size in trysizes: out = console.runCmd("hping2 " + ip + " -E /dev/urandom -q -c 20 " - + "--fast -d "+ str(size)) + + "--fast -d "+ str(size) + " -N " + str(size)) if out["return"]: eth0fails += " " + str(size) except ConsoleError, e: diff --git a/tools/xm-test/tests/network/04_network_local_udp_pos.py b/tools/xm-test/tests/network/04_network_local_udp_pos.py index 7cd5e6c0af..fcc6807a1d 100644 --- a/tools/xm-test/tests/network/04_network_local_udp_pos.py +++ b/tools/xm-test/tests/network/04_network_local_udp_pos.py @@ -43,7 +43,7 @@ try: lofails="" for size in trysizes: out = console.runCmd("hping2 127.0.0.1 -E /dev/urandom -2 -q -c 20 " - + "--fast -d " + str(size)) + + "--fast -d " + str(size) + " -N " + str(size)) if out["return"]: lofails += " " + str(size) print out["output"] @@ -54,7 +54,7 @@ try: ip = netdev.getNetDevIP() for size in trysizes: out = console.runCmd("hping2 " + ip + " -E /dev/urandom -2 -q -c 20 " - + "--fast -d " + str(size)) + + "--fast -d " + str(size) + " -N " + str(size)) if out["return"]: eth0fails += " " + str(size) print out["output"] diff --git a/tools/xm-test/tests/network/06_network_dom0_tcp_pos.py b/tools/xm-test/tests/network/06_network_dom0_tcp_pos.py index e5b67b5329..e36c090bf7 100644 --- a/tools/xm-test/tests/network/06_network_dom0_tcp_pos.py +++ b/tools/xm-test/tests/network/06_network_dom0_tcp_pos.py @@ -44,7 +44,7 @@ try: dom0ip = netdev.getDom0AliasIP() for size in trysizes: out = console.runCmd("hping2 " + dom0ip + " -E /dev/urandom -q -c 20 " - + "--fast -d " + str(size)) + + "--fast -d " + str(size) + " -N " + str(size)) if out["return"]: fails += " " + str(size) print out["output"] diff --git a/tools/xm-test/tests/network/07_network_dom0_udp_pos.py b/tools/xm-test/tests/network/07_network_dom0_udp_pos.py index 7521e8eb07..f86514f811 100644 --- a/tools/xm-test/tests/network/07_network_dom0_udp_pos.py +++ b/tools/xm-test/tests/network/07_network_dom0_udp_pos.py @@ -43,7 +43,7 @@ try: dom0ip = netdev.getDom0AliasIP() for size in trysizes: out = console.runCmd("hping2 " + dom0ip + " -E /dev/urandom -2 -q -c 20" - + " --fast -d " + str(size)) + + " --fast -d " + str(size) + " -N " + str(size)) if out["return"]: fails += " " + str(size) print out["output"] diff --git a/tools/xm-test/tests/network/12_network_domU_tcp_pos.py b/tools/xm-test/tests/network/12_network_domU_tcp_pos.py index 5c08bab2a8..50a8a9a569 100644 --- a/tools/xm-test/tests/network/12_network_domU_tcp_pos.py +++ b/tools/xm-test/tests/network/12_network_domU_tcp_pos.py @@ -50,7 +50,7 @@ try: ip2 = dst_netdev.getNetDevIP() for size in pingsizes: out = src_console.runCmd("hping2 " + ip2 + " -E /dev/urandom -q -c 20 " - + "--fast -d " + str(size)) + + "--fast -d " + str(size) + " -N " + str(size)) if out["return"]: fails += " " + str(size) print out["output"] diff --git a/tools/xm-test/tests/network/13_network_domU_udp_pos.py b/tools/xm-test/tests/network/13_network_domU_udp_pos.py index bb2aedf4a1..b247267f25 100644 --- a/tools/xm-test/tests/network/13_network_domU_udp_pos.py +++ b/tools/xm-test/tests/network/13_network_domU_udp_pos.py @@ -50,7 +50,7 @@ try: ip2 = dst_netdev.getNetDevIP() for size in pingsizes: out = src_console.runCmd("hping2 " + ip2 + " -E /dev/urandom -2 -q " - + "-c 20 --fast -d " + str(size)) + + "-c 20 --fast -d " + str(size) + " -N " + str(size)) if out["return"]: fails += " " + str(size) print out["output"] From 0a44ca5991690acb6c6d88f08dfbe2fa8144ac14 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 19 May 2006 16:07:36 +0100 Subject: [PATCH 3/5] [XEND] separate concept of initial memory size and overhead memory size. When a domain (whether para- or fully-virtualized) reports how much overhead memory it requires (via getDomainMemory in image.py), all such memory was immediately allocated to the domain itself. This is certainly incorrect for HVM domains, since additional increase_reservation calls are made later in qemu. Since all ballooned memory is already taken, qemu will fail. The fix is to treat the requested memory size and the overhead size as separate values. The requested memory size is immediately allocated to the new domain; the overhead is left unallocated for whatever else might need it later. Signed-off-by: Charles Coffing --- tools/python/xen/xend/XendDomainInfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index f6961b71c9..029c0c969c 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1264,7 +1264,7 @@ class XendDomainInfo: m = self.image.getDomainMemory(self.info['memory'] * 1024) balloon.free(m) xc.domain_setmaxmem(self.domid, m) - xc.domain_memory_increase_reservation(self.domid, m, 0, 0) + xc.domain_memory_increase_reservation(self.domid, self.info['memory'] * 1024, 0, 0) self.createChannels() From 37d3005e6271fa2c613f466068d6c0f38943c754 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 19 May 2006 16:08:51 +0100 Subject: [PATCH 4/5] [XEND] An empirical and more conservative memory-overhead estimate for PV and HVM guests. This patch calculates the overhead needed for HVM domains. If HVM is supported by the hardware, I add a little ballooning overhead to paravirtualized VMs also, to avoid low-memory situations. (There are various unchecked alloc_domheap_pages calls in shadow*.c that I am trying to avoid tripping over for now...) The values in this patch work fine on 32 bit; I may update them later based on feedback and/or testing on 64 bit. Signed-off-by: Charles Coffing --- tools/python/xen/xend/image.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 43ed39993c..6d2da07cd6 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -19,6 +19,7 @@ import os, string import re +import math import xen.lowlevel.xc from xen.xend import sxp @@ -141,11 +142,13 @@ class ImageHandler: % (self.ostype, self.vm.getDomid(), str(result))) - def getDomainMemory(self, mem): + def getDomainMemory(self, mem_kb): """@return The memory required, in KiB, by the domain to store the - given amount, also in KiB. This is normally just mem, but HVM domains - have overheads to account for.""" - return mem + given amount, also in KiB. This is normally just mem, but if HVM is + supported, keep a little extra free.""" + if 'hvm' in xc.xeninfo()['xen_caps']: + mem_kb += 4*1024; + return mem_kb def buildDomain(self): """Build the domain. Define in subclass.""" @@ -377,15 +380,20 @@ class HVMImageHandler(ImageHandler): os.waitpid(self.pid, 0) self.pid = 0 - def getDomainMemory(self, mem): + def getDomainMemory(self, mem_kb): """@see ImageHandler.getDomainMemory""" - page_kb = 4 - extra_pages = 0 if os.uname()[4] == 'ia64': page_kb = 16 # ROM size for guest firmware, ioreq page and xenstore page extra_pages = 1024 + 2 - return mem + extra_pages * page_kb + else: + page_kb = 4 + # This was derived emperically: + # 2.4 MB overhead per 1024 MB RAM + 8 MB constant + # + 4 to avoid low-memory condition + extra_mb = (2.4/1024) * (mem_kb/1024.0) + 12; + extra_pages = int( math.ceil( extra_mb*1024 / page_kb )) + return mem_kb + extra_pages * page_kb def register_shutdown_watch(self): """ add xen store watch on control/shutdown """ From 573e986d56c848a3e8901f30ad7740c92d1ed23b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 19 May 2006 16:10:52 +0100 Subject: [PATCH 5/5] Several page allocations, done in the hypervisor when starting an HVM domain, are not checked. This can cause the physical machine to crash when starting the HVM domain during low-memory conditions. Kudos to Charles Arnold for catching the problem with shadow_direct_map_init. Signed-off-by: Charles Coffing --- xen/arch/x86/hvm/hvm.c | 6 +++++- xen/arch/x86/hvm/svm/svm.c | 4 +++- xen/arch/x86/hvm/svm/vmcb.c | 17 ++++++++++------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index e5a3c89703..a0844e4edf 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -189,7 +189,11 @@ void hvm_setup_platform(struct domain* d) if ( !hvm_guest(current) || (current->vcpu_id != 0) ) return; - shadow_direct_map_init(d); + if ( shadow_direct_map_init(d) == 0 ) + { + printk("Can not allocate shadow direct map for HVM domain.\n"); + domain_crash_synchronous(); + } hvm_map_io_shared_page(d); hvm_get_info(d); diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 2541a140f9..96e0d31b7f 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -458,6 +458,9 @@ int start_svm(void) if (!(test_bit(X86_FEATURE_SVME, &boot_cpu_data.x86_capability))) return 0; + svm_globals[cpu].hsa = alloc_host_save_area(); + if (! svm_globals[cpu].hsa) + return 0; rdmsr(MSR_EFER, eax, edx); eax |= EFER_SVME; @@ -466,7 +469,6 @@ int start_svm(void) printk("AMD SVM Extension is enabled for cpu %d.\n", cpu ); /* Initialize the HSA for this core */ - svm_globals[cpu].hsa = alloc_host_save_area(); phys_hsa = (u64) virt_to_maddr( svm_globals[cpu].hsa ); phys_hsa_lo = (u32) phys_hsa; phys_hsa_hi = (u32) (phys_hsa >> 32); diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c index 3917650a4f..44c87335d6 100644 --- a/xen/arch/x86/hvm/svm/vmcb.c +++ b/xen/arch/x86/hvm/svm/vmcb.c @@ -139,18 +139,21 @@ static int construct_vmcb_controls(struct arch_svm_struct *arch_svm) /* The following is for I/O and MSR permision map */ iopm = alloc_xenheap_pages(get_order_from_bytes(IOPM_SIZE)); - - ASSERT(iopm); - memset(iopm, 0xff, IOPM_SIZE); - clear_bit(PC_DEBUG_PORT, iopm); + if (iopm) + { + memset(iopm, 0xff, IOPM_SIZE); + clear_bit(PC_DEBUG_PORT, iopm); + } msrpm = alloc_xenheap_pages(get_order_from_bytes(MSRPM_SIZE)); - - ASSERT(msrpm); - memset(msrpm, 0xff, MSRPM_SIZE); + if (msrpm) + memset(msrpm, 0xff, MSRPM_SIZE); arch_svm->iopm = iopm; arch_svm->msrpm = msrpm; + if (! iopm || ! msrpm) + return 1; + vmcb->iopm_base_pa = (u64) virt_to_maddr(iopm); vmcb->msrpm_base_pa = (u64) virt_to_maddr(msrpm);