From 97a7c0c266c59380eac2552ba211bd0983710d61 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 7 Apr 2006 13:40:22 +0100 Subject: [PATCH 01/22] Power down an x86 system directly within domain0 rather than executing a shutdown hypercall. Domain0 is able to execute ACPI power-off code. Signed-off-by: Harry Butterworth --- linux-2.6-xen-sparse/drivers/xen/core/reboot.c | 4 ++++ 1 file changed, 4 insertions(+) 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); } From 9958cf716758bb5f709f09ab32670f4e950a36e0 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 7 Apr 2006 13:41:58 +0100 Subject: [PATCH 02/22] Do not disable spurious irq debugging in i386 xenlinux. It may be masking underlying problems, and the problem it was intended to work around should be fixed properly. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c | 4 ---- 1 file changed, 4 deletions(-) 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) { From 28a88159e342cfc5d6986edb7fe3d9f5747cfaad Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 7 Apr 2006 14:26:02 +0100 Subject: [PATCH 03/22] Avoid double slashes in linker object file lists. Signed-off-by: Keir Fraser --- xen/Rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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. From f5de363eff322d17f0eecdaad7f653ecb8d338f5 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 7 Apr 2006 14:27:46 +0100 Subject: [PATCH 04/22] Turn pirq_mask into a generic bitmap type. Signed-off-by: Keir Fraser --- xen/arch/ia64/xen/irq.c | 27 +++++++++++---------------- xen/arch/x86/irq.c | 28 +++++++++++----------------- xen/include/xen/sched.h | 2 +- 3 files changed, 23 insertions(+), 34 deletions(-) diff --git a/xen/arch/ia64/xen/irq.c b/xen/arch/ia64/xen/irq.c index c42b5e2944..e7d0862d9c 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) ) { - 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/irq.c b/xen/arch/x86/irq.c index b260e9d627..0b9d88037b 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) ) { - 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/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; From 6ca8eebc9bf8131c6adb05b2da5580cd10a9ef5b Mon Sep 17 00:00:00 2001 From: "smh22@firebug.cl.cam.ac.uk" Date: Fri, 7 Apr 2006 15:58:00 +0100 Subject: [PATCH 05/22] Additional sanity / compatability checks during guest build. Signed-off-by: Steven Hand --- tools/libxc/xc_linux_build.c | 38 +++++++++++++++++++++++++++++++----- tools/libxc/xc_load_elf.c | 15 ++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) 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."); From 41dca18e001ad9657ec6cf284dbda003c3822375 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 7 Apr 2006 16:15:44 +0100 Subject: [PATCH 06/22] Fix my slightly broken change to pirq_mask logic -- we must pass the last seen bit *plus 1* to find_next_bit(). Signed-off-by: Keir Fraser --- xen/arch/ia64/xen/irq.c | 2 +- xen/arch/x86/irq.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/arch/ia64/xen/irq.c b/xen/arch/ia64/xen/irq.c index e7d0862d9c..350ec72435 100644 --- a/xen/arch/ia64/xen/irq.c +++ b/xen/arch/ia64/xen/irq.c @@ -1363,7 +1363,7 @@ int pirq_guest_unmask(struct domain *d) for ( pirq = find_first_bit(d->pirq_mask, NR_PIRQS); pirq < NR_PIRQS; - pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq) ) + pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq+1) ) { desc = &irq_desc[pirq]; spin_lock_irq(&desc->lock); diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 0b9d88037b..5a0749fb4e 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -176,7 +176,7 @@ int pirq_guest_unmask(struct domain *d) for ( pirq = find_first_bit(d->pirq_mask, NR_PIRQS); pirq < NR_PIRQS; - pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq) ) + pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq+1) ) { desc = &irq_desc[irq_to_vector(pirq)]; spin_lock_irq(&desc->lock); From b59014bf578e547db1903d3f432e41a8eb3e942f Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 7 Apr 2006 18:41:28 +0100 Subject: [PATCH 07/22] Robustify and add tracing to the IO-APIC update hypercall. If this patch, and any others that follow it, fix some of the prblems that various users have been seeing then they may be good candidates for backporting to 3.0.2 (assuming no regressions for other users). Signed-off-by: Keir Fraser --- xen/arch/x86/io_apic.c | 156 ++++++++++++++++++++++++++++++----------- 1 file changed, 117 insertions(+), 39 deletions(-) diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c index 18d8ed961c..ca180d3bf7 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,54 @@ 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; + int idx; + + 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 = -1; + entry->apic = -1; + + idx = entry - irq_2_pin; + if (idx >= NR_IRQS) { + while (prev->next != idx) + prev = &irq_2_pin[prev->next]; + prev->next = entry->next; + entry->next = irq_2_pin_free_entry; + irq_2_pin_free_entry = idx; + } else { + entry->next = 0; + } +} + /* * Reroute an IRQ to a different pin. */ @@ -959,6 +992,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 +1891,18 @@ int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval) return 0; } +#define WARN_BOGUS_WRITE(f, a...) \ + printk("%s: apic=%d,pin=%d,oirq=%d,nirq=%d\n" \ + "%s: oent=%08x:%08x,nent=%08x:%08x\n" \ + "%s: " f, __FUNCTION__, apic, pin, old_irq, new_irq, \ + __FUNCTION__, *(u32 *)&old_rte, *((u32 *)&old_rte+1), \ + *(u32 *)&new_rte, *((u32 *)&new_rte+1), \ + __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 +1914,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 +1926,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 +1937,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; - - if ( rte.vector >= FIRST_DEVICE_VECTOR ) - { - /* Is there a valid irq mapped to this vector? */ - irq = vector_irq[rte.vector]; - if ( !IO_APIC_IRQ(irq) ) - return 0; - - /* Set the correct irq-handling type. */ - irq_desc[IO_APIC_VECTOR(irq)].handler = rte.trigger ? - &ioapic_level_type: &ioapic_edge_type; - - /* Record the pin<->irq mapping. */ - for ( entry = &irq_2_pin[irq]; ; entry = &irq_2_pin[entry->next] ) - { - if ( (entry->apic == apic) && (entry->pin == pin) ) - break; - if ( !entry->next ) - { - add_pin_to_irq(irq, apic, pin); - break; - } - } - } + new_rte.delivery_mode = INT_DELIVERY_MODE; + new_rte.dest_mode = INT_DEST_MODE; 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)); + + /* Read first (interesting) half of current routing entry. */ + *(u32 *)&old_rte = io_apic_read(apic, 0x10 + 2 * pin); + + /* No change to the first half of the routing entry? Bail quietly. */ + if ( *(u32 *)&old_rte == *(u32 *)&new_rte ) + { + 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; + } + + remove_pin_at_irq(old_irq, apic, pin); + } + + if ( (new_irq != -1) && IO_APIC_IRQ(new_irq) ) + { + if ( irq_desc[IO_APIC_VECTOR(new_irq)].action ) + { + 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; + } + + + 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; From b766b4774afbaf01a0b2291e4d9add1df953dc11 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 8 Apr 2006 09:05:53 +0100 Subject: [PATCH 08/22] Added trace buffer virtual irq to implement non-polling trace record access. Signed-off-by: Rob Gardner --- xen/common/trace.c | 23 +++++++++++++++++++++++ xen/include/public/xen.h | 1 + xen/include/xen/softirq.h | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-) 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 #include #include +#include +#include #include #include #include @@ -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/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__ From ee29f146c33b704a5e256fe0a36b851d021c1225 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 8 Apr 2006 11:01:17 +0100 Subject: [PATCH 09/22] Fix remove_pin_at_irq(), introduced with changeset 9586:f84a333d8aa6e1a25e2b73b07610e95007267f6a. Signed-off-by: Keir Fraser --- xen/arch/x86/io_apic.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c index ca180d3bf7..97aae7a77d 100644 --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -110,7 +110,6 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin) static void remove_pin_at_irq(unsigned int irq, int apic, int pin) { struct irq_pin_list *entry, *prev; - int idx; for (entry = &irq_2_pin[irq]; ; entry = &irq_2_pin[entry->next]) { if ((entry->apic == apic) && (entry->pin == pin)) @@ -119,18 +118,24 @@ static void remove_pin_at_irq(unsigned int irq, int apic, int pin) BUG(); } - entry->pin = -1; - entry->apic = -1; + entry->pin = entry->apic = -1; - idx = entry - irq_2_pin; - if (idx >= NR_IRQS) { - while (prev->next != idx) + 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 = idx; - } else { - entry->next = 0; + 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; } } From ea121d62ab22604f2adc008d6a8740fa3d186b11 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 8 Apr 2006 12:09:25 +0100 Subject: [PATCH 10/22] Clean up IO-APIC update tracing and demote to DPRINTK(). Signed-off-by: Keir Fraser --- xen/arch/x86/io_apic.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c index 97aae7a77d..715b7d294d 100644 --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -1897,12 +1897,11 @@ int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval) } #define WARN_BOGUS_WRITE(f, a...) \ - printk("%s: apic=%d,pin=%d,oirq=%d,nirq=%d\n" \ - "%s: oent=%08x:%08x,nent=%08x:%08x\n" \ - "%s: " f, __FUNCTION__, apic, pin, old_irq, new_irq, \ - __FUNCTION__, *(u32 *)&old_rte, *((u32 *)&old_rte+1), \ - *(u32 *)&new_rte, *((u32 *)&new_rte+1), \ - __FUNCTION__ , ##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) { From 90027f708a554da0cf6f572883482b499714c697 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 8 Apr 2006 12:10:04 +0100 Subject: [PATCH 11/22] Build CONFIG_PNP_ACPI by default. Signed-off-by: Keir Fraser --- buildconfigs/linux-defconfig_xen0_x86_32 | 26 +++++++++++++++--------- buildconfigs/linux-defconfig_xen0_x86_64 | 8 +++++++- buildconfigs/linux-defconfig_xen_x86_32 | 4 ++-- buildconfigs/linux-defconfig_xen_x86_64 | 8 +++++++- 4 files changed, 32 insertions(+), 14 deletions(-) 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..25cc732d0b 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 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..ba7c616d8c 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 From 72c295faefc8c2c156a4d0d6fd513be1e5448160 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 9 Apr 2006 18:23:16 +0100 Subject: [PATCH 12/22] Remove various compile-time options from SEDF scheduler and clean up formatting. Signed-off-by: Keir Fraser --- xen/common/sched_sedf.c | 729 +++++++++++++++------------------------- 1 file changed, 263 insertions(+), 466 deletions(-) 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*/ - __add_to_waitqueue_sort(curinf->vcpu); - continue; - } + curinf->period)) * curinf->period; - if ( unlikely((curinf->deadl_abs < now) || - (curinf->cputime > curinf->slice)) ) + /* Put them back into the queue. */ + __add_to_waitqueue_sort(curinf->vcpu); + } + 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; } From d36204c3835c794d014c0da489eaf41c517f4fe6 Mon Sep 17 00:00:00 2001 From: "ack@kneesa.uk.xensource.com" Date: Mon, 10 Apr 2006 10:57:38 +0100 Subject: [PATCH 13/22] fix x86_32 default linux builds --- buildconfigs/linux-defconfig_xen0_x86_64 | 2 ++ buildconfigs/linux-defconfig_xen_x86_64 | 2 ++ 2 files changed, 4 insertions(+) diff --git a/buildconfigs/linux-defconfig_xen0_x86_64 b/buildconfigs/linux-defconfig_xen0_x86_64 index 25cc732d0b..94d81d5ae3 100644 --- a/buildconfigs/linux-defconfig_xen0_x86_64 +++ b/buildconfigs/linux-defconfig_xen0_x86_64 @@ -381,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 @@ -565,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_64 b/buildconfigs/linux-defconfig_xen_x86_64 index ba7c616d8c..5d95052289 100644 --- a/buildconfigs/linux-defconfig_xen_x86_64 +++ b/buildconfigs/linux-defconfig_xen_x86_64 @@ -863,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 @@ -1094,6 +1095,7 @@ CONFIG_DUMMY=m CONFIG_BONDING=m CONFIG_EQUALIZER=m CONFIG_TUN=m +CONFIG_NET_SB1000=m # # ARCnet devices From d033b064ca456423fc0c55822497aa9354f6ecd8 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 10 Apr 2006 11:39:32 +0100 Subject: [PATCH 14/22] Introduce page_to_bus() and use it in pci-dma-xen.c and swiotlb.c. On xen/ia64 with the P2M/VP model pseudo physical address(gpaddr) is fully virtualized so it defines xen_features(XENFEAT_auto_translated_physmap) = 1. In this case page_to_phys(page) should return pseudo physical address like pfn_to_mfn() and its families. However dma is not virtualized, it can't be used for pci-dma-xen.c, swiotlb.c. Signed-off-by: Isaku Yamahata --- linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c | 4 ++-- linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c | 4 ++-- linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/io.h | 1 + linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/io.h | 1 + 4 files changed, 6 insertions(+), 4 deletions(-) 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/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/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))) From 5dfbb5affbd3e7ba8fd8493da4325d33915465d8 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 10 Apr 2006 13:24:58 +0100 Subject: [PATCH 15/22] 'make mkpatches' diffs against pristine tree rather than ref tree, so it includes extra patches under patches/ subdirectory. Signed-off-by: Keir Fraser --- buildconfigs/Rules.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildconfigs/Rules.mk b/buildconfigs/Rules.mk index e4cb40def8..0a6804bc7e 100644 --- a/buildconfigs/Rules.mk +++ b/buildconfigs/Rules.mk @@ -124,14 +124,14 @@ linux-2.6-xen.patch: ref-linux-$(LINUX_VER)/.valid-ref rm -rf tmp-$@ cp -al $( $@ || true + diff -Nurp $(patsubst ref%,pristine%,$( $@ || true rm -rf tmp-$@ %-xen.patch: ref-%/.valid-ref rm -rf tmp-$@ cp -al $( $@ || true + diff -Nurp $(patsubst ref%,pristine%,$( $@ || true rm -rf tmp-$@ %-mrproper: %-mrproper-extra From 9a74026a08cea9910e704b687148172805b4b86a Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 10 Apr 2006 14:47:51 +0100 Subject: [PATCH 16/22] I used the wrong operator in a couple places for putting together some error messages out of format strings. This patch corrects those operators and fixes the strings. Signed-off-by: Ryan Wilson --- tools/python/xen/xend/server/pciif.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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") From cfca4d6941023d678d99e6fbd2a88f411b77e690 Mon Sep 17 00:00:00 2001 From: "vhanquez@kneesa.uk.xensource.com" Date: Mon, 10 Apr 2006 14:51:10 +0000 Subject: [PATCH 17/22] fix bug #609 - error: PIC register `bx' clobbered in `asm' Signed-off-by: Vincent Hanquez --- tools/ioemu/hw/vga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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; } From 312aae5cfc804b627bdbdeacc73e483fe18a2760 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 10 Apr 2006 16:26:52 +0100 Subject: [PATCH 18/22] Remove unused netbsd build fragments. Signed-Off-By: Homrs --- buildconfigs/Rules.mk | 32 +------------------------------- buildconfigs/mk.linux-2.6-xen | 9 +++------ 2 files changed, 4 insertions(+), 37 deletions(-) diff --git a/buildconfigs/Rules.mk b/buildconfigs/Rules.mk index 0a6804bc7e..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 @@ -134,17 +111,10 @@ linux-2.6-xen.patch: ref-linux-$(LINUX_VER)/.valid-ref diff -Nurp $(patsubst ref%,pristine%,$( $@ || 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/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 $( Date: Mon, 10 Apr 2006 16:27:46 +0100 Subject: [PATCH 19/22] build: Remove iptables and python loging helper targets These targets don't really fit into the build infastructure, for instance there is no faclilty for them to be removed on make distclean. I posted a patch that fleshed out the targets, but Christian Limpach suggested to me that removing them would be a better idea. Signed-Off-By: Horms --- Makefile | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/Makefile b/Makefile index 3cd9d53b99..4159ba4c67 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' @@ -154,10 +142,6 @@ help: @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' From 4886bb64c1ab8f5c0884a6ebc5c9c7591149684b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 10 Apr 2006 16:31:53 +0100 Subject: [PATCH 20/22] build: Make sure that DESTDIR is set In the case where XEN_PYTHON_NATIVE_INSTALL is in effect, if DESTDIR is not set then the install will go into a relative directory rather than under the default prefix (usually /usr). An alternate solution would be to update the fragments that do the python install to use $(DESTDIR)/ instead of $(DESTDIR). This is not an incredible burden as there are only two such fragments in the tree. However, it seems prone to error as new makefiles are created in the future. Signed-Off-By: Horms --- Config.mk | 1 + 1 file changed, 1 insertion(+) 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 From f2bc7f94025a2f2d511c9da03edd56584c0055ba Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 10 Apr 2006 16:34:59 +0100 Subject: [PATCH 21/22] build: clean up output of make help a little bit Signed-Off-By: Horms --- Makefile | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 4159ba4c67..e9dcdfccac 100644 --- a/Makefile +++ b/Makefile @@ -135,10 +135,9 @@ 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 '' @@ -146,8 +145,8 @@ help: @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!)' # Use this target with extreme care! uninstall: D=$(DESTDIR) From 9ffd98fa29fd8dc997529fa120d25446dbbc1bdd Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 10 Apr 2006 16:35:30 +0100 Subject: [PATCH 22/22] build: Document the use of XEN_PYTHON_NATIVE_INSTALL Document the use of the XEN_PYTHON_NATIVE_INSTALL environment variable Signed-Off-By: Horms --- Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Makefile b/Makefile index e9dcdfccac..71a7c7d342 100644 --- a/Makefile +++ b/Makefile @@ -147,6 +147,13 @@ help: @echo ' sparse trees' @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' + @echo ' instead of /lib/python' + @echo ' true if set to non-empty value, false otherwise' # Use this target with extreme care! uninstall: D=$(DESTDIR)