# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID ba9706473941520247153e7e31d89899285d09ce
# Parent 5e4e11d059a1d9aa42b818ad0118c163e2f66767
Make the event-channel pending and mask arrays consist of
longs. Thi sensures appropriate alignment for architectures
that require it, and also allows us to naturally support up
to 4096 event channels per 64-bit guest.
Moved 'n_vcpu' field from shared_info to start_info. Really it
ought to disappear altogether as the info can be derived from
xenstore.
Fix a weird bug in XendDomainInfo where 'vcpus' information for
a domain defaults to floating point value 1.0 rather than integer
1. This looks like a Python bug to me, but in any case it is
'fixed' by explicitly converting the default value to an integer.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r 5e4e11d059a1 -r ba9706473941
linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c Mon Oct 17
13:12:20 2005
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c Mon Oct 17
14:15:17 2005
@@ -94,7 +94,7 @@
irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- u32 l1, l2;
+ unsigned long l1, l2;
unsigned int l1i, l2i, port;
irqreturn_t (*handler)(int, void *, struct pt_regs *);
shared_info_t *s = HYPERVISOR_shared_info;
@@ -108,14 +108,14 @@
while ( l1 != 0 )
{
l1i = __ffs(l1);
- l1 &= ~(1 << l1i);
+ l1 &= ~(1UL << l1i);
while ( (l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i]) != 0 )
{
l2i = __ffs(l2);
- l2 &= ~(1 << l2i);
+ l2 &= ~(1UL << l2i);
- port = (l1i << 5) + l2i;
+ port = (l1i * BITS_PER_LONG) + l2i;
if ( (handler = evtchns[port].handler) != NULL )
{
clear_evtchn(port);
diff -r 5e4e11d059a1 -r ba9706473941
linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Mon Oct 17
13:12:20 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Mon Oct 17
14:15:17 2005
@@ -1123,7 +1123,7 @@
* If SMP should be disabled, then really disable it!
*/
if (!max_cpus) {
- HYPERVISOR_shared_info->n_vcpu = 1;
+ xen_start_info->n_vcpu = 1;
printk(KERN_INFO "SMP mode deactivated, forcing use of dummy
APIC emulation.\n");
smpboot_clear_io_apic_irqs();
#if 0
@@ -1153,12 +1153,10 @@
*/
Dprintk("CPU present map: %lx\n", physids_coerce(phys_cpu_present_map));
#endif
- Dprintk("CPU present map: %lx\n",
- (1UL << HYPERVISOR_shared_info->n_vcpu) - 1);
+ Dprintk("CPU present map: %lx\n", (1UL << xen_start_info->n_vcpu) - 1);
kicked = 1;
- for (cpu = 1; kicked < NR_CPUS &&
- cpu < HYPERVISOR_shared_info->n_vcpu; cpu++) {
+ for (cpu = 1; kicked < NR_CPUS && cpu < xen_start_info->n_vcpu; cpu++) {
if (max_cpus <= cpucount+1)
continue;
diff -r 5e4e11d059a1 -r ba9706473941
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Mon Oct 17 13:12:20 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Mon Oct 17 14:15:17 2005
@@ -71,8 +71,8 @@
#ifdef CONFIG_SMP
-static u8 cpu_evtchn[NR_EVENT_CHANNELS];
-static u32 cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/32];
+static u8 cpu_evtchn[NR_EVENT_CHANNELS];
+static unsigned long cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/BITS_PER_LONG];
#define active_evtchns(cpu,sh,idx) \
((sh)->evtchn_pending[idx] & \
@@ -137,7 +137,7 @@
/* NB. Interrupts are disabled on entry. */
asmlinkage void evtchn_do_upcall(struct pt_regs *regs)
{
- u32 l1, l2;
+ unsigned long l1, l2;
unsigned int l1i, l2i, port;
int irq, cpu = smp_processor_id();
shared_info_t *s = HYPERVISOR_shared_info;
@@ -149,13 +149,13 @@
l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
while (l1 != 0) {
l1i = __ffs(l1);
- l1 &= ~(1 << l1i);
+ l1 &= ~(1UL << l1i);
while ((l2 = active_evtchns(cpu, s, l1i)) != 0) {
l2i = __ffs(l2);
- l2 &= ~(1 << l2i);
+ l2 &= ~(1UL << l2i);
- port = (l1i << 5) + l2i;
+ port = (l1i * BITS_PER_LONG) + l2i;
if ((irq = evtchn_to_irq[port]) != -1)
do_IRQ(irq, regs);
else
diff -r 5e4e11d059a1 -r ba9706473941
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c Mon Oct 17
13:12:20 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c Mon Oct 17
14:15:17 2005
@@ -1045,7 +1045,7 @@
*/
if (!max_cpus) {
#ifdef CONFIG_XEN
- HYPERVISOR_shared_info->n_vcpu = 1;
+ xen_start_info->n_vcpu = 1;
#endif
printk(KERN_INFO "SMP mode deactivated, forcing use of dummy
APIC emulation.\n");
#ifndef CONFIG_XEN
@@ -1082,7 +1082,7 @@
int apicid = cpu_present_to_apicid(i);
if (physid_isset(apicid, phys_cpu_present_map)) {
#else
- if (i < HYPERVISOR_shared_info->n_vcpu) {
+ if (i < xen_start_info->n_vcpu) {
#endif
cpu_set(i, cpu_present_map);
/* possible map would be different if we supported real
diff -r 5e4e11d059a1 -r ba9706473941
linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h
Mon Oct 17 13:12:20 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h
Mon Oct 17 14:15:17 2005
@@ -52,4 +52,4 @@
}
-#define smp_found_config (HYPERVISOR_shared_info->n_vcpu > 1)
+#define smp_found_config (xen_start_info->n_vcpu > 1)
diff -r 5e4e11d059a1 -r ba9706473941
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h
Mon Oct 17 13:12:20 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h
Mon Oct 17 14:15:17 2005
@@ -52,4 +52,4 @@
}
-#define smp_found_config (HYPERVISOR_shared_info->n_vcpu > 1)
+#define smp_found_config (xen_start_info->n_vcpu > 1)
diff -r 5e4e11d059a1 -r ba9706473941
linux-2.6-xen-sparse/include/asm-xen/evtchn.h
--- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h Mon Oct 17 13:12:20 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h Mon Oct 17 14:15:17 2005
@@ -99,8 +99,9 @@
* like a real IO-APIC we 'lose the interrupt edge' if the channel is
* masked.
*/
- if (synch_test_bit (port, &s->evtchn_pending[0]) &&
- !synch_test_and_set_bit(port>>5, &vcpu_info->evtchn_pending_sel)) {
+ if (synch_test_bit(port, &s->evtchn_pending[0]) &&
+ !synch_test_and_set_bit(port / BITS_PER_LONG,
+ &vcpu_info->evtchn_pending_sel)) {
vcpu_info->evtchn_upcall_pending = 1;
if (!vcpu_info->evtchn_upcall_mask)
force_evtchn_callback();
diff -r 5e4e11d059a1 -r ba9706473941 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c Mon Oct 17 13:12:20 2005
+++ b/tools/libxc/xc_linux_build.c Mon Oct 17 14:15:17 2005
@@ -636,6 +636,7 @@
start_info->store_evtchn = store_evtchn;
start_info->console_mfn = *console_mfn;
start_info->console_evtchn = console_evtchn;
+ start_info->n_vcpu = vcpus;
if ( initrd_len != 0 )
{
start_info->mod_start = vinitrd_start;
@@ -652,9 +653,6 @@
/* Mask all upcalls... */
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
-
- shared_info->n_vcpu = vcpus;
- printf(" VCPUS: %d\n", shared_info->n_vcpu);
munmap(shared_info, PAGE_SIZE);
diff -r 5e4e11d059a1 -r ba9706473941 tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c Mon Oct 17 13:12:20 2005
+++ b/tools/libxc/xc_vmx_build.c Mon Oct 17 14:15:17 2005
@@ -518,9 +518,6 @@
/* Mask all upcalls... */
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
-
- shared_info->n_vcpu = vcpus;
- printf(" VCPUS: %d\n", shared_info->n_vcpu);
munmap(shared_info, PAGE_SIZE);
diff -r 5e4e11d059a1 -r ba9706473941 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Mon Oct 17 13:12:20 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py Mon Oct 17 14:15:17 2005
@@ -439,7 +439,7 @@
defaultInfo('on_crash', lambda: "restart")
defaultInfo('cpu', lambda: None)
defaultInfo('cpu_weight', lambda: 1.0)
- defaultInfo('vcpus', lambda: 1)
+ defaultInfo('vcpus', lambda: int(1))
defaultInfo('vcpu_avail', lambda: (1 << self.info['vcpus']) - 1)
defaultInfo('bootloader', lambda: None)
defaultInfo('backend', lambda: [])
diff -r 5e4e11d059a1 -r ba9706473941 xen/arch/ia64/vmx/vmx_support.c
--- a/xen/arch/ia64/vmx/vmx_support.c Mon Oct 17 13:12:20 2005
+++ b/xen/arch/ia64/vmx/vmx_support.c Mon Oct 17 14:15:17 2005
@@ -49,7 +49,7 @@
*/
if (test_and_clear_bit(port,
&d->shared_info->evtchn_pending[0])) {
- clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel);
+ clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
vmx_io_assist(v);
}
@@ -67,7 +67,7 @@
* nothing losed. Next loop will check I/O channel to fix this
* window.
*/
- clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel);
+ clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
}
else
break;
@@ -139,8 +139,8 @@
/* Clear indicator specific to interrupt delivered from DM */
if (test_and_clear_bit(port,
&d->shared_info->evtchn_pending[0])) {
- if (!d->shared_info->evtchn_pending[port >> 5])
- clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel);
+ if (!d->shared_info->evtchn_pending[port/BITS_PER_LONG])
+ clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
if (!v->vcpu_info->evtchn_pending_sel)
clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
diff -r 5e4e11d059a1 -r ba9706473941 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c Mon Oct 17 13:12:20 2005
+++ b/xen/arch/x86/domain_build.c Mon Oct 17 14:15:17 2005
@@ -557,10 +557,9 @@
/* Mask all upcalls... */
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
- d->shared_info->n_vcpu = num_online_cpus();
-
- for ( i = 1; i < d->shared_info->n_vcpu; i++ )
- (void)alloc_vcpu(d, i, i % num_online_cpus());
+
+ for ( i = 1; i < num_online_cpus(); i++ )
+ (void)alloc_vcpu(d, i, i);
/* Set up monitor table */
update_pagetables(v);
@@ -588,7 +587,8 @@
/* Set up start info area. */
si = (start_info_t *)vstartinfo_start;
memset(si, 0, PAGE_SIZE);
- si->nr_pages = nr_pages;
+ si->nr_pages = nr_pages;
+ si->n_vcpu = num_online_cpus();
if ( opt_dom0_translate )
{
diff -r 5e4e11d059a1 -r ba9706473941 xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c Mon Oct 17 13:12:20 2005
+++ b/xen/arch/x86/vmx_io.c Mon Oct 17 14:15:17 2005
@@ -684,15 +684,15 @@
struct domain *d = v->domain;
int port = iopacket_port(d);
- /* evtchn_pending is shared by other event channels in 0-31 range */
- if (!d->shared_info->evtchn_pending[port>>5])
- clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel);
-
- /* Note: VMX domains may need upcalls as well */
+ /* evtchn_pending_sel bit is shared by other event channels. */
+ if (!d->shared_info->evtchn_pending[port/BITS_PER_LONG])
+ clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
+
+ /* Note: VMX domains may need upcalls as well. */
if (!v->vcpu_info->evtchn_pending_sel)
clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
- /* clear the pending bit for port */
+ /* Clear the pending bit for port. */
return test_and_clear_bit(port, &d->shared_info->evtchn_pending[0]);
}
@@ -726,7 +726,7 @@
break;
/* Events other than IOPACKET_PORT might have woken us up. In that
case, safely go back to sleep. */
- clear_bit(port>>5, ¤t->vcpu_info->evtchn_pending_sel);
+ clear_bit(port/BITS_PER_LONG, ¤t->vcpu_info->evtchn_pending_sel);
clear_bit(0, ¤t->vcpu_info->evtchn_upcall_pending);
} while(1);
}
diff -r 5e4e11d059a1 -r ba9706473941 xen/common/keyhandler.c
--- a/xen/common/keyhandler.c Mon Oct 17 13:12:20 2005
+++ b/xen/common/keyhandler.c Mon Oct 17 14:15:17 2005
@@ -136,7 +136,7 @@
&d->shared_info->evtchn_pending[0]),
test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
&d->shared_info->evtchn_mask[0]),
- test_bit(v->virq_to_evtchn[VIRQ_DEBUG]>>5,
+ test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_LONG,
&v->vcpu_info->evtchn_pending_sel));
send_guest_virq(v, VIRQ_DEBUG);
}
diff -r 5e4e11d059a1 -r ba9706473941 xen/include/public/xen.h
--- a/xen/include/public/xen.h Mon Oct 17 13:12:20 2005
+++ b/xen/include/public/xen.h Mon Oct 17 14:15:17 2005
@@ -260,8 +260,11 @@
unsigned long args[6];
} multicall_entry_t;
-/* Event channel endpoints per domain. */
-#define NR_EVENT_CHANNELS 1024
+/*
+ * Event channel endpoints per domain:
+ * 1024 if a long is 32 bits; 4096 if a long is 64 bits.
+ */
+#define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64)
/*
* Per-VCPU information goes here. This will be cleaned up more when Xen
@@ -295,7 +298,7 @@
*/
uint8_t evtchn_upcall_pending;
uint8_t evtchn_upcall_mask;
- uint32_t evtchn_pending_sel;
+ unsigned long evtchn_pending_sel;
#ifdef __ARCH_HAS_VCPU_INFO
arch_vcpu_info_t arch;
#endif
@@ -333,16 +336,14 @@
vcpu_time_info_t vcpu_time[MAX_VIRT_CPUS];
- uint32_t n_vcpu;
-
/*
- * A domain can have up to 1024 "event channels" on which it can send
- * and receive asynchronous event notifications. There are three classes
- * of event that are delivered by this mechanism:
+ * A domain can create "event channels" on which it can send and receive
+ * asynchronous event notifications. There are three classes of event that
+ * are delivered by this mechanism:
* 1. Bi-directional inter- and intra-domain connections. Domains must
- * arrange out-of-band to set up a connection (usually the setup
- * is initiated and organised by a privileged third party such as
- * software running in domain 0).
+ * arrange out-of-band to set up a connection (usually by allocating
+ * an unbound 'listener' port and avertising that via a storage service
+ * such as xenstore).
* 2. Physical interrupts. A domain with suitable hardware-access
* privileges can bind an event-channel port to a physical interrupt
* source.
@@ -350,8 +351,8 @@
* port to a virtual interrupt source, such as the virtual-timer
* device or the emergency console.
*
- * Event channels are addressed by a "port index" between 0 and 1023.
- * Each channel is associated with two bits of information:
+ * Event channels are addressed by a "port index". Each channel is
+ * associated with two bits of information:
* 1. PENDING -- notifies the domain that there is a pending notification
* to be processed. This bit is cleared by the guest.
* 2. MASK -- if this bit is clear then a 0->1 transition of PENDING
@@ -363,11 +364,11 @@
*
* To expedite scanning of pending notifications, any 0->1 pending
* transition on an unmasked channel causes a corresponding bit in a
- * 32-bit selector to be set. Each bit in the selector covers a 32-bit
- * word in the PENDING bitfield array.
+ * per-vcpu selector word to be set. Each bit in the selector covers a
+ * 'C long' in the PENDING bitfield array.
*/
- uint32_t evtchn_pending[32];
- uint32_t evtchn_mask[32];
+ unsigned long evtchn_pending[sizeof(unsigned long) * 8];
+ unsigned long evtchn_mask[sizeof(unsigned long) * 8];
/*
* Wallclock time: updated only by control software. Guests should base
@@ -422,6 +423,7 @@
unsigned long mfn_list; /* VIRTUAL address of page-frame list. */
unsigned long mod_start; /* VIRTUAL address of pre-loaded module. */
unsigned long mod_len; /* Size (bytes) of pre-loaded module. */
+ uint32_t n_vcpu;
int8_t cmd_line[MAX_GUEST_CMDLINE];
} start_info_t;
diff -r 5e4e11d059a1 -r ba9706473941 xen/include/xen/event.h
--- a/xen/include/xen/event.h Mon Oct 17 13:12:20 2005
+++ b/xen/include/xen/event.h Mon Oct 17 14:15:17 2005
@@ -28,10 +28,11 @@
shared_info_t *s = d->shared_info;
/* These four operations must happen in strict order. */
- if ( !test_and_set_bit(port, &s->evtchn_pending[0]) &&
- !test_bit (port, &s->evtchn_mask[0]) &&
- !test_and_set_bit(port>>5, &v->vcpu_info->evtchn_pending_sel) &&
- !test_and_set_bit(0, &v->vcpu_info->evtchn_upcall_pending) )
+ if ( !test_and_set_bit(port, &s->evtchn_pending[0]) &&
+ !test_bit (port, &s->evtchn_mask[0]) &&
+ !test_and_set_bit(port / BITS_PER_LONG,
+ &v->vcpu_info->evtchn_pending_sel) &&
+ !test_and_set_bit(0, &v->vcpu_info->evtchn_upcall_pending) )
{
evtchn_notify(v);
}
diff -r 5e4e11d059a1 -r ba9706473941 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Mon Oct 17 13:12:20 2005
+++ b/xen/include/xen/sched.h Mon Oct 17 14:15:17 2005
@@ -19,7 +19,7 @@
/* A global pointer to the initial domain (DOM0). */
extern struct domain *dom0;
-#define MAX_EVTCHNS 1024
+#define MAX_EVTCHNS NR_EVENT_CHANNELS
#define EVTCHNS_PER_BUCKET 128
#define NR_EVTCHN_BUCKETS (MAX_EVTCHNS / EVTCHNS_PER_BUCKET)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|