aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoremellor@leeni.uk.xensource.com <emellor@leeni.uk.xensource.com>2006-04-10 16:36:03 +0100
committeremellor@leeni.uk.xensource.com <emellor@leeni.uk.xensource.com>2006-04-10 16:36:03 +0100
commit224cab0dfd3e7696fec21acf5e0cd821328fbe49 (patch)
treed162a66094c2f8c5dbe26fc5dd0a84675c7de998
parent02e0e0d9bb791264722682d5dc26691e3a338803 (diff)
parent9ffd98fa29fd8dc997529fa120d25446dbbc1bdd (diff)
downloadxen-224cab0dfd3e7696fec21acf5e0cd821328fbe49.tar.gz
xen-224cab0dfd3e7696fec21acf5e0cd821328fbe49.tar.bz2
xen-224cab0dfd3e7696fec21acf5e0cd821328fbe49.zip
Merged.
-rw-r--r--Config.mk1
-rw-r--r--Makefile34
-rw-r--r--buildconfigs/Rules.mk36
-rw-r--r--buildconfigs/linux-defconfig_xen0_x86_3226
-rw-r--r--buildconfigs/linux-defconfig_xen0_x86_6410
-rw-r--r--buildconfigs/linux-defconfig_xen_x86_324
-rw-r--r--buildconfigs/linux-defconfig_xen_x86_6410
-rw-r--r--buildconfigs/mk.linux-2.6-xen9
-rw-r--r--linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c4
-rw-r--r--linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c4
-rw-r--r--linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c4
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/core/reboot.c4
-rw-r--r--linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/io.h1
-rw-r--r--linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/io.h1
-rw-r--r--tools/ioemu/hw/vga.c4
-rw-r--r--tools/libxc/xc_linux_build.c38
-rw-r--r--tools/libxc/xc_load_elf.c15
-rw-r--r--tools/python/xen/xend/server/pciif.py8
-rw-r--r--xen/Rules.mk2
-rw-r--r--xen/arch/ia64/xen/irq.c27
-rw-r--r--xen/arch/x86/io_apic.c146
-rw-r--r--xen/arch/x86/irq.c28
-rw-r--r--xen/common/sched_sedf.c727
-rw-r--r--xen/common/trace.c23
-rw-r--r--xen/include/public/xen.h1
-rw-r--r--xen/include/xen/sched.h2
-rw-r--r--xen/include/xen/softirq.h3
27 files changed, 545 insertions, 627 deletions
diff --git a/Config.mk b/Config.mk
index 7cea3953c5..2b15addd12 100644
--- a/Config.mk
+++ b/Config.mk
@@ -24,6 +24,7 @@ OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
DISTDIR ?= $(XEN_ROOT)/dist
+DESTDIR ?= /
INSTALL = install
INSTALL_DIR = $(INSTALL) -d -m0755
diff --git a/Makefile b/Makefile
index 3cd9d53b99..71a7c7d342 100644
--- a/Makefile
+++ b/Makefile
@@ -115,18 +115,6 @@ distclean: clean
# Linux name for GNU distclean
mrproper: distclean
-install-logging: LOGGING=logging-0.4.9.2
-install-logging:
- [ -f $(LOGGING).tar.gz ] || wget http://www.red-dove.com/$(LOGGING).tar.gz
- tar -zxf $(LOGGING).tar.gz
- cd $(LOGGING) && python setup.py install
-
-# handy target to upgrade iptables (use rpm or apt-get in preference)
-install-iptables:
- wget http://www.netfilter.org/files/iptables-1.2.11.tar.bz2
- tar -jxf iptables-1.2.11.tar.bz2
- $(MAKE) -C iptables-1.2.11 PREFIX= KERNEL_DIR=../linux-$(LINUX_VER)-xen0 install
-
help:
@echo 'Installation targets:'
@echo ' install - build and install everything'
@@ -147,23 +135,25 @@ help:
@echo ' dev-docs - build developer-only documentation'
@echo ''
@echo 'Cleaning targets:'
- @echo ' clean - clean the Xen, tools and docs (but not'
- @echo ' guest kernel) trees'
- @echo ' distclean - clean plus delete kernel tarballs and kernel'
- @echo ' build trees'
+ @echo ' clean - clean the Xen, tools and docs (but not guest kernel trees)'
+ @echo ' distclean - clean plus delete kernel build trees and'
+ @echo ' local downloaded files'
@echo ' kdelete - delete guest kernel build trees'
@echo ' kclean - clean guest kernel build trees'
@echo ''
- @echo 'Dependency installation targets:'
- @echo ' install-logging - install the Python Logging package'
- @echo ' install-iptables - install iptables tools'
- @echo ''
@echo 'Miscellaneous targets:'
@echo ' prep-kernels - prepares kernel directories, does not build'
@echo ' mkpatches - make patches against vanilla kernels from'
@echo ' sparse trees'
- @echo ' uninstall - attempt to remove installed Xen tools (use'
- @echo ' with extreme care!)'
+ @echo ' uninstall - attempt to remove installed Xen tools'
+ @echo ' (use with extreme care!)'
+ @echo
+ @echo 'Environment:'
+ @echo ' XEN_PYTHON_NATIVE_INSTALL=y'
+ @echo ' - native python install or dist'
+ @echo ' install into prefix/lib/python<VERSION>'
+ @echo ' instead of <PREFIX>/lib/python'
+ @echo ' true if set to non-empty value, false otherwise'
# Use this target with extreme care!
uninstall: D=$(DESTDIR)
diff --git a/buildconfigs/Rules.mk b/buildconfigs/Rules.mk
index e4cb40def8..57df05e06b 100644
--- a/buildconfigs/Rules.mk
+++ b/buildconfigs/Rules.mk
@@ -40,29 +40,6 @@ patch-%.bz2:
@echo "Cannot find $(@F) in path $(LINUX_SRC_PATH)"
wget $(KERNEL_REPO)/pub/linux/kernel/v$(_LINUX_VDIR)/$(_LINUX_XDIR)/$(@F) -O./$@
-# Expand NetBSD release to NetBSD version
-NETBSD_RELEASE ?= 2.0
-NETBSD_VER ?= $(patsubst netbsd-%-xen-sparse,%,$(wildcard netbsd-$(NETBSD_RELEASE)*-xen-sparse))
-NETBSD_CVSSNAP ?= 20050309
-
-# Setup NetBSD search path
-NETBSD_SRC_PATH ?= .:..
-vpath netbsd-%.tar.bz2 $(NETBSD_SRC_PATH)
-
-# download a pristine NetBSD tarball if there isn't one in NETBSD_SRC_PATH
-netbsd-%-xen-kernel-$(NETBSD_CVSSNAP).tar.bz2:
- @echo "Cannot find $@ in path $(NETBSD_SRC_PATH)"
- wget http://www.cl.cam.ac.uk/Research/SRG/netos/xen/downloads/$@ -O./$@
-
-netbsd-%.tar.bz2: netbsd-%-xen-kernel-$(NETBSD_CVSSNAP).tar.bz2
- ln -fs $< $@
-
-ifeq ($(OS),linux)
-OS_VER = $(LINUX_VER)
-else
-OS_VER = $(NETBSD_VER)
-endif
-
pristine-%: pristine-%/.valid-pristine
@true
@@ -124,27 +101,20 @@ linux-2.6-xen.patch: ref-linux-$(LINUX_VER)/.valid-ref
rm -rf tmp-$@
cp -al $(<D) tmp-$@
( cd linux-2.6-xen-sparse && ./mkbuildtree ../tmp-$@ )
- diff -Nurp $(<D) tmp-$@ > $@ || true
+ diff -Nurp $(patsubst ref%,pristine%,$(<D)) tmp-$@ > $@ || true
rm -rf tmp-$@
%-xen.patch: ref-%/.valid-ref
rm -rf tmp-$@
cp -al $(<D) tmp-$@
( cd $*-xen-sparse && ./mkbuildtree ../tmp-$@ )
- diff -Nurp $(<D) tmp-$@ > $@ || true
+ diff -Nurp $(patsubst ref%,pristine%,$(<D)) tmp-$@ > $@ || true
rm -rf tmp-$@
-%-mrproper: %-mrproper-extra
+%-mrproper:
rm -rf pristine-$(*)* ref-$(*)* $*.tar.bz2
rm -rf $*-xen.patch
-netbsd-%-mrproper-extra:
- rm -rf netbsd-$*-tools netbsd-$*-tools.tar.bz2
- rm -f netbsd-$*-xen-kernel-$(NETBSD_CVSSNAP).tar.bz2
-
-%-mrproper-extra:
- @: # do nothing
-
config-update-pae:
ifeq ($(XEN_TARGET_X86_PAE),y)
sed -e 's!^CONFIG_HIGHMEM4G=y$$!\# CONFIG_HIGHMEM4G is not set!;s!^\# CONFIG_HIGHMEM64G is not set$$!CONFIG_HIGHMEM64G=y!' $(CONFIG_FILE) > $(CONFIG_FILE)- && mv $(CONFIG_FILE)- $(CONFIG_FILE)
diff --git a/buildconfigs/linux-defconfig_xen0_x86_32 b/buildconfigs/linux-defconfig_xen0_x86_32
index c520622e1e..fe24dacce5 100644
--- a/buildconfigs/linux-defconfig_xen0_x86_32
+++ b/buildconfigs/linux-defconfig_xen0_x86_32
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc3-xen0
-# Thu Feb 16 22:52:42 2006
+# Linux kernel version: 2.6.16-xen0
+# Sat Apr 8 11:34:07 2006
#
CONFIG_X86_32=y
CONFIG_SEMAPHORE_SLEEPERS=y
@@ -208,7 +208,6 @@ CONFIG_ACPI_BLACKLIST_YEAR=0
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_SYSTEM=y
-# CONFIG_X86_PM_TIMER is not set
# CONFIG_ACPI_CONTAINER is not set
#
@@ -392,7 +391,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
-# CONFIG_PNP is not set
+CONFIG_PNP=y
+CONFIG_PNP_DEBUG=y
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
#
# Block devices
@@ -440,6 +445,7 @@ CONFIG_BLK_DEV_IDECD=y
#
CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDEPCI_SHARE_IRQ is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -623,6 +629,7 @@ CONFIG_NETDEVICES=y
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=y
+# CONFIG_NET_SB1000 is not set
#
# ARCnet devices
@@ -1064,11 +1071,7 @@ CONFIG_USB_MON=y
# CONFIG_INFINIBAND is not set
#
-# SN Devices
-#
-
-#
-# EDAC - error detection and reporting (RAS)
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
#
# CONFIG_EDAC is not set
@@ -1306,7 +1309,7 @@ CONFIG_CRYPTO_CRC32C=m
#
# CONFIG_CRYPTO_DEV_PADLOCK is not set
CONFIG_XEN=y
-CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_INTERFACE_VERSION=0x00030101
#
# XEN
@@ -1332,6 +1335,7 @@ CONFIG_XEN_DISABLE_SERIAL=y
CONFIG_XEN_SYSFS=y
CONFIG_HAVE_ARCH_ALLOC_SKB=y
CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_NO_IDLE_HZ=y
#
# Library routines
@@ -1344,4 +1348,6 @@ CONFIG_ZLIB_INFLATE=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_X86_BIOS_REBOOT=y
+CONFIG_X86_NO_TSS=y
+CONFIG_X86_NO_IDT=y
CONFIG_KTIME_SCALAR=y
diff --git a/buildconfigs/linux-defconfig_xen0_x86_64 b/buildconfigs/linux-defconfig_xen0_x86_64
index 04e992076d..94d81d5ae3 100644
--- a/buildconfigs/linux-defconfig_xen0_x86_64
+++ b/buildconfigs/linux-defconfig_xen0_x86_64
@@ -327,7 +327,13 @@ CONFIG_STANDALONE=y
#
# Plug and Play support
#
-# CONFIG_PNP is not set
+CONFIG_PNP=y
+CONFIG_PNP_DEBUG=y
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
#
# Block devices
@@ -375,6 +381,7 @@ CONFIG_BLK_DEV_IDECD=y
#
CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDEPCI_SHARE_IRQ is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -559,6 +566,7 @@ CONFIG_NETDEVICES=y
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=y
+# CONFIG_NET_SB1000 is not set
#
# ARCnet devices
diff --git a/buildconfigs/linux-defconfig_xen_x86_32 b/buildconfigs/linux-defconfig_xen_x86_32
index 59baf22bb2..27a102a80c 100644
--- a/buildconfigs/linux-defconfig_xen_x86_32
+++ b/buildconfigs/linux-defconfig_xen_x86_32
@@ -912,12 +912,12 @@ CONFIG_PARPORT_1284=y
# Plug and Play support
#
CONFIG_PNP=y
-# CONFIG_PNP_DEBUG is not set
+CONFIG_PNP_DEBUG=y
#
# Protocols
#
-# CONFIG_PNPACPI is not set
+CONFIG_PNPACPI=y
#
# Block devices
diff --git a/buildconfigs/linux-defconfig_xen_x86_64 b/buildconfigs/linux-defconfig_xen_x86_64
index 8e97389570..5d95052289 100644
--- a/buildconfigs/linux-defconfig_xen_x86_64
+++ b/buildconfigs/linux-defconfig_xen_x86_64
@@ -776,7 +776,13 @@ CONFIG_PARPORT_1284=y
#
# Plug and Play support
#
-# CONFIG_PNP is not set
+CONFIG_PNP=y
+CONFIG_PNP_DEBUG=y
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
#
# Block devices
@@ -857,6 +863,7 @@ CONFIG_BLK_DEV_IDESCSI=m
CONFIG_IDE_GENERIC=y
CONFIG_BLK_DEV_CMD640=y
CONFIG_BLK_DEV_CMD640_ENHANCED=y
+CONFIG_BLK_DEV_IDEPNP=y
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -1088,6 +1095,7 @@ CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
+CONFIG_NET_SB1000=m
#
# ARCnet devices
diff --git a/buildconfigs/mk.linux-2.6-xen b/buildconfigs/mk.linux-2.6-xen
index 69b3f5b554..10cba291e5 100644
--- a/buildconfigs/mk.linux-2.6-xen
+++ b/buildconfigs/mk.linux-2.6-xen
@@ -1,13 +1,10 @@
-
-OS = linux
-
LINUX_SERIES = 2.6
LINUX_VER = 2.6.16
LINUX_SRCS = linux-2.6.16.tar.bz2
EXTRAVERSION ?= xen
-LINUX_DIR = $(OS)-$(LINUX_VER)-$(EXTRAVERSION)
+LINUX_DIR = linux-$(LINUX_VER)-$(EXTRAVERSION)
include buildconfigs/Rules.mk
@@ -22,7 +19,7 @@ build: $(LINUX_DIR)/include/linux/autoconf.h
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) vmlinuz
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) install
-$(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER)/.valid-ref
+$(LINUX_DIR)/include/linux/autoconf.h: ref-linux-$(LINUX_VER)/.valid-ref
rm -rf $(LINUX_DIR)
cp -al $(<D) $(LINUX_DIR)
# Apply arch-xen patches
@@ -52,4 +49,4 @@ clean::
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) clean
delete:
- rm -rf tmp-$(OS)-$(LINUX_VER) $(LINUX_DIR)
+ rm -rf tmp-linux-$(LINUX_VER) $(LINUX_DIR)
diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c
index 4d96270261..eb616232c7 100644
--- a/linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c
@@ -69,7 +69,7 @@ dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
} else {
for (i = 0; i < nents; i++ ) {
sg[i].dma_address =
- page_to_phys(sg[i].page) + sg[i].offset;
+ page_to_bus(sg[i].page) + sg[i].offset;
sg[i].dma_length = sg[i].length;
BUG_ON(!sg[i].page);
IOMMU_BUG_ON(address_needs_mapping(
@@ -105,7 +105,7 @@ dma_map_page(struct device *dev, struct page *page, unsigned long offset,
dma_addr = swiotlb_map_page(
dev, page, offset, size, direction);
} else {
- dma_addr = page_to_phys(page) + offset;
+ dma_addr = page_to_bus(page) + offset;
IOMMU_BUG_ON(address_needs_mapping(dev, dma_addr));
}
diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
index b738343e89..bb9b6ed2f1 100644
--- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
@@ -1848,10 +1848,6 @@ void __init setup_arch(char **cmdline_p)
get_smp_config();
#endif
- /* XXX Disable irqdebug until we have a way to avoid interrupt
- * conflicts. */
- noirqdebug_setup("");
-
register_memory();
if (xen_start_info->flags & SIF_INITDOMAIN) {
diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c b/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c
index e493e345c5..da0a0981ca 100644
--- a/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c
@@ -32,7 +32,7 @@ EXPORT_SYMBOL(swiotlb);
#define OFFSET(val,align) ((unsigned long)((val) & ( (align) - 1)))
-#define SG_ENT_PHYS_ADDRESS(sg) (page_to_phys((sg)->page) + (sg)->offset)
+#define SG_ENT_PHYS_ADDRESS(sg) (page_to_bus((sg)->page) + (sg)->offset)
/*
* Maximum allowable number of contiguous slabs to map,
@@ -607,7 +607,7 @@ swiotlb_map_page(struct device *hwdev, struct page *page,
dma_addr_t dev_addr;
char *map;
- dev_addr = page_to_phys(page) + offset;
+ dev_addr = page_to_bus(page) + offset;
if (address_needs_mapping(hwdev, dev_addr)) {
buffer.page = page;
buffer.offset = offset;
diff --git a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c
index ba0b9b9112..7a3d2cc39d 100644
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c
@@ -59,6 +59,10 @@ void machine_power_off(void)
{
/* We really want to get pending console data out before we die. */
xencons_force_flush();
+#if defined(__i386__) || defined(__x86_64__)
+ if (pm_power_off)
+ pm_power_off();
+#endif
HYPERVISOR_shutdown(SHUTDOWN_poweroff);
}
diff --git a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/io.h b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/io.h
index 5961a42a89..7f9b7cdd36 100644
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/io.h
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/io.h
@@ -102,6 +102,7 @@ static inline void * phys_to_virt(unsigned long address)
*/
#define page_to_pseudophys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
#define page_to_phys(page) (phys_to_machine(page_to_pseudophys(page)))
+#define page_to_bus(page) (phys_to_machine(page_to_pseudophys(page)))
#define bio_to_pseudophys(bio) (page_to_pseudophys(bio_page((bio))) + \
(unsigned long) bio_offset((bio)))
diff --git a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/io.h b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/io.h
index c024447ae6..1ae9c89ba9 100644
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/io.h
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/io.h
@@ -130,6 +130,7 @@ static inline void * phys_to_virt(unsigned long address)
*/
#define page_to_pseudophys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
#define page_to_phys(page) (phys_to_machine(page_to_pseudophys(page)))
+#define page_to_bus(page) (phys_to_machine(page_to_pseudophys(page)))
#define bio_to_pseudophys(bio) (page_to_pseudophys(bio_page((bio))) + \
(unsigned long) bio_offset((bio)))
diff --git a/tools/ioemu/hw/vga.c b/tools/ioemu/hw/vga.c
index 3120ebac5d..11daaa27a2 100644
--- a/tools/ioemu/hw/vga.c
+++ b/tools/ioemu/hw/vga.c
@@ -1369,10 +1369,10 @@ static inline unsigned int cpuid_edx(unsigned int op)
{
unsigned int eax, edx;
- __asm__("cpuid"
+ __asm__("pushl %%ebx; cpuid; popl %%ebx"
: "=a" (eax), "=d" (edx)
: "0" (op)
- : "bx", "cx");
+ : "cx");
return edx;
}
diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c
index 2dbcf9fac6..34338884fe 100644
--- a/tools/libxc/xc_linux_build.c
+++ b/tools/libxc/xc_linux_build.c
@@ -110,10 +110,10 @@ static int parse_features(
if ( i == XENFEAT_NR_SUBMAPS*32 )
{
- ERROR("Unknown feature \"%.*s\".\n", (int)(p-feats), feats);
+ ERROR("Unknown feature \"%.*s\".", (int)(p-feats), feats);
if ( req )
{
- ERROR("Kernel requires an unknown hypervisor feature.\n");
+ ERROR("Kernel requires an unknown hypervisor feature.");
return -EINVAL;
}
}
@@ -579,6 +579,31 @@ static int setup_guest(int xc_handle,
return -1;
}
#else /* x86 */
+
+/* Check if the platform supports the guest kernel format */
+static int compat_check(int xc_handle, struct domain_setup_info *dsi)
+{
+ xen_capabilities_info_t xen_caps = "";
+
+ if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) {
+ ERROR("Cannot determine host capabilities.");
+ return 0;
+ }
+
+ if (strstr(xen_caps, "xen-3.0-x86_32p")) {
+ if (!dsi->pae_kernel) {
+ ERROR("Non PAE-kernel on PAE host.");
+ return 0;
+ }
+ } else if (dsi->pae_kernel) {
+ ERROR("PAE-kernel on non-PAE host.");
+ return 0;
+ }
+
+ return 1;
+}
+
+
static int setup_guest(int xc_handle,
uint32_t dom,
const char *image, unsigned long image_size,
@@ -635,10 +660,13 @@ static int setup_guest(int xc_handle,
if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
{
- PERROR("Guest OS must load to a page boundary.\n");
+ PERROR("Guest OS must load to a page boundary.");
goto error_out;
}
+ if (!compat_check(xc_handle, &dsi))
+ goto error_out;
+
/* Parse and validate kernel features. */
p = strstr(dsi.xen_guest_string, "FEATURES=");
if ( p != NULL )
@@ -647,7 +675,7 @@ static int setup_guest(int xc_handle,
supported_features,
required_features) )
{
- ERROR("Failed to parse guest kernel features.\n");
+ ERROR("Failed to parse guest kernel features.");
goto error_out;
}
@@ -659,7 +687,7 @@ static int setup_guest(int xc_handle,
{
if ( (supported_features[i]&required_features[i]) != required_features[i] )
{
- ERROR("Guest kernel does not support a required feature.\n");
+ ERROR("Guest kernel does not support a required feature.");
goto error_out;
}
}
diff --git a/tools/libxc/xc_load_elf.c b/tools/libxc/xc_load_elf.c
index 94c5c8708c..ee4b2f9a71 100644
--- a/tools/libxc/xc_load_elf.c
+++ b/tools/libxc/xc_load_elf.c
@@ -69,6 +69,21 @@ static int parseelfimage(const char *image,
return -EINVAL;
}
+ if (
+#if defined(__i386__)
+ (ehdr->e_ident[EI_CLASS] != ELFCLASS32) ||
+ (ehdr->e_machine != EM_386) ||
+#elif defined(__x86_64__)
+ (ehdr->e_ident[EI_CLASS] != ELFCLASS64) ||
+ (ehdr->e_machine != EM_X86_64) ||
+#endif
+ (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) ||
+ (ehdr->e_type != ET_EXEC) )
+ {
+ ERROR("Kernel not a Xen-compatible Elf image.");
+ return -EINVAL;
+ }
+
if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
{
ERROR("ELF program headers extend beyond end of image.");
diff --git a/tools/python/xen/xend/server/pciif.py b/tools/python/xen/xend/server/pciif.py
index aa222691f6..053b66adcb 100644
--- a/tools/python/xen/xend/server/pciif.py
+++ b/tools/python/xen/xend/server/pciif.py
@@ -115,7 +115,7 @@ class PciController(DevController):
dev = PciDevice(domain, bus, slot, func)
except Exception, e:
raise VmError("pci: failed to locate device and "+
- "parse it's resources - %s"+str(e))
+ "parse it's resources - "+str(e))
if dev.driver!='pciback':
raise VmError(("pci: PCI Backend does not own device "+ \
@@ -131,7 +131,7 @@ class PciController(DevController):
nr_ports = size, allow_access = True)
if rc<0:
raise VmError(('pci: failed to configure I/O ports on device '+
- '%s - errno=%d')&(dev.name,rc))
+ '%s - errno=%d')%(dev.name,rc))
for (start, size) in dev.iomem:
# Convert start/size from bytes to page frame sizes
@@ -147,7 +147,7 @@ class PciController(DevController):
allow_access = True)
if rc<0:
raise VmError(('pci: failed to configure I/O memory on device '+
- '%s - errno=%d')&(dev.name,rc))
+ '%s - errno=%d')%(dev.name,rc))
if dev.irq>0:
log.debug('pci: enabling irq %d'%dev.irq)
@@ -155,7 +155,7 @@ class PciController(DevController):
allow_access = True)
if rc<0:
raise VmError(('pci: failed to configure irq on device '+
- '%s - errno=%d')&(dev.name,rc))
+ '%s - errno=%d')%(dev.name,rc))
def waitForBackend(self,devid):
return (0, "ok - no hotplug")
diff --git a/xen/Rules.mk b/xen/Rules.mk
index 66749058d3..1f4687f7fa 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -74,7 +74,7 @@ subdir-n := $(patsubst %,%/,$(patsubst %/,%,$(subdir-n)))
subdir-y := $(patsubst %,%/,$(patsubst %/,%,$(subdir-y)))
# Add explicitly declared subdirectories to the object list.
-obj-y += $(patsubst %,%/built_in.o,$(subdir-y))
+obj-y += $(patsubst %/,%/built_in.o,$(subdir-y))
# Add implicitly declared subdirectories (in the object list) to the
# subdirectory list, and rewrite the object-list entry.
diff --git a/xen/arch/ia64/xen/irq.c b/xen/arch/ia64/xen/irq.c
index c42b5e2944..350ec72435 100644
--- a/xen/arch/ia64/xen/irq.c
+++ b/xen/arch/ia64/xen/irq.c
@@ -1358,25 +1358,20 @@ static void __do_IRQ_guest(int irq)
int pirq_guest_unmask(struct domain *d)
{
irq_desc_t *desc;
- int i, j, pirq;
- u32 m;
+ int pirq;
shared_info_t *s = d->shared_info;
- for ( i = 0; i < ARRAY_SIZE(d->pirq_mask); i++ )
+ for ( pirq = find_first_bit(d->pirq_mask, NR_PIRQS);
+ pirq < NR_PIRQS;
+ pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq+1) )
{
- m = d->pirq_mask[i];
- while ( (j = ffs(m)) != 0 )
- {
- m &= ~(1 << --j);
- pirq = (i << 5) + j;
- desc = &irq_desc[pirq];
- spin_lock_irq(&desc->lock);
- if ( !test_bit(d->pirq_to_evtchn[pirq], &s->evtchn_mask[0]) &&
- test_and_clear_bit(pirq, &d->pirq_mask) &&
- (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
- desc->handler->end(pirq);
- spin_unlock_irq(&desc->lock);
- }
+ desc = &irq_desc[pirq];
+ spin_lock_irq(&desc->lock);
+ if ( !test_bit(d->pirq_to_evtchn[pirq], &s->evtchn_mask[0]) &&
+ test_and_clear_bit(pirq, &d->pirq_mask) &&
+ (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
+ desc->handler->end(pirq);
+ spin_unlock_irq(&desc->lock);
}
return 0;
diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c
index 18d8ed961c..715b7d294d 100644
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -75,6 +75,7 @@ int disable_timer_pin_1 __initdata;
static struct irq_pin_list {
int apic, pin, next;
} irq_2_pin[PIN_MAP_SIZE];
+static int irq_2_pin_free_entry = NR_IRQS;
int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
@@ -85,22 +86,59 @@ int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
*/
static void add_pin_to_irq(unsigned int irq, int apic, int pin)
{
- static int first_free_entry = NR_IRQS;
struct irq_pin_list *entry = irq_2_pin + irq;
- while (entry->next)
+ while (entry->next) {
+ BUG_ON((entry->apic == apic) && (entry->pin == pin));
entry = irq_2_pin + entry->next;
+ }
+
+ BUG_ON((entry->apic == apic) && (entry->pin == pin));
if (entry->pin != -1) {
- entry->next = first_free_entry;
- entry = irq_2_pin + entry->next;
- if (++first_free_entry >= PIN_MAP_SIZE)
+ if (irq_2_pin_free_entry >= PIN_MAP_SIZE)
panic("io_apic.c: whoops");
+ entry->next = irq_2_pin_free_entry;
+ entry = irq_2_pin + entry->next;
+ irq_2_pin_free_entry = entry->next;
+ entry->next = 0;
}
entry->apic = apic;
entry->pin = pin;
}
+static void remove_pin_at_irq(unsigned int irq, int apic, int pin)
+{
+ struct irq_pin_list *entry, *prev;
+
+ for (entry = &irq_2_pin[irq]; ; entry = &irq_2_pin[entry->next]) {
+ if ((entry->apic == apic) && (entry->pin == pin))
+ break;
+ if (!entry->next)
+ BUG();
+ }
+
+ entry->pin = entry->apic = -1;
+
+ if (entry != &irq_2_pin[irq]) {
+ /* Removed entry is not at head of list. */
+ prev = &irq_2_pin[irq];
+ while (&irq_2_pin[prev->next] != entry)
+ prev = &irq_2_pin[prev->next];
+ prev->next = entry->next;
+ entry->next = irq_2_pin_free_entry;
+ irq_2_pin_free_entry = entry - irq_2_pin;
+ } else if (entry->next != 0) {
+ /* Removed entry is at head of multi-item list. */
+ prev = entry;
+ entry = &irq_2_pin[entry->next];
+ *prev = *entry;
+ entry->pin = entry->apic = -1;
+ entry->next = irq_2_pin_free_entry;
+ irq_2_pin_free_entry = entry - irq_2_pin;
+ }
+}
+
/*
* Reroute an IRQ to a different pin.
*/
@@ -959,6 +997,10 @@ static void __init enable_IO_APIC(void)
irq_2_pin[i].next = 0;
}
+ /* Initialise dynamic irq_2_pin free list. */
+ for (i = NR_IRQS; i < PIN_MAP_SIZE; i++)
+ irq_2_pin[i].next = i + 1;
+
/*
* The number of IO-APIC IRQ registers (== #pins):
*/
@@ -1854,11 +1896,17 @@ int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval)
return 0;
}
+#define WARN_BOGUS_WRITE(f, a...) \
+ DPRINTK("\n%s: apic=%d, pin=%d, old_irq=%d, new_irq=%d\n" \
+ "%s: old_entry=%08x, new_entry=%08x\n" \
+ "%s: " f, __FUNCTION__, apic, pin, old_irq, new_irq, \
+ __FUNCTION__, *(u32 *)&old_rte, *(u32 *)&new_rte, \
+ __FUNCTION__ , ##a )
+
int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
{
- int apic, pin, irq;
- struct IO_APIC_route_entry rte = { 0 };
- struct irq_pin_list *entry;
+ int apic, pin, old_irq = -1, new_irq = -1;
+ struct IO_APIC_route_entry old_rte = { 0 }, new_rte = { 0 };
unsigned long flags;
if ( (apic = ioapic_physbase_to_id(physbase)) < 0 )
@@ -1870,8 +1918,9 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
pin = (reg - 0x10) >> 1;
- *(u32 *)&rte = val;
- rte.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
+ /* Write first half from guest; second half is target info. */
+ *(u32 *)&new_rte = val;
+ new_rte.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
/*
* What about weird destination types?
@@ -1881,7 +1930,7 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
* ExtINT: Ignore? Linux only asserts this at start of day.
* For now, print a message and return an error. We can fix up on demand.
*/
- if ( rte.delivery_mode > dest_LowestPrio )
+ if ( new_rte.delivery_mode > dest_LowestPrio )
{
printk("ERROR: Attempt to write weird IOAPIC destination mode!\n");
printk(" APIC=%d/%d, lo-reg=%x\n", apic, pin, val);
@@ -1892,36 +1941,69 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
* The guest does not know physical APIC arrangement (flat vs. cluster).
* Apply genapic conventions for this platform.
*/
- rte.delivery_mode = INT_DELIVERY_MODE;
- rte.dest_mode = INT_DEST_MODE;
+ new_rte.delivery_mode = INT_DELIVERY_MODE;
+ new_rte.dest_mode = INT_DEST_MODE;
+
+ spin_lock_irqsave(&ioapic_lock, flags);
+
+ /* Read first (interesting) half of current routing entry. */
+ *(u32 *)&old_rte = io_apic_read(apic, 0x10 + 2 * pin);
- if ( rte.vector >= FIRST_DEVICE_VECTOR )
+ /* No change to the first half of the routing entry? Bail quietly. */
+ if ( *(u32 *)&old_rte == *(u32 *)&new_rte )
{
- /* Is there a valid irq mapped to this vector? */
- irq = vector_irq[rte.vector];
- if ( !IO_APIC_IRQ(irq) )
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+ return 0;
+ }
+
+ if ( old_rte.vector >= FIRST_DEVICE_VECTOR )
+ old_irq = vector_irq[old_rte.vector];
+ if ( new_rte.vector >= FIRST_DEVICE_VECTOR )
+ new_irq = vector_irq[new_rte.vector];
+
+ if ( (old_irq != new_irq) && (old_irq != -1) && IO_APIC_IRQ(old_irq) )
+ {
+ if ( irq_desc[IO_APIC_VECTOR(old_irq)].action )
+ {
+ WARN_BOGUS_WRITE("Attempt to remove IO-APIC pin of in-use IRQ!\n");
+ spin_unlock_irqrestore(&ioapic_lock, flags);
return 0;
+ }
- /* Set the correct irq-handling type. */
- irq_desc[IO_APIC_VECTOR(irq)].handler = rte.trigger ?
- &ioapic_level_type: &ioapic_edge_type;
+ remove_pin_at_irq(old_irq, apic, pin);
+ }
- /* Record the pin<->irq mapping. */
- for ( entry = &irq_2_pin[irq]; ; entry = &irq_2_pin[entry->next] )
+ if ( (new_irq != -1) && IO_APIC_IRQ(new_irq) )
+ {
+ if ( irq_desc[IO_APIC_VECTOR(new_irq)].action )
{
- if ( (entry->apic == apic) && (entry->pin == pin) )
- break;
- if ( !entry->next )
- {
- add_pin_to_irq(irq, apic, pin);
- break;
- }
+ WARN_BOGUS_WRITE("Attempt to %s IO-APIC pin for in-use IRQ!\n",
+ (old_irq != new_irq) ? "add" : "modify");
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+ return 0;
}
+
+ /* Set the correct irq-handling type. */
+ irq_desc[IO_APIC_VECTOR(new_irq)].handler = new_rte.trigger ?
+ &ioapic_level_type: &ioapic_edge_type;
+
+ if ( old_irq != new_irq )
+ add_pin_to_irq(new_irq, apic, pin);
+
+ /* Mask iff level triggered. */
+ new_rte.mask = new_rte.trigger;
+ }
+ else if ( !new_rte.mask )
+ {
+ /* This pin leads nowhere but the guest has not masked it. */
+ WARN_BOGUS_WRITE("Installing bogus unmasked IO-APIC entry!\n");
+ new_rte.mask = 1;
}
- spin_lock_irqsave(&ioapic_lock, flags);
- io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&rte) + 0));
- io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&rte) + 1));
+
+ io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&new_rte) + 0));
+ io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&new_rte) + 1));
+
spin_unlock_irqrestore(&ioapic_lock, flags);
return 0;
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index b260e9d627..5a0749fb4e 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -171,26 +171,20 @@ static void __do_IRQ_guest(int vector)
int pirq_guest_unmask(struct domain *d)
{
irq_desc_t *desc;
- unsigned int i, j, pirq;
- u32 m;
+ unsigned int pirq;
shared_info_t *s = d->shared_info;
- for ( i = 0; i < ARRAY_SIZE(d->pirq_mask); i++ )
+ for ( pirq = find_first_bit(d->pirq_mask, NR_PIRQS);
+ pirq < NR_PIRQS;
+ pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq+1) )
{
- m = d->pirq_mask[i];
- while ( m != 0 )
- {
- j = find_first_set_bit(m);
- m &= ~(1 << j);
- pirq = (i << 5) + j;
- desc = &irq_desc[irq_to_vector(pirq)];
- spin_lock_irq(&desc->lock);
- if ( !test_bit(d->pirq_to_evtchn[pirq], &s->evtchn_mask[0]) &&
- test_and_clear_bit(pirq, &d->pirq_mask) &&
- (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
- desc->handler->end(irq_to_vector(pirq));
- spin_unlock_irq(&desc->lock);
- }
+ desc = &irq_desc[irq_to_vector(pirq)];
+ spin_lock_irq(&desc->lock);
+ if ( !test_bit(d->pirq_to_evtchn[pirq], &s->evtchn_mask[0]) &&
+ test_and_clear_bit(pirq, &d->pirq_mask) &&
+ (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
+ desc->handler->end(irq_to_vector(pirq));
+ spin_unlock_irq(&desc->lock);
}
return 0;
diff --git a/xen/common/sched_sedf.c b/xen/common/sched_sedf.c
index 6e216195a8..71e6b9ba36 100644
--- a/xen/common/sched_sedf.c
+++ b/xen/common/sched_sedf.c
@@ -15,35 +15,24 @@
/*verbosity settings*/
#define SEDFLEVEL 0
-#define PRINT(_f, _a...) \
- if ((_f)<=SEDFLEVEL) printk(_a );
+#define PRINT(_f, _a...) \
+ do { \
+ if ( (_f) <= SEDFLEVEL ) \
+ printk(_a ); \
+ } while ( 0 )
#ifndef NDEBUG
#define SEDF_STATS
-#define CHECK(_p) if ( !(_p) ) \
- { printk("Check '%s' failed, line %d, file %s\n", #_p , __LINE__,\
- __FILE__);}
+#define CHECK(_p) \
+ do { \
+ if ( !(_p) ) \
+ printk("Check '%s' failed, line %d, file %s\n", \
+ #_p , __LINE__, __FILE__); \
+ } while ( 0 )
#else
#define CHECK(_p) ((void)0)
#endif
-/*various ways of unblocking domains*/
-#define UNBLOCK_ISOCHRONOUS_EDF 1
-#define UNBLOCK_EDF 2
-#define UNBLOCK_ATROPOS 3
-#define UNBLOCK_SHORT_RESUME 4
-#define UNBLOCK_BURST 5
-#define UNBLOCK_EXTRA_SUPPORT 6
-#define UNBLOCK UNBLOCK_EXTRA_SUPPORT
-
-/*various ways of treating extra-time*/
-#define EXTRA_OFF 1
-#define EXTRA_ROUNDR 2
-#define EXTRA_SLICE_WEIGHT 3
-#define EXTRA_BLOCK_WEIGHT 4
-
-#define EXTRA EXTRA_BLOCK_WEIGHT
-
#define EXTRA_NONE (0)
#define EXTRA_AWARE (1)
#define EXTRA_RUN_PEN (2)
@@ -68,8 +57,8 @@
struct sedf_dom_info {
struct domain *domain;
};
-struct sedf_vcpu_info
-{
+
+struct sedf_vcpu_info {
struct vcpu *vcpu;
struct list_head list;
struct list_head extralist[2];
@@ -85,10 +74,10 @@ struct sedf_vcpu_info
s_time_t latency;
/*status of domain*/
- int status;
+ int status;
/*weights for "Scheduling for beginners/ lazy/ etc." ;)*/
- short weight;
- short extraweight;
+ short weight;
+ short extraweight;
/*Bookkeeping*/
s_time_t deadl_abs;
s_time_t sched_start_abs;
@@ -123,28 +112,29 @@ struct sedf_cpu_info {
s_time_t current_slice_expires;
};
-#define EDOM_INFO(d) ((struct sedf_vcpu_info *)((d)->sched_priv))
-#define CPU_INFO(cpu) ((struct sedf_cpu_info *)schedule_data[cpu].sched_priv)
-#define LIST(d) (&EDOM_INFO(d)->list)
-#define EXTRALIST(d,i) (&(EDOM_INFO(d)->extralist[i]))
-#define RUNQ(cpu) (&CPU_INFO(cpu)->runnableq)
+#define EDOM_INFO(d) ((struct sedf_vcpu_info *)((d)->sched_priv))
+#define CPU_INFO(cpu) ((struct sedf_cpu_info *)schedule_data[cpu].sched_priv)
+#define LIST(d) (&EDOM_INFO(d)->list)
+#define EXTRALIST(d,i) (&(EDOM_INFO(d)->extralist[i]))
+#define RUNQ(cpu) (&CPU_INFO(cpu)->runnableq)
#define WAITQ(cpu) (&CPU_INFO(cpu)->waitq)
-#define EXTRAQ(cpu,i) (&(CPU_INFO(cpu)->extraq[i]))
+#define EXTRAQ(cpu,i) (&(CPU_INFO(cpu)->extraq[i]))
#define IDLETASK(cpu) ((struct vcpu *)schedule_data[cpu].idle)
#define PERIOD_BEGIN(inf) ((inf)->deadl_abs - (inf)->period)
-#define MIN(x,y) (((x)<(y))?(x):(y))
+#define MIN(x,y) (((x)<(y))?(x):(y))
#define DIV_UP(x,y) (((x) + (y) - 1) / y)
-#define extra_runs(inf) ((inf->status) & 6)
+#define extra_runs(inf) ((inf->status) & 6)
#define extra_get_cur_q(inf) (((inf->status & 6) >> 1)-1)
-#define sedf_runnable(edom) (!(EDOM_INFO(edom)->status & SEDF_ASLEEP))
+#define sedf_runnable(edom) (!(EDOM_INFO(edom)->status & SEDF_ASLEEP))
static void sedf_dump_cpu_state(int i);
-static inline int extraq_on(struct vcpu *d, int i) {
+static inline int extraq_on(struct vcpu *d, int i)
+{
return ((EXTRALIST(d,i)->next != NULL) &&
(EXTRALIST(d,i)->next != EXTRALIST(d,i)));
}
@@ -165,8 +155,8 @@ static inline void extraq_del(struct vcpu *d, int i)
{
struct list_head *list = EXTRALIST(d,i);
ASSERT(extraq_on(d,i));
- PRINT(3, "Removing domain %i.%i from L%i extraq\n", d->domain->domain_id,
- d->vcpu_id, i);
+ PRINT(3, "Removing domain %i.%i from L%i extraq\n",
+ d->domain->domain_id, d->vcpu_id, i);
list_del(list);
list->next = NULL;
ASSERT(!extraq_on(d, i));
@@ -178,94 +168,96 @@ static inline void extraq_del(struct vcpu *d, int i)
each entry, in order to avoid overflow. The algorithm works by simply
charging each domain that recieved extratime with an inverse of its weight.
*/
-static inline void extraq_add_sort_update(struct vcpu *d, int i, int sub) {
+static inline void extraq_add_sort_update(struct vcpu *d, int i, int sub)
+{
struct list_head *cur;
struct sedf_vcpu_info *curinf;
ASSERT(!extraq_on(d,i));
+
PRINT(3, "Adding domain %i.%i (score= %i, short_pen= %"PRIi64")"
" to L%i extraq\n",
d->domain->domain_id, d->vcpu_id, EDOM_INFO(d)->score[i],
EDOM_INFO(d)->short_block_lost_tot, i);
- /*iterate through all elements to find our "hole" and on our way
- update all the other scores*/
- list_for_each(cur,EXTRAQ(d->processor,i)){
+
+ /*
+ * Iterate through all elements to find our "hole" and on our way
+ * update all the other scores.
+ */
+ list_for_each ( cur, EXTRAQ(d->processor, i) )
+ {
curinf = list_entry(cur,struct sedf_vcpu_info,extralist[i]);
curinf->score[i] -= sub;
- if (EDOM_INFO(d)->score[i] < curinf->score[i])
+ if ( EDOM_INFO(d)->score[i] < curinf->score[i] )
break;
- else
- PRINT(4,"\tbehind domain %i.%i (score= %i)\n",
- curinf->vcpu->domain->domain_id,
- curinf->vcpu->vcpu_id, curinf->score[i]);
+ PRINT(4,"\tbehind domain %i.%i (score= %i)\n",
+ curinf->vcpu->domain->domain_id,
+ curinf->vcpu->vcpu_id, curinf->score[i]);
}
- /*cur now contains the element, before which we'll enqueue*/
+
+ /* cur now contains the element, before which we'll enqueue. */
PRINT(3, "\tlist_add to %p\n", cur->prev);
list_add(EXTRALIST(d,i),cur->prev);
- /*continue updating the extraq*/
- if ((cur != EXTRAQ(d->processor,i)) && sub)
- for (cur = cur->next; cur != EXTRAQ(d->processor,i);
- cur = cur-> next) {
- curinf = list_entry(cur,struct sedf_vcpu_info,
- extralist[i]);
+ /* Continue updating the extraq. */
+ if ( (cur != EXTRAQ(d->processor,i)) && sub )
+ {
+ for ( cur = cur->next; cur != EXTRAQ(d->processor,i); cur = cur->next )
+ {
+ curinf = list_entry(cur,struct sedf_vcpu_info, extralist[i]);
curinf->score[i] -= sub;
PRINT(4, "\tupdating domain %i.%i (score= %u)\n",
curinf->vcpu->domain->domain_id,
curinf->vcpu->vcpu_id, curinf->score[i]);
}
+ }
+
ASSERT(extraq_on(d,i));
}
-static inline void extraq_check(struct vcpu *d) {
- if (extraq_on(d, EXTRA_UTIL_Q)) {
- PRINT(2,"Dom %i.%i is on L1 extraQ\n",d->domain->domain_id, d->vcpu_id);
- if (!(EDOM_INFO(d)->status & EXTRA_AWARE) &&
- !extra_runs(EDOM_INFO(d))) {
+static inline void extraq_check(struct vcpu *d)
+{
+ if ( extraq_on(d, EXTRA_UTIL_Q) )
+ {
+ PRINT(2,"Dom %i.%i is on L1 extraQ\n",
+ d->domain->domain_id, d->vcpu_id);
+
+ if ( !(EDOM_INFO(d)->status & EXTRA_AWARE) &&
+ !extra_runs(EDOM_INFO(d)) )
+ {
extraq_del(d, EXTRA_UTIL_Q);
PRINT(2,"Removed dom %i.%i from L1 extraQ\n",
d->domain->domain_id, d->vcpu_id);
}
- } else {
- PRINT(2,"Dom %i.%i is NOT on L1 extraQ\n",d->domain->domain_id,
+ }
+ else
+ {
+ PRINT(2, "Dom %i.%i is NOT on L1 extraQ\n",
+ d->domain->domain_id,
d->vcpu_id);
- if ((EDOM_INFO(d)->status & EXTRA_AWARE) && sedf_runnable(d))
+
+ if ( (EDOM_INFO(d)->status & EXTRA_AWARE) && sedf_runnable(d) )
{
-#if (EXTRA == EXTRA_ROUNDR)
- extraq_add_tail(d, EXTRA_UTIL_Q);
-#elif (EXTRA == EXTRA_SLICE_WEIGHT || \
- EXTRA == EXTRA_BLOCK_WEIGHT)
extraq_add_sort_update(d, EXTRA_UTIL_Q, 0);
-#elif
- ;
-#endif
- PRINT(2,"Added dom %i.%i to L1 extraQ\n",d->domain->domain_id,
- d->vcpu_id);
+ PRINT(2,"Added dom %i.%i to L1 extraQ\n",
+ d->domain->domain_id, d->vcpu_id);
}
}
}
-static inline void extraq_check_add_unblocked(struct vcpu *d,
- int priority) {
+static inline void extraq_check_add_unblocked(struct vcpu *d, int priority)
+{
struct sedf_vcpu_info *inf = EDOM_INFO(d);
- if (inf->status & EXTRA_AWARE)
-#if (EXTRA == EXTRA_ROUNDR)
- if (priority)
- extraq_add_head(d,EXTRA_UTIL_Q);
- else
- extraq_add_tail(d,EXTRA_UTIL_Q);
-#elif (EXTRA == EXTRA_SLICE_WEIGHT \
- || EXTRA == EXTRA_BLOCK_WEIGHT)
- /*put in on the weighted extraq,
- without updating any scores*/
- extraq_add_sort_update(d, EXTRA_UTIL_Q, 0);
-#else
- ;
-#endif
+
+ if ( inf->status & EXTRA_AWARE )
+ /* Put on the weighted extraq without updating any scores. */
+ extraq_add_sort_update(d, EXTRA_UTIL_Q, 0);
}
-static inline int __task_on_queue(struct vcpu *d) {
+static inline int __task_on_queue(struct vcpu *d)
+{
return (((LIST(d))->next != NULL) && (LIST(d)->next != LIST(d)));
}
+
static inline void __del_from_queue(struct vcpu *d)
{
struct list_head *list = LIST(d);
@@ -279,42 +271,47 @@ static inline void __del_from_queue(struct vcpu *d)
typedef int(*list_comparer)(struct list_head* el1, struct list_head* el2);
-static inline void list_insert_sort(struct list_head *list,
- struct list_head *element, list_comparer comp) {
+static inline void list_insert_sort(
+ struct list_head *list, struct list_head *element, list_comparer comp)
+{
struct list_head *cur;
- /*iterate through all elements to find our "hole"*/
- list_for_each(cur,list){
- if (comp(element, cur) < 0)
+
+ /* Iterate through all elements to find our "hole". */
+ list_for_each( cur, list )
+ if ( comp(element, cur) < 0 )
break;
- }
- /*cur now contains the element, before which we'll enqueue*/
+
+ /* cur now contains the element, before which we'll enqueue. */
PRINT(3,"\tlist_add to %p\n",cur->prev);
list_add(element, cur->prev);
-}
+}
+
#define DOMAIN_COMPARER(name, field, comp1, comp2) \
int name##_comp(struct list_head* el1, struct list_head* el2) \
{ \
- struct sedf_vcpu_info *d1, *d2; \
- d1 = list_entry(el1,struct sedf_vcpu_info, field); \
- d2 = list_entry(el2,struct sedf_vcpu_info, field); \
- if ((comp1) == (comp2)) \
- return 0; \
- if ((comp1) < (comp2)) \
- return -1; \
- else \
- return 1; \
+ struct sedf_vcpu_info *d1, *d2; \
+ d1 = list_entry(el1,struct sedf_vcpu_info, field); \
+ d2 = list_entry(el2,struct sedf_vcpu_info, field); \
+ if ( (comp1) == (comp2) ) \
+ return 0; \
+ if ( (comp1) < (comp2) ) \
+ return -1; \
+ else \
+ return 1; \
}
+
/* adds a domain to the queue of processes which wait for the beginning of the
next period; this list is therefore sortet by this time, which is simply
absol. deadline - period
*/
-DOMAIN_COMPARER(waitq, list, PERIOD_BEGIN(d1), PERIOD_BEGIN(d2))
- static inline void __add_to_waitqueue_sort(struct vcpu *d) {
- ASSERT(!__task_on_queue(d));
+DOMAIN_COMPARER(waitq, list, PERIOD_BEGIN(d1), PERIOD_BEGIN(d2));
+static inline void __add_to_waitqueue_sort(struct vcpu *v)
+{
+ ASSERT(!__task_on_queue(v));
PRINT(3,"Adding domain %i.%i (bop= %"PRIu64") to waitq\n",
- d->domain->domain_id, d->vcpu_id, PERIOD_BEGIN(EDOM_INFO(d)));
- list_insert_sort(WAITQ(d->processor), LIST(d), waitq_comp);
- ASSERT(__task_on_queue(d));
+ v->domain->domain_id, v->vcpu_id, PERIOD_BEGIN(EDOM_INFO(v)));
+ list_insert_sort(WAITQ(v->processor), LIST(v), waitq_comp);
+ ASSERT(__task_on_queue(v));
}
/* adds a domain to the queue of processes which have started their current
@@ -322,60 +319,62 @@ DOMAIN_COMPARER(waitq, list, PERIOD_BEGIN(d1), PERIOD_BEGIN(d2))
on this list is running on the processor, if the list is empty the idle
task will run. As we are implementing EDF, this list is sorted by deadlines.
*/
-DOMAIN_COMPARER(runq, list, d1->deadl_abs, d2->deadl_abs)
- static inline void __add_to_runqueue_sort(struct vcpu *d) {
+DOMAIN_COMPARER(runq, list, d1->deadl_abs, d2->deadl_abs);
+static inline void __add_to_runqueue_sort(struct vcpu *v)
+{
PRINT(3,"Adding domain %i.%i (deadl= %"PRIu64") to runq\n",
- d->domain->domain_id, d->vcpu_id, EDOM_INFO(d)->deadl_abs);
- list_insert_sort(RUNQ(d->processor), LIST(d), runq_comp);
+ v->domain->domain_id, v->vcpu_id, EDOM_INFO(v)->deadl_abs);
+ list_insert_sort(RUNQ(v->processor), LIST(v), runq_comp);
}
/* Allocates memory for per domain private scheduling data*/
-static int sedf_alloc_task(struct vcpu *d)
+static int sedf_alloc_task(struct vcpu *v)
{
PRINT(2, "sedf_alloc_task was called, domain-id %i.%i\n",
- d->domain->domain_id, d->vcpu_id);
+ v->domain->domain_id, v->vcpu_id);
- if ( d->domain->sched_priv == NULL )
+ if ( v->domain->sched_priv == NULL )
{
- d->domain->sched_priv = xmalloc(struct sedf_dom_info);
- if ( d->domain->sched_priv == NULL )
+ v->domain->sched_priv = xmalloc(struct sedf_dom_info);
+ if ( v->domain->sched_priv == NULL )
return -1;
- memset(d->domain->sched_priv, 0, sizeof(struct sedf_dom_info));
+ memset(v->domain->sched_priv, 0, sizeof(struct sedf_dom_info));
}
- if ( (d->sched_priv = xmalloc(struct sedf_vcpu_info)) == NULL )
+ if ( (v->sched_priv = xmalloc(struct sedf_vcpu_info)) == NULL )
return -1;
- memset(d->sched_priv, 0, sizeof(struct sedf_vcpu_info));
+ memset(v->sched_priv, 0, sizeof(struct sedf_vcpu_info));
return 0;
}
/* Setup the sedf_dom_info */
-static void sedf_add_task(struct vcpu *d)
+static void sedf_add_task(struct vcpu *v)
{
- struct sedf_vcpu_info *inf = EDOM_INFO(d);
- inf->vcpu = d;
+ struct sedf_vcpu_info *inf = EDOM_INFO(v);
+
+ inf->vcpu = v;
- PRINT(2,"sedf_add_task was called, domain-id %i.%i\n",d->domain->domain_id,
- d->vcpu_id);
+ PRINT(2,"sedf_add_task was called, domain-id %i.%i\n",
+ v->domain->domain_id, v->vcpu_id);
/* Allocate per-CPU context if this is the first domain to be added. */
- if ( unlikely(schedule_data[d->processor].sched_priv == NULL) )
+ if ( unlikely(schedule_data[v->processor].sched_priv == NULL) )
{
- schedule_data[d->processor].sched_priv =
+ schedule_data[v->processor].sched_priv =
xmalloc(struct sedf_cpu_info);
- BUG_ON(schedule_data[d->processor].sched_priv == NULL);
- memset(CPU_INFO(d->processor), 0, sizeof(*CPU_INFO(d->processor)));
- INIT_LIST_HEAD(WAITQ(d->processor));
- INIT_LIST_HEAD(RUNQ(d->processor));
- INIT_LIST_HEAD(EXTRAQ(d->processor,EXTRA_PEN_Q));
- INIT_LIST_HEAD(EXTRAQ(d->processor,EXTRA_UTIL_Q));
+ BUG_ON(schedule_data[v->processor].sched_priv == NULL);
+ memset(CPU_INFO(v->processor), 0, sizeof(*CPU_INFO(v->processor)));
+ INIT_LIST_HEAD(WAITQ(v->processor));
+ INIT_LIST_HEAD(RUNQ(v->processor));
+ INIT_LIST_HEAD(EXTRAQ(v->processor,EXTRA_PEN_Q));
+ INIT_LIST_HEAD(EXTRAQ(v->processor,EXTRA_UTIL_Q));
}
- if ( d->domain->domain_id == 0 )
+ if ( v->domain->domain_id == 0 )
{
/*set dom0 to something useful to boot the machine*/
inf->period = MILLISECS(20);
@@ -400,14 +399,14 @@ static void sedf_add_task(struct vcpu *d)
INIT_LIST_HEAD(&(inf->extralist[EXTRA_PEN_Q]));
INIT_LIST_HEAD(&(inf->extralist[EXTRA_UTIL_Q]));
- if ( !is_idle_vcpu(d) )
+ if ( !is_idle_vcpu(v) )
{
- extraq_check(d);
+ extraq_check(v);
}
else
{
- EDOM_INFO(d)->deadl_abs = 0;
- EDOM_INFO(d)->status &= ~SEDF_ASLEEP;
+ EDOM_INFO(v)->deadl_abs = 0;
+ EDOM_INFO(v)->status &= ~SEDF_ASLEEP;
}
}
@@ -418,17 +417,11 @@ static void sedf_free_task(struct domain *d)
PRINT(2,"sedf_free_task was called, domain-id %i\n",d->domain_id);
- ASSERT(d->sched_priv != NULL);
xfree(d->sched_priv);
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
- {
if ( d->vcpu[i] )
- {
- ASSERT(d->vcpu[i]->sched_priv != NULL);
xfree(d->vcpu[i]->sched_priv);
- }
- }
}
/*
@@ -438,64 +431,60 @@ static void sedf_free_task(struct domain *d)
static void desched_edf_dom(s_time_t now, struct vcpu* d)
{
struct sedf_vcpu_info* inf = EDOM_INFO(d);
- /*current domain is running in real time mode*/
-
+
+ /* Current domain is running in real time mode. */
ASSERT(__task_on_queue(d));
- /*update the domains cputime*/
+
+ /* Update the domain's cputime. */
inf->cputime += now - inf->sched_start_abs;
- /*scheduling decisions, which don't remove the running domain
- from the runq*/
+ /*
+ * Scheduling decisions which don't remove the running domain from the
+ * runq.
+ */
if ( (inf->cputime < inf->slice) && sedf_runnable(d) )
return;
__del_from_queue(d);
- /*manage bookkeeping (i.e. calculate next deadline,
- memorize overun-time of slice) of finished domains*/
+ /*
+ * Manage bookkeeping (i.e. calculate next deadline, memorise
+ * overrun-time of slice) of finished domains.
+ */
if ( inf->cputime >= inf->slice )
{
inf->cputime -= inf->slice;
if ( inf->period < inf->period_orig )
{
- /*this domain runs in latency scaling or burst mode*/
-#if (UNBLOCK == UNBLOCK_BURST)
- /*if we are runnig in burst scaling wait for two periods
- before scaling periods up again*/
- if ( (now - inf->unblock_abs) >= (2 * inf->period) )
-#endif
+ /* This domain runs in latency scaling or burst mode. */
+ inf->period *= 2;
+ inf->slice *= 2;
+ if ( (inf->period > inf->period_orig) ||
+ (inf->slice > inf->slice_orig) )
{
- inf->period *= 2; inf->slice *= 2;
- if ( (inf->period > inf->period_orig) ||
- (inf->slice > inf->slice_orig) )
- {
- /*reset slice & period*/
- inf->period = inf->period_orig;
- inf->slice = inf->slice_orig;
- }
+ /* Reset slice and period. */
+ inf->period = inf->period_orig;
+ inf->slice = inf->slice_orig;
}
}
- /*set next deadline*/
+
+ /* Set next deadline. */
inf->deadl_abs += inf->period;
}
- /*add a runnable domain to the waitqueue*/
+ /* Add a runnable domain to the waitqueue. */
if ( sedf_runnable(d) )
{
__add_to_waitqueue_sort(d);
}
else
{
- /*we have a blocked realtime task -> remove it from exqs too*/
-#if (EXTRA > EXTRA_OFF)
-#if (EXTRA == EXTRA_BLOCK_WEIGHT)
+ /* We have a blocked realtime task -> remove it from exqs too. */
if ( extraq_on(d, EXTRA_PEN_Q) )
extraq_del(d, EXTRA_PEN_Q);
-#endif
if ( extraq_on(d, EXTRA_UTIL_Q) )
extraq_del(d, EXTRA_UTIL_Q);
-#endif
}
ASSERT(EQ(sedf_runnable(d), __task_on_queue(d)));
@@ -513,58 +502,57 @@ static void update_queues(
PRINT(3,"Updating waitq..\n");
- /*check for the first elements of the waitqueue, whether their
- next period has already started*/
- list_for_each_safe(cur, tmp, waitq) {
+ /*
+ * Check for the first elements of the waitqueue, whether their
+ * next period has already started.
+ */
+ list_for_each_safe ( cur, tmp, waitq )
+ {
curinf = list_entry(cur, struct sedf_vcpu_info, list);
PRINT(4,"\tLooking @ dom %i.%i\n",
curinf->vcpu->domain->domain_id, curinf->vcpu->vcpu_id);
- if ( PERIOD_BEGIN(curinf) <= now )
- {
- __del_from_queue(curinf->vcpu);
- __add_to_runqueue_sort(curinf->vcpu);
- }
- else
+ if ( PERIOD_BEGIN(curinf) > now )
break;
+ __del_from_queue(curinf->vcpu);
+ __add_to_runqueue_sort(curinf->vcpu);
}
PRINT(3,"Updating runq..\n");
- /*process the runq, find domains that are on
- the runqueue which shouldn't be there*/
- list_for_each_safe(cur, tmp, runq) {
+ /* Process the runq, find domains that are on the runq that shouldn't. */
+ list_for_each_safe ( cur, tmp, runq )
+ {
curinf = list_entry(cur,struct sedf_vcpu_info,list);
PRINT(4,"\tLooking @ dom %i.%i\n",
curinf->vcpu->domain->domain_id, curinf->vcpu->vcpu_id);
if ( unlikely(curinf->slice == 0) )
{
- /*ignore domains with empty slice*/
+ /* Ignore domains with empty slice. */
PRINT(4,"\tUpdating zero-slice domain %i.%i\n",
curinf->vcpu->domain->domain_id,
curinf->vcpu->vcpu_id);
__del_from_queue(curinf->vcpu);
- /*move them to their next period*/
+ /* Move them to their next period. */
curinf->deadl_abs += curinf->period;
- /*ensure that the start of the next period is in the future*/
+
+ /* Ensure that the start of the next period is in the future. */
if ( unlikely(PERIOD_BEGIN(curinf) < now) )
- {
curinf->deadl_abs +=
(DIV_UP(now - PERIOD_BEGIN(curinf),
- curinf->period)) * curinf->period;
- }
- /*and put them back into the queue*/
+ curinf->period)) * curinf->period;
+
+ /* Put them back into the queue. */
__add_to_waitqueue_sort(curinf->vcpu);
- continue;
}
-
- if ( unlikely((curinf->deadl_abs < now) ||
- (curinf->cputime > curinf->slice)) )
+ else if ( unlikely((curinf->deadl_abs < now) ||
+ (curinf->cputime > curinf->slice)) )
{
- /*we missed the deadline or the slice was
- already finished... might hapen because
- of dom_adj.*/
+ /*
+ * We missed the deadline or the slice was already finished.
+ * Might hapen because of dom_adj.
+ */
PRINT(4,"\tDomain %i.%i exceeded it's deadline/"
"slice (%"PRIu64" / %"PRIu64") now: %"PRIu64
" cputime: %"PRIu64"\n",
@@ -573,20 +561,23 @@ static void update_queues(
curinf->deadl_abs, curinf->slice, now,
curinf->cputime);
__del_from_queue(curinf->vcpu);
- /*common case: we miss one period!*/
+
+ /* Common case: we miss one period. */
curinf->deadl_abs += curinf->period;
- /*if we are still behind: modulo arithmetic,
- force deadline to be in future and
- aligned to period borders!*/
- if (unlikely(curinf->deadl_abs < now))
+ /*
+ * If we are still behind: modulo arithmetic, force deadline
+ * to be in future and aligned to period borders.
+ */
+ if ( unlikely(curinf->deadl_abs < now) )
curinf->deadl_abs +=
DIV_UP(now - curinf->deadl_abs,
curinf->period) * curinf->period;
ASSERT(curinf->deadl_abs >= now);
- /*give a fresh slice*/
+
+ /* Give a fresh slice. */
curinf->cputime = 0;
- if (PERIOD_BEGIN(curinf) > now)
+ if ( PERIOD_BEGIN(curinf) > now )
__add_to_waitqueue_sort(curinf->vcpu);
else
__add_to_runqueue_sort(curinf->vcpu);
@@ -594,43 +585,36 @@ static void update_queues(
else
break;
}
+
PRINT(3,"done updating the queues\n");
}
-#if (EXTRA > EXTRA_OFF)
/* removes a domain from the head of the according extraQ and
requeues it at a specified position:
round-robin extratime: end of extraQ
weighted ext.: insert in sorted list by score
if the domain is blocked / has regained its short-block-loss
time it is not put on any queue */
-static void desched_extra_dom(s_time_t now, struct vcpu* d)
+static void desched_extra_dom(s_time_t now, struct vcpu *d)
{
struct sedf_vcpu_info *inf = EDOM_INFO(d);
int i = extra_get_cur_q(inf);
-
-#if (EXTRA == EXTRA_SLICE_WEIGHT || EXTRA == EXTRA_BLOCK_WEIGHT)
- unsigned long oldscore;
-#endif
+ unsigned long oldscore;
+
ASSERT(extraq_on(d, i));
- /*unset all running flags*/
+
+ /* Unset all running flags. */
inf->status &= ~(EXTRA_RUN_PEN | EXTRA_RUN_UTIL);
- /*fresh slice for the next run*/
+ /* Fresh slice for the next run. */
inf->cputime = 0;
- /*accumulate total extratime*/
+ /* Accumulate total extratime. */
inf->extra_time_tot += now - inf->sched_start_abs;
- /*remove extradomain from head of the queue*/
+ /* Remove extradomain from head of the queue. */
extraq_del(d, i);
-#if (EXTRA == EXTRA_ROUNDR)
- if ( sedf_runnable(d) && (inf->status & EXTRA_AWARE) )
- /*add to the tail if it is runnable => round-robin*/
- extraq_add_tail(d, EXTRA_UTIL_Q);
-#elif (EXTRA == EXTRA_SLICE_WEIGHT || EXTRA == EXTRA_BLOCK_WEIGHT)
- /*update the score*/
+ /* Update the score. */
oldscore = inf->score[i];
-#if (EXTRA == EXTRA_BLOCK_WEIGHT)
if ( i == EXTRA_PEN_Q )
{
/*domain was running in L0 extraq*/
@@ -640,7 +624,8 @@ static void desched_extra_dom(s_time_t now, struct vcpu* d)
PRINT(3,"Domain %i.%i: Short_block_loss: %"PRIi64"\n",
inf->vcpu->domain->domain_id, inf->vcpu->vcpu_id,
inf->short_block_lost_tot);
- if (inf->short_block_lost_tot <= 0) {
+ if ( inf->short_block_lost_tot <= 0 )
+ {
PRINT(4,"Domain %i.%i compensated short block loss!\n",
inf->vcpu->domain->domain_id, inf->vcpu->vcpu_id);
/*we have (over-)compensated our block penalty*/
@@ -649,6 +634,7 @@ static void desched_extra_dom(s_time_t now, struct vcpu* d)
inf->status &= ~EXTRA_WANT_PEN_Q;
goto check_extra_queues;
}
+
/*we have to go again for another try in the block-extraq,
the score is not used incremantally here, as this is
already done by recalculating the block_lost*/
@@ -657,7 +643,6 @@ static void desched_extra_dom(s_time_t now, struct vcpu* d)
oldscore = 0;
}
else
-#endif
{
/*domain was running in L1 extraq => score is inverse of
utilization and is used somewhat incremental!*/
@@ -684,7 +669,6 @@ static void desched_extra_dom(s_time_t now, struct vcpu* d)
{
/*remove this blocked domain from the waitq!*/
__del_from_queue(d);
-#if (EXTRA == EXTRA_BLOCK_WEIGHT)
/*make sure that we remove a blocked domain from the other
extraq too*/
if ( i == EXTRA_PEN_Q )
@@ -697,14 +681,12 @@ static void desched_extra_dom(s_time_t now, struct vcpu* d)
if ( extraq_on(d, EXTRA_PEN_Q) )
extraq_del(d, EXTRA_PEN_Q);
}
-#endif
}
-#endif
+
ASSERT(EQ(sedf_runnable(d), __task_on_queue(d)));
ASSERT(IMPLY(extraq_on(d, EXTRA_UTIL_Q) || extraq_on(d, EXTRA_PEN_Q),
sedf_runnable(d)));
}
-#endif
static struct task_slice sedf_do_extra_schedule(
@@ -718,7 +700,6 @@ static struct task_slice sedf_do_extra_schedule(
if ( end_xt - now < EXTRA_QUANTUM )
goto return_idle;
-#if (EXTRA == EXTRA_BLOCK_WEIGHT)
if ( !list_empty(extraq[EXTRA_PEN_Q]) )
{
/*we still have elements on the level 0 extraq
@@ -733,7 +714,6 @@ static struct task_slice sedf_do_extra_schedule(
#endif
}
else
-#endif
{
if ( !list_empty(extraq[EXTRA_UTIL_Q]) )
{
@@ -772,11 +752,9 @@ static struct task_slice sedf_do_schedule(s_time_t now)
int cpu = smp_processor_id();
struct list_head *runq = RUNQ(cpu);
struct list_head *waitq = WAITQ(cpu);
-#if (EXTRA > EXTRA_OFF)
struct sedf_vcpu_info *inf = EDOM_INFO(current);
struct list_head *extraq[] = {
EXTRAQ(cpu, EXTRA_PEN_Q), EXTRAQ(cpu, EXTRA_UTIL_Q)};
-#endif
struct sedf_vcpu_info *runinf, *waitinf;
struct task_slice ret;
@@ -793,14 +771,12 @@ static struct task_slice sedf_do_schedule(s_time_t now)
if ( inf->status & SEDF_ASLEEP )
inf->block_abs = now;
-#if (EXTRA > EXTRA_OFF)
if ( unlikely(extra_runs(inf)) )
{
/*special treatment of domains running in extra time*/
desched_extra_dom(now, current);
}
else
-#endif
{
desched_edf_dom(now, current);
}
@@ -837,13 +813,8 @@ static struct task_slice sedf_do_schedule(s_time_t now)
waitinf = list_entry(waitq->next,struct sedf_vcpu_info, list);
/*we could not find any suitable domain
=> look for domains that are aware of extratime*/
-#if (EXTRA > EXTRA_OFF)
ret = sedf_do_extra_schedule(now, PERIOD_BEGIN(waitinf),
extraq, cpu);
-#else
- ret.task = IDLETASK(cpu);
- ret.time = PERIOD_BEGIN(waitinf) - now;
-#endif
CHECK(ret.time > 0);
}
else
@@ -891,14 +862,10 @@ static void sedf_sleep(struct vcpu *d)
{
if ( __task_on_queue(d) )
__del_from_queue(d);
-#if (EXTRA > EXTRA_OFF)
if ( extraq_on(d, EXTRA_UTIL_Q) )
extraq_del(d, EXTRA_UTIL_Q);
-#endif
-#if (EXTRA == EXTRA_BLOCK_WEIGHT)
if ( extraq_on(d, EXTRA_PEN_Q) )
extraq_del(d, EXTRA_PEN_Q);
-#endif
}
}
@@ -939,7 +906,7 @@ static void sedf_sleep(struct vcpu *d)
* -addition: experiments have shown that this may have a HUGE impact on
* performance of other domains, becaus it can lead to excessive context
* switches
-
+ *
* Part2: Long Unblocking
* Part 2a
* -it is obvious that such accounting of block time, applied when
@@ -974,32 +941,6 @@ static void sedf_sleep(struct vcpu *d)
* -either behaviour can lead to missed deadlines in other domains as
* opposed to approaches 1,2a,2b
*/
-#if (UNBLOCK <= UNBLOCK_SHORT_RESUME)
-static void unblock_short_vcons(struct sedf_vcpu_info* inf, s_time_t now)
-{
- inf->deadl_abs += inf->period;
- inf->cputime = 0;
-}
-#endif
-
-#if (UNBLOCK == UNBLOCK_SHORT_RESUME)
-static void unblock_short_cons(struct sedf_vcpu_info* inf, s_time_t now)
-{
- /*treat blocked time as consumed by the domain*/
- inf->cputime += now - inf->block_abs;
- if ( (inf->cputime + EXTRA_QUANTUM) > inf->slice )
- {
- /*we don't have a reasonable amount of time in
- our slice left :( => start in next period!*/
- unblock_short_vcons(inf, now);
- }
-#ifdef SEDF_STATS
- else
- inf->short_cont++;
-#endif
-}
-#endif
-
static void unblock_short_extra_support(
struct sedf_vcpu_info* inf, s_time_t now)
{
@@ -1051,33 +992,6 @@ static void unblock_short_extra_support(
}
-#if (UNBLOCK == UNBLOCK_ISOCHRONOUS_EDF)
-static void unblock_long_vcons(struct sedf_vcpu_info* inf, s_time_t now)
-{
- /* align to next future period */
- inf->deadl_abs += (DIV_UP(now - inf->deadl_abs, inf->period) +1)
- * inf->period;
- inf->cputime = 0;
-}
-#endif
-
-
-#if 0
-static void unblock_long_cons_a (struct sedf_vcpu_info* inf, s_time_t now)
-{
- /*treat the time the domain was blocked in the
- CURRENT period as consumed by the domain*/
- inf->cputime = (now - inf->deadl_abs) % inf->period;
- if ( (inf->cputime + EXTRA_QUANTUM) > inf->slice )
- {
- /*we don't have a reasonable amount of time in our slice
- left :( => start in next period!*/
- unblock_long_vcons(inf, now);
- }
-}
-#endif
-
-
static void unblock_long_cons_b(struct sedf_vcpu_info* inf,s_time_t now)
{
/*Conservative 2b*/
@@ -1087,110 +1001,6 @@ static void unblock_long_cons_b(struct sedf_vcpu_info* inf,s_time_t now)
}
-#if (UNBLOCK == UNBLOCK_ATROPOS)
-static void unblock_long_cons_c(struct sedf_vcpu_info* inf,s_time_t now)
-{
- if ( likely(inf->latency) )
- {
- /*scale the slice and period accordingly to the latency hint*/
- /*reduce period temporarily to the latency hint*/
- inf->period = inf->latency;
- /*this results in max. 4s slice/period length*/
- ASSERT((inf->period < ULONG_MAX)
- && (inf->slice_orig < ULONG_MAX));
- /*scale slice accordingly, so that utilisation stays the same*/
- inf->slice = (inf->period * inf->slice_orig)
- / inf->period_orig;
- inf->deadl_abs = now + inf->period;
- inf->cputime = 0;
- }
- else
- {
- /*we don't have a latency hint.. use some other technique*/
- unblock_long_cons_b(inf, now);
- }
-}
-#endif
-
-
-#if (UNBLOCK == UNBLOCK_BURST)
-/*a new idea of dealing with short blocks: burst period scaling*/
-static void unblock_short_burst(struct sedf_vcpu_info* inf, s_time_t now)
-{
- /*treat blocked time as consumed by the domain*/
- inf->cputime += now - inf->block_abs;
-
- if ( (inf->cputime + EXTRA_QUANTUM) <= inf->slice )
- {
- /*if we can still use some time in the current slice
- then use it!*/
-#ifdef SEDF_STATS
- /*we let the domain run in the current period*/
- inf->short_cont++;
-#endif
- }
- else
- {
- /*we don't have a reasonable amount of time in
- our slice left => switch to burst mode*/
- if ( likely(inf->unblock_abs) )
- {
- /*set the period-length to the current blocking
- interval, possible enhancements: average over last
- blocking intervals, user-specified minimum,...*/
- inf->period = now - inf->unblock_abs;
- /*check for overflow on multiplication*/
- ASSERT((inf->period < ULONG_MAX)
- && (inf->slice_orig < ULONG_MAX));
- /*scale slice accordingly, so that utilisation
- stays the same*/
- inf->slice = (inf->period * inf->slice_orig)
- / inf->period_orig;
- /*set new (shorter) deadline*/
- inf->deadl_abs += inf->period;
- }
- else
- {
- /*in case we haven't unblocked before
- start in next period!*/
- inf->cputime=0;
- inf->deadl_abs += inf->period;
- }
- }
-
- inf->unblock_abs = now;
-}
-
-
-static void unblock_long_burst(struct sedf_vcpu_info* inf, s_time_t now)
-{
- if ( unlikely(inf->latency && (inf->period > inf->latency)) )
- {
- /*scale the slice and period accordingly to the latency hint*/
- inf->period = inf->latency;
- /*check for overflows on multiplication*/
- ASSERT((inf->period < ULONG_MAX)
- && (inf->slice_orig < ULONG_MAX));
- /*scale slice accordingly, so that utilisation stays the same*/
- inf->slice = (inf->period * inf->slice_orig)
- / inf->period_orig;
- inf->deadl_abs = now + inf->period;
- inf->cputime = 0;
- }
- else
- {
- /*we don't have a latency hint.. or we are currently in
- "burst mode": use some other technique
- NB: this should be in fact the normal way of operation,
- when we are in sync with the device!*/
- unblock_long_cons_b(inf, now);
- }
-
- inf->unblock_abs = now;
-}
-#endif /* UNBLOCK == UNBLOCK_BURST */
-
-
#define DOMAIN_EDF 1
#define DOMAIN_EXTRA_PEN 2
#define DOMAIN_EXTRA_UTIL 3
@@ -1225,32 +1035,31 @@ static inline int should_switch(struct vcpu *cur,
cur_inf = EDOM_INFO(cur);
other_inf = EDOM_INFO(other);
- /*check whether we need to make an earlier sched-decision*/
- if (PERIOD_BEGIN(other_inf) <
- CPU_INFO(other->processor)->current_slice_expires)
+ /* Check whether we need to make an earlier scheduling decision. */
+ if ( PERIOD_BEGIN(other_inf) <
+ CPU_INFO(other->processor)->current_slice_expires )
return 1;
- /*no timing-based switches need to be taken into account here*/
- switch (get_run_type(cur)) {
+
+ /* No timing-based switches need to be taken into account here. */
+ switch ( get_run_type(cur) )
+ {
case DOMAIN_EDF:
- /* do not interrupt a running EDF domain */
+ /* Do not interrupt a running EDF domain. */
return 0;
case DOMAIN_EXTRA_PEN:
- /*check whether we also want
- the L0 ex-q with lower score*/
- if ((other_inf->status & EXTRA_WANT_PEN_Q)
- && (other_inf->score[EXTRA_PEN_Q] <
- cur_inf->score[EXTRA_PEN_Q]))
- return 1;
- else return 0;
+ /* Check whether we also want the L0 ex-q with lower score. */
+ return ((other_inf->status & EXTRA_WANT_PEN_Q) &&
+ (other_inf->score[EXTRA_PEN_Q] <
+ cur_inf->score[EXTRA_PEN_Q]));
case DOMAIN_EXTRA_UTIL:
- /*check whether we want the L0 extraq, don't
- switch if both domains want L1 extraq */
- if (other_inf->status & EXTRA_WANT_PEN_Q)
- return 1;
- else return 0;
+ /* Check whether we want the L0 extraq. Don't
+ * switch if both domains want L1 extraq.
+ */
+ return !!(other_inf->status & EXTRA_WANT_PEN_Q);
case DOMAIN_IDLE:
return 1;
}
+
return 1;
}
@@ -1295,7 +1104,6 @@ void sedf_wake(struct vcpu *d)
{
PRINT(4,"extratime unblock\n");
/* unblocking in extra-time! */
-#if (EXTRA == EXTRA_BLOCK_WEIGHT)
if ( inf->status & EXTRA_WANT_PEN_Q )
{
/*we have a domain that wants compensation
@@ -1304,7 +1112,6 @@ void sedf_wake(struct vcpu *d)
chance!*/
extraq_add_sort_update(d, EXTRA_PEN_Q, 0);
}
-#endif
extraq_check_add_unblocked(d, 0);
}
else
@@ -1316,15 +1123,7 @@ void sedf_wake(struct vcpu *d)
#ifdef SEDF_STATS
inf->short_block_tot++;
#endif
-#if (UNBLOCK <= UNBLOCK_ATROPOS)
- unblock_short_vcons(inf, now);
-#elif (UNBLOCK == UNBLOCK_SHORT_RESUME)
- unblock_short_cons(inf, now);
-#elif (UNBLOCK == UNBLOCK_BURST)
- unblock_short_burst(inf, now);
-#elif (UNBLOCK == UNBLOCK_EXTRA_SUPPORT)
unblock_short_extra_support(inf, now);
-#endif
extraq_check_add_unblocked(d, 1);
}
@@ -1335,18 +1134,7 @@ void sedf_wake(struct vcpu *d)
#ifdef SEDF_STATS
inf->long_block_tot++;
#endif
-#if (UNBLOCK == UNBLOCK_ISOCHRONOUS_EDF)
- unblock_long_vcons(inf, now);
-#elif (UNBLOCK == UNBLOCK_EDF \
- || UNBLOCK == UNBLOCK_EXTRA_SUPPORT)
- unblock_long_cons_b(inf, now);
-#elif (UNBLOCK == UNBLOCK_ATROPOS)
- unblock_long_cons_c(inf, now);
-#elif (UNBLOCK == UNBLOCK_SHORT_RESUME)
unblock_long_cons_b(inf, now);
-#elif (UNBLOCK == UNBLOCK_BURST)
- unblock_long_burst(inf, now);
-#endif
extraq_check_add_unblocked(d, 1);
}
@@ -1528,7 +1316,7 @@ static int sedf_adjust_weights(struct sched_adjdom_cmd *cmd)
sumt[cpu] = 0;
}
- /* sum up all weights */
+ /* Sum across all weights. */
for_each_domain( d )
{
for_each_vcpu( d, p )
@@ -1553,7 +1341,7 @@ static int sedf_adjust_weights(struct sched_adjdom_cmd *cmd)
}
}
- /* adjust all slices (and periods) to the new weight */
+ /* Adjust all slices (and periods) to the new weight. */
for_each_domain( d )
{
for_each_vcpu ( d, p )
@@ -1580,35 +1368,42 @@ static int sedf_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd)
{
struct vcpu *v;
- PRINT(2,"sedf_adjdom was called, domain-id %i new period %"PRIu64" "\
+ PRINT(2,"sedf_adjdom was called, domain-id %i new period %"PRIu64" "
"new slice %"PRIu64"\nlatency %"PRIu64" extra:%s\n",
p->domain_id, cmd->u.sedf.period, cmd->u.sedf.slice,
cmd->u.sedf.latency, (cmd->u.sedf.extratime)?"yes":"no");
if ( cmd->direction == SCHED_INFO_PUT )
{
- /*check for sane parameters*/
- if (!cmd->u.sedf.period && !cmd->u.sedf.weight)
+ /* Check for sane parameters. */
+ if ( !cmd->u.sedf.period && !cmd->u.sedf.weight )
return -EINVAL;
- if (cmd->u.sedf.weight) {
- if ((cmd->u.sedf.extratime & EXTRA_AWARE) &&
- (! cmd->u.sedf.period)) {
- /*weight driven domains with xtime ONLY!*/
- for_each_vcpu(p, v) {
+ if ( cmd->u.sedf.weight )
+ {
+ if ( (cmd->u.sedf.extratime & EXTRA_AWARE) &&
+ (!cmd->u.sedf.period) )
+ {
+ /* Weight-driven domains with extratime only. */
+ for_each_vcpu ( p, v )
+ {
EDOM_INFO(v)->extraweight = cmd->u.sedf.weight;
EDOM_INFO(v)->weight = 0;
EDOM_INFO(v)->slice = 0;
EDOM_INFO(v)->period = WEIGHT_PERIOD;
}
- } else {
- /*weight driven domains with real-time execution*/
- for_each_vcpu(p, v)
+ }
+ else
+ {
+ /* Weight-driven domains with real-time execution. */
+ for_each_vcpu ( p, v )
EDOM_INFO(v)->weight = cmd->u.sedf.weight;
}
}
- else {
- /*time driven domains*/
- for_each_vcpu(p, v) {
+ else
+ {
+ /* Time-driven domains. */
+ for_each_vcpu ( p, v )
+ {
/*
* Sanity checking: note that disabling extra weight requires
* that we set a non-zero slice.
@@ -1626,10 +1421,12 @@ static int sedf_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd)
EDOM_INFO(v)->slice = cmd->u.sedf.slice;
}
}
- if (sedf_adjust_weights(cmd))
+
+ if ( sedf_adjust_weights(cmd) )
return -EINVAL;
-
- for_each_vcpu(p, v) {
+
+ for_each_vcpu ( p, v )
+ {
EDOM_INFO(v)->status =
(EDOM_INFO(v)->status &
~EXTRA_AWARE) | (cmd->u.sedf.extratime & EXTRA_AWARE);
@@ -1641,11 +1438,11 @@ static int sedf_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd)
{
cmd->u.sedf.period = EDOM_INFO(p->vcpu[0])->period;
cmd->u.sedf.slice = EDOM_INFO(p->vcpu[0])->slice;
- cmd->u.sedf.extratime = EDOM_INFO(p->vcpu[0])->status
- & EXTRA_AWARE;
+ cmd->u.sedf.extratime = EDOM_INFO(p->vcpu[0])->status & EXTRA_AWARE;
cmd->u.sedf.latency = EDOM_INFO(p->vcpu[0])->latency;
cmd->u.sedf.weight = EDOM_INFO(p->vcpu[0])->weight;
}
+
PRINT(2,"sedf_adjdom_finished\n");
return 0;
}
diff --git a/xen/common/trace.c b/xen/common/trace.c
index b0594aa0a8..dbd0f7e7a0 100644
--- a/xen/common/trace.c
+++ b/xen/common/trace.c
@@ -27,6 +27,8 @@
#include <xen/smp.h>
#include <xen/trace.h>
#include <xen/errno.h>
+#include <xen/event.h>
+#include <xen/softirq.h>
#include <xen/init.h>
#include <asm/atomic.h>
#include <public/dom0_ops.h>
@@ -40,6 +42,11 @@ static struct t_buf *t_bufs[NR_CPUS];
static struct t_rec *t_recs[NR_CPUS];
static int nr_recs;
+/* High water mark for trace buffers; */
+/* Send virtual interrupt when buffer level reaches this point */
+static int t_buf_highwater;
+
+
/* a flag recording whether initialization has been done */
/* or more properly, if the tbuf subsystem is enabled right now */
int tb_init_done;
@@ -50,6 +57,12 @@ static unsigned long tb_cpu_mask = (~0UL);
/* which tracing events are enabled */
static u32 tb_event_mask = TRC_ALL;
+static void trace_notify_guest(void)
+{
+ send_guest_global_virq(dom0, VIRQ_TBUF);
+}
+
+
/**
* alloc_trace_bufs - performs initialization of the per-cpu trace buffers.
*
@@ -93,6 +106,9 @@ static int alloc_trace_bufs(void)
t_recs[i] = (struct t_rec *)(buf + 1);
}
+ t_buf_highwater = nr_recs >> 1; /* 50% high water */
+ open_softirq(TRACE_SOFTIRQ, trace_notify_guest);
+
return 0;
}
@@ -272,6 +288,13 @@ void trace(u32 event, unsigned long d1, unsigned long d2,
buf->prod++;
local_irq_restore(flags);
+
+ /*
+ * Notify trace buffer consumer that we've reached the high water mark.
+ *
+ */
+ if ( (buf->prod - buf->cons) == t_buf_highwater )
+ raise_softirq(TRACE_SOFTIRQ);
}
/*
diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
index e18fbf9669..8b2faffc6f 100644
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -77,6 +77,7 @@
#define VIRQ_DEBUG 1 /* V. Request guest to dump debug info. */
#define VIRQ_CONSOLE 2 /* G. (DOM0) Bytes received on emergency console. */
#define VIRQ_DOM_EXC 3 /* G. (DOM0) Exceptional event for some domain. */
+#define VIRQ_TBUF 4 /* G. (DOM0) Trace buffer has records available. */
#define VIRQ_DEBUGGER 6 /* G. (DOM0) A domain has paused for debugging. */
#define VIRQ_XENOPROF 7 /* V. XenOprofile interrupt: new sample available */
#define NR_VIRQS 8
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 1ea48aae7d..bd01f83d27 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -134,7 +134,7 @@ struct domain
*/
#define NR_PIRQS 256 /* Put this somewhere sane! */
u16 pirq_to_evtchn[NR_PIRQS];
- u32 pirq_mask[NR_PIRQS/32];
+ DECLARE_BITMAP(pirq_mask, NR_PIRQS);
/* I/O capabilities (access to IRQs and memory-mapped I/O). */
struct rangeset *iomem_caps;
diff --git a/xen/include/xen/softirq.h b/xen/include/xen/softirq.h
index 9293b3168e..f4d484f43b 100644
--- a/xen/include/xen/softirq.h
+++ b/xen/include/xen/softirq.h
@@ -9,7 +9,8 @@
#define NMI_SOFTIRQ 4
#define PAGE_SCRUB_SOFTIRQ 5
#define DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ 6
-#define NR_SOFTIRQS 7
+#define TRACE_SOFTIRQ 7
+#define NR_SOFTIRQS 8
#ifndef __ASSEMBLY__