[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Clean up Xen's event-channel interface, and semantics for binding
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 1d375ce8e0e04871782b94408e8b8fe3d399cdd6 # Parent 579d1e771025f8eb36ae537650499dd9a6b66e7b Clean up Xen's event-channel interface, and semantics for binding to VCPUs. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 579d1e771025 -r 1d375ce8e0e0 linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h Fri Jul 8 12:24:58 2005 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h Fri Jul 8 14:17:54 2005 @@ -126,8 +126,8 @@ /* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */ extern int bind_virq_to_irq(int virq); extern void unbind_virq_from_irq(int virq); -extern int bind_ipi_on_cpu_to_irq(int cpu, int ipi); -extern void unbind_ipi_on_cpu_from_irq(int cpu, int ipi); +extern int bind_ipi_to_irq(int ipi); +extern void unbind_ipi_from_irq(int ipi); extern int bind_evtchn_to_irq(int evtchn); extern void unbind_evtchn_from_irq(int evtchn); diff -r 579d1e771025 -r 1d375ce8e0e0 xen/common/event_channel.c --- a/xen/common/event_channel.c Fri Jul 8 12:24:58 2005 +++ b/xen/common/event_channel.c Fri Jul 8 14:17:54 2005 @@ -220,12 +220,10 @@ chn1->u.interdomain.remote_dom = d2; chn1->u.interdomain.remote_port = (u16)port2; - chn1->notify_vcpu_id = 0; chn1->state = ECS_INTERDOMAIN; chn2->u.interdomain.remote_dom = d1; chn2->u.interdomain.remote_port = (u16)port1; - chn2->notify_vcpu_id = 0; chn2->state = ECS_INTERDOMAIN; out: @@ -285,10 +283,7 @@ { struct evtchn *chn; struct domain *d = current->domain; - int port, ipi_vcpu = bind->ipi_vcpu; - - if ( (ipi_vcpu >= MAX_VIRT_CPUS) || (d->vcpu[ipi_vcpu] == NULL) ) - return -EINVAL; + int port; spin_lock(&d->evtchn_lock); @@ -296,7 +291,7 @@ { chn = evtchn_from_port(d, port); chn->state = ECS_IPI; - chn->notify_vcpu_id = ipi_vcpu; + chn->notify_vcpu_id = current->vcpu_id; } spin_unlock(&d->evtchn_lock); @@ -325,8 +320,6 @@ goto out; chn = evtchn_from_port(d, port); - - chn->notify_vcpu_id = 0; d->pirq_to_evtchn[pirq] = port; rc = pirq_guest_bind(d->vcpu[0], pirq, @@ -441,7 +434,9 @@ BUG(); } - chn1->state = ECS_FREE; + /* Reset binding to vcpu0 when the channel is freed. */ + chn1->state = ECS_FREE; + chn1->notify_vcpu_id = 0; out: if ( d2 != NULL ) @@ -570,12 +565,13 @@ status->u.virq = chn->u.virq; break; case ECS_IPI: - status->status = EVTCHNSTAT_ipi; - status->u.ipi_vcpu = chn->notify_vcpu_id; + status->status = EVTCHNSTAT_ipi; break; default: BUG(); } + + status->vcpu = chn->notify_vcpu_id; out: spin_unlock(&d->evtchn_lock); @@ -583,13 +579,16 @@ return rc; } -static long evtchn_rebind(evtchn_rebind_t *bind) +static long evtchn_bind_vcpu(evtchn_bind_vcpu_t *bind) { struct domain *d = current->domain; int port = bind->port; int vcpu = bind->vcpu; struct evtchn *chn; - long rc = 0; + long rc = 0; + + if ( (vcpu >= MAX_VIRT_CPUS) || (d->vcpu[vcpu] == NULL) ) + return -EINVAL; spin_lock(&d->evtchn_lock); @@ -600,7 +599,17 @@ } chn = evtchn_from_port(d, port); - chn->notify_vcpu_id = vcpu; + switch ( chn->state ) + { + case ECS_UNBOUND: + case ECS_INTERDOMAIN: + case ECS_PIRQ: + chn->notify_vcpu_id = vcpu; + break; + default: + rc = -EINVAL; + break; + } out: spin_unlock(&d->evtchn_lock); @@ -664,10 +673,8 @@ rc = -EFAULT; break; - case EVTCHNOP_rebind: - rc = evtchn_rebind(&op.u.rebind); - if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) ) - rc = -EFAULT; + case EVTCHNOP_bind_vcpu: + rc = evtchn_bind_vcpu(&op.u.bind_vcpu); break; default: diff -r 579d1e771025 -r 1d375ce8e0e0 linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c --- a/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c Fri Jul 8 12:24:58 2005 +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c Fri Jul 8 14:17:54 2005 @@ -236,17 +236,17 @@ spin_unlock(&irq_mapping_update_lock); } -int bind_ipi_on_cpu_to_irq(int cpu, int ipi) +int bind_ipi_on_cpu_to_irq(int ipi) { evtchn_op_t op; int evtchn, irq; + int cpu = smp_processor_id(); spin_lock(&irq_mapping_update_lock); if ( (evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == 0 ) { - op.cmd = EVTCHNOP_bind_ipi; - op.u.bind_ipi.ipi_vcpu = cpu; + op.cmd = EVTCHNOP_bind_ipi; if ( HYPERVISOR_event_channel_op(&op) != 0 ) panic("Failed to bind virtual IPI %d on cpu %d\n", ipi, cpu); evtchn = op.u.bind_ipi.port; @@ -278,9 +278,9 @@ spin_lock(&irq_mapping_update_lock); - op.cmd = EVTCHNOP_rebind; - op.u.rebind.port = evtchn; - op.u.rebind.vcpu = newcpu; + op.cmd = EVTCHNOP_bind_vcpu; + op.u.bind_vcpu.port = evtchn; + op.u.bind_vcpu.vcpu = newcpu; if ( HYPERVISOR_event_channel_op(&op) != 0 ) printk(KERN_INFO "Failed to rebind IPI%d to CPU%d\n",ipi,newcpu); @@ -294,18 +294,19 @@ spin_lock(&irq_mapping_update_lock); - op.cmd = EVTCHNOP_rebind; - op.u.rebind.port = evtchn; - op.u.rebind.vcpu = newcpu; + op.cmd = EVTCHNOP_bind_vcpu; + op.u.bind_vcpu.port = evtchn; + op.u.bind_vcpu.vcpu = newcpu; if ( HYPERVISOR_event_channel_op(&op) != 0 ) printk(KERN_INFO "Failed to rebind IRQ%d to CPU%d\n",irq,newcpu); spin_unlock(&irq_mapping_update_lock); } -void unbind_ipi_on_cpu_from_irq(int cpu, int ipi) -{ - evtchn_op_t op; +void unbind_ipi_from_irq(int ipi) +{ + evtchn_op_t op; + int cpu = smp_processor_id(); int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]; int irq = irq_to_evtchn[evtchn]; diff -r 579d1e771025 -r 1d375ce8e0e0 xen/include/public/dom0_ops.h --- a/xen/include/public/dom0_ops.h Fri Jul 8 12:24:58 2005 +++ b/xen/include/public/dom0_ops.h Fri Jul 8 14:17:54 2005 @@ -19,7 +19,7 @@ * This makes sure that old versions of dom0 tools will stop working in a * well-defined way (rather than crashing the machine, for instance). */ -#define DOM0_INTERFACE_VERSION 0xAAAA100D +#define DOM0_INTERFACE_VERSION 0xAAAA100E /************************************************************************/ diff -r 579d1e771025 -r 1d375ce8e0e0 xen/include/public/event_channel.h --- a/xen/include/public/event_channel.h Fri Jul 8 12:24:58 2005 +++ b/xen/include/public/event_channel.h Fri Jul 8 14:17:54 2005 @@ -89,8 +89,6 @@ */ #define EVTCHNOP_bind_ipi 7 typedef struct evtchn_bind_ipi { - /* IN parameters. */ - u32 ipi_vcpu; /* OUT parameters. */ u32 port; } evtchn_bind_ipi_t; @@ -144,6 +142,7 @@ #define EVTCHNSTAT_virq 4 /* Channel is bound to a virtual IRQ line */ #define EVTCHNSTAT_ipi 5 /* Channel is bound to a virtual IPI line */ u32 status; + u32 vcpu; /* VCPU to which this channel is bound. */ union { struct { domid_t dom; @@ -154,16 +153,25 @@ } interdomain; /* EVTCHNSTAT_interdomain */ u32 pirq; /* EVTCHNSTAT_pirq */ u32 virq; /* EVTCHNSTAT_virq */ - u32 ipi_vcpu; /* EVTCHNSTAT_ipi */ } u; } evtchn_status_t; -#define EVTCHNOP_rebind 8 -typedef struct { +/* + * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an + * event is pending. + * NOTES: + * 1. IPI- and VIRQ-bound channels always notify the vcpu that initialised + * the binding. This binding cannot be changed. + * 2. All other channels notify vcpu0 by default. This default is set when + * the channel is allocated (a port that is freed and subsequently reused + * has its binding reset to vcpu0). + */ +#define EVTCHNOP_bind_vcpu 8 +typedef struct evtchn_bind_vcpu { /* IN parameters. */ - u32 port; /* 0 */ - u32 vcpu; /* 4 */ -} evtchn_rebind_t; /* 8 bytes */ + u32 port; + u32 vcpu; +} evtchn_bind_vcpu_t; typedef struct evtchn_op { u32 cmd; /* EVTCHNOP_* */ @@ -176,7 +184,7 @@ evtchn_close_t close; evtchn_send_t send; evtchn_status_t status; - evtchn_rebind_t rebind; + evtchn_bind_vcpu_t bind_vcpu; } u; } evtchn_op_t; diff -r 579d1e771025 -r 1d375ce8e0e0 linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h Fri Jul 8 12:24:58 2005 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h Fri Jul 8 14:17:54 2005 @@ -128,8 +128,8 @@ /* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */ extern int bind_virq_to_irq(int virq); extern void unbind_virq_from_irq(int virq); -extern int bind_ipi_on_cpu_to_irq(int cpu, int ipi); -extern void unbind_ipi_on_cpu_from_irq(int cpu, int ipi); +extern int bind_ipi_to_irq(int ipi); +extern void unbind_ipi_from_irq(int ipi); extern int bind_evtchn_to_irq(int evtchn); extern void unbind_evtchn_from_irq(int evtchn); diff -r 579d1e771025 -r 1d375ce8e0e0 linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c Fri Jul 8 12:24:58 2005 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c Fri Jul 8 14:17:54 2005 @@ -1533,13 +1533,13 @@ int cpu = smp_processor_id(); per_cpu(resched_irq, cpu) = - bind_ipi_on_cpu_to_irq(cpu, RESCHEDULE_VECTOR); + bind_ipi_to_irq(RESCHEDULE_VECTOR); sprintf(resched_name[cpu], "resched%d", cpu); BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt, SA_INTERRUPT, resched_name[cpu], NULL)); per_cpu(callfunc_irq, cpu) = - bind_ipi_on_cpu_to_irq(cpu, CALL_FUNCTION_VECTOR); + bind_ipi_to_irq(CALL_FUNCTION_VECTOR); sprintf(callfunc_name[cpu], "callfunc%d", cpu); BUG_ON(request_irq(per_cpu(callfunc_irq, cpu), smp_call_function_interrupt, _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |