[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Architecture-independent, and tasklet-based, continue_hypercall_on_cpu().
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1271240945 -3600 # Node ID 07befd9cf6d3097c3b44d857c8498a6ed14772c7 # Parent 5057604eeefcb6479cc97c092a2399a115fae879 Architecture-independent, and tasklet-based, continue_hypercall_on_cpu(). Signed-off-by: Juergen Gross <juergen.gross@xxxxxxxxxxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/domain.c | 76 ---------------------------- xen/common/domain.c | 67 ++++++++++++++++++++++++ xen/common/schedule.c | 46 +--------------- xen/include/asm-ia64/linux-xen/asm/ptrace.h | 2 xen/include/asm-x86/domain.h | 6 -- xen/include/asm-x86/regs.h | 2 xen/include/xen/domain.h | 4 + xen/include/xen/sched.h | 10 +-- 8 files changed, 83 insertions(+), 130 deletions(-) diff -r 5057604eeefc -r 07befd9cf6d3 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Wed Apr 14 10:44:29 2010 +0100 +++ b/xen/arch/x86/domain.c Wed Apr 14 11:29:05 2010 +0100 @@ -1517,82 +1517,6 @@ void sync_vcpu_execstate(struct vcpu *v) flush_tlb_mask(&v->vcpu_dirty_cpumask); } -struct migrate_info { - long (*func)(void *data); - void *data; - void (*saved_schedule_tail)(struct vcpu *); - cpumask_t saved_affinity; - unsigned int nest; -}; - -static void continue_hypercall_on_cpu_helper(struct vcpu *v) -{ - struct cpu_user_regs *regs = guest_cpu_user_regs(); - struct migrate_info *info = v->arch.continue_info; - cpumask_t mask = info->saved_affinity; - void (*saved_schedule_tail)(struct vcpu *) = info->saved_schedule_tail; - - regs->eax = info->func(info->data); - - if ( info->nest-- == 0 ) - { - xfree(info); - v->arch.schedule_tail = saved_schedule_tail; - v->arch.continue_info = NULL; - vcpu_unlock_affinity(v, &mask); - } - - (*saved_schedule_tail)(v); -} - -int continue_hypercall_on_cpu(int cpu, long (*func)(void *data), void *data) -{ - struct vcpu *v = current; - struct migrate_info *info; - cpumask_t mask = cpumask_of_cpu(cpu); - int rc; - - if ( cpu == smp_processor_id() ) - return func(data); - - info = v->arch.continue_info; - if ( info == NULL ) - { - info = xmalloc(struct migrate_info); - if ( info == NULL ) - return -ENOMEM; - - rc = vcpu_lock_affinity(v, &mask); - if ( rc ) - { - xfree(info); - return rc; - } - - info->saved_schedule_tail = v->arch.schedule_tail; - info->saved_affinity = mask; - info->nest = 0; - - v->arch.schedule_tail = continue_hypercall_on_cpu_helper; - v->arch.continue_info = info; - } - else - { - BUG_ON(info->nest != 0); - rc = vcpu_locked_change_affinity(v, &mask); - if ( rc ) - return rc; - info->nest++; - } - - info->func = func; - info->data = data; - - /* Dummy return value will be overwritten by new schedule_tail. */ - BUG_ON(!test_bit(SCHEDULE_SOFTIRQ, &softirq_pending(smp_processor_id()))); - return 0; -} - #define next_arg(fmt, args) ({ \ unsigned long __arg; \ switch ( *(fmt)++ ) \ diff -r 5057604eeefc -r 07befd9cf6d3 xen/common/domain.c --- a/xen/common/domain.c Wed Apr 14 10:44:29 2010 +0100 +++ b/xen/common/domain.c Wed Apr 14 11:29:05 2010 +0100 @@ -898,6 +898,73 @@ long vm_assist(struct domain *p, unsigne return -ENOSYS; } +struct migrate_info { + long (*func)(void *data); + void *data; + struct vcpu *vcpu; + unsigned int nest; +}; + +static DEFINE_PER_CPU(struct migrate_info *, continue_info); + +static void continue_hypercall_tasklet_handler(unsigned long _info) +{ + struct migrate_info *info = (struct migrate_info *)_info; + struct vcpu *v = info->vcpu; + + vcpu_sleep_sync(v); + + this_cpu(continue_info) = info; + return_reg(v) = info->func(info->data); + this_cpu(continue_info) = NULL; + + if ( info->nest-- == 0 ) + { + xfree(info); + vcpu_unpause(v); + } +} + +int continue_hypercall_on_cpu(int cpu, long (*func)(void *data), void *data) +{ + struct vcpu *curr = current; + struct migrate_info *info; + + if ( cpu == smp_processor_id() ) + return func(data); + + info = this_cpu(continue_info); + if ( info == NULL ) + { + info = xmalloc(struct migrate_info); + if ( info == NULL ) + return -ENOMEM; + + info->vcpu = curr; + info->nest = 0; + + tasklet_init( + &curr->continue_hypercall_tasklet, + continue_hypercall_tasklet_handler, + (unsigned long)info); + + vcpu_pause_nosync(curr); + } + else + { + BUG_ON(info->nest != 0); + info->nest++; + } + + info->func = func; + info->data = data; + + tasklet_schedule_on_cpu(&curr->continue_hypercall_tasklet, cpu); + + /* Dummy return value will be overwritten by tasklet. */ + return 0; +} + /* * Local variables: * mode: C diff -r 5057604eeefc -r 07befd9cf6d3 xen/common/schedule.c --- a/xen/common/schedule.c Wed Apr 14 10:44:29 2010 +0100 +++ b/xen/common/schedule.c Wed Apr 14 11:29:05 2010 +0100 @@ -408,26 +408,18 @@ void cpu_disable_scheduler(void) } } -static int __vcpu_set_affinity( - struct vcpu *v, cpumask_t *affinity, - bool_t old_lock_status, bool_t new_lock_status) +int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity) { cpumask_t online_affinity, old_affinity; + + if ( v->domain->is_pinned ) + return -EINVAL; cpus_and(online_affinity, *affinity, cpu_online_map); if ( cpus_empty(online_affinity) ) return -EINVAL; vcpu_schedule_lock_irq(v); - - if ( v->affinity_locked != old_lock_status ) - { - BUG_ON(!v->affinity_locked); - vcpu_schedule_unlock_irq(v); - return -EBUSY; - } - - v->affinity_locked = new_lock_status; old_affinity = v->cpu_affinity; v->cpu_affinity = *affinity; @@ -444,36 +436,6 @@ static int __vcpu_set_affinity( } return 0; -} - -int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity) -{ - if ( v->domain->is_pinned ) - return -EINVAL; - return __vcpu_set_affinity(v, affinity, 0, 0); -} - -int vcpu_lock_affinity(struct vcpu *v, cpumask_t *affinity) -{ - return __vcpu_set_affinity(v, affinity, 0, 1); -} - -int vcpu_locked_change_affinity(struct vcpu *v, cpumask_t *affinity) -{ - return __vcpu_set_affinity(v, affinity, 1, 1); -} - -void vcpu_unlock_affinity(struct vcpu *v, cpumask_t *affinity) -{ - cpumask_t online_affinity; - - /* Do not fail if no CPU in old affinity mask is online. */ - cpus_and(online_affinity, *affinity, cpu_online_map); - if ( cpus_empty(online_affinity) ) - *affinity = cpu_online_map; - - if ( __vcpu_set_affinity(v, affinity, 1, 0) != 0 ) - BUG(); } /* Block the currently-executing domain until a pertinent event occurs. */ diff -r 5057604eeefc -r 07befd9cf6d3 xen/include/asm-ia64/linux-xen/asm/ptrace.h --- a/xen/include/asm-ia64/linux-xen/asm/ptrace.h Wed Apr 14 10:44:29 2010 +0100 +++ b/xen/include/asm-ia64/linux-xen/asm/ptrace.h Wed Apr 14 11:29:05 2010 +0100 @@ -197,6 +197,8 @@ static inline struct cpu_user_regs *vcpu { return (struct cpu_user_regs *)((unsigned long)v + IA64_STK_OFFSET) - 1; } + +#define return_reg(v) (vcpu_regs(v)->r8) struct cpu_user_regs *guest_cpu_user_regs(void); diff -r 5057604eeefc -r 07befd9cf6d3 xen/include/asm-x86/domain.h --- a/xen/include/asm-x86/domain.h Wed Apr 14 10:44:29 2010 +0100 +++ b/xen/include/asm-x86/domain.h Wed Apr 14 11:29:05 2010 +0100 @@ -381,9 +381,6 @@ struct arch_vcpu void (*ctxt_switch_from) (struct vcpu *); void (*ctxt_switch_to) (struct vcpu *); - /* Record information required to continue execution after migration */ - void *continue_info; - /* Bounce information for propagating an exception to guest OS. */ struct trap_bounce trap_bounce; @@ -450,9 +447,6 @@ struct arch_vcpu /* Shorthands to improve code legibility. */ #define hvm_vmx hvm_vcpu.u.vmx #define hvm_svm hvm_vcpu.u.svm - -/* Continue the current hypercall via func(data) on specified cpu. */ -int continue_hypercall_on_cpu(int cpu, long (*func)(void *data), void *data); void vcpu_show_execution_state(struct vcpu *); void vcpu_show_registers(const struct vcpu *); diff -r 5057604eeefc -r 07befd9cf6d3 xen/include/asm-x86/regs.h --- a/xen/include/asm-x86/regs.h Wed Apr 14 10:44:29 2010 +0100 +++ b/xen/include/asm-x86/regs.h Wed Apr 14 11:29:05 2010 +0100 @@ -19,4 +19,6 @@ (diff == 0); \ }) +#define return_reg(v) ((v)->arch.guest_context.user_regs.eax) + #endif /* __X86_REGS_H__ */ diff -r 5057604eeefc -r 07befd9cf6d3 xen/include/xen/domain.h --- a/xen/include/xen/domain.h Wed Apr 14 10:44:29 2010 +0100 +++ b/xen/include/xen/domain.h Wed Apr 14 11:29:05 2010 +0100 @@ -3,6 +3,7 @@ #define __XEN_DOMAIN_H__ #include <public/xen.h> +#include <asm/domain.h> typedef union { struct vcpu_guest_context *nat; @@ -62,6 +63,9 @@ bool_t domctl_lock_acquire(void); bool_t domctl_lock_acquire(void); void domctl_lock_release(void); +/* Continue the current hypercall via func(data) on specified cpu. */ +int continue_hypercall_on_cpu(int cpu, long (*func)(void *data), void *data); + extern unsigned int xen_processor_pmbits; #endif /* __XEN_DOMAIN_H__ */ diff -r 5057604eeefc -r 07befd9cf6d3 xen/include/xen/sched.h --- a/xen/include/xen/sched.h Wed Apr 14 10:44:29 2010 +0100 +++ b/xen/include/xen/sched.h Wed Apr 14 11:29:05 2010 +0100 @@ -15,7 +15,7 @@ #include <xen/timer.h> #include <xen/grant_table.h> #include <xen/rangeset.h> -#include <asm/domain.h> +#include <xen/domain.h> #include <xen/xenoprof.h> #include <xen/rcupdate.h> #include <xen/irq.h> @@ -132,8 +132,6 @@ struct vcpu bool_t defer_shutdown; /* VCPU is paused following shutdown request (d->is_shutting_down)? */ bool_t paused_for_shutdown; - /* VCPU affinity is temporarily locked from controller changes? */ - bool_t affinity_locked; /* * > 0: a single port is being polled; @@ -156,6 +154,9 @@ struct vcpu /* Bitmask of CPUs which are holding onto this VCPU's state. */ cpumask_t vcpu_dirty_cpumask; + + /* Tasklet for continue_hypercall_on_cpu(). */ + struct tasklet continue_hypercall_tasklet; struct arch_vcpu arch; }; @@ -581,9 +582,6 @@ void vcpu_force_reschedule(struct vcpu * void vcpu_force_reschedule(struct vcpu *v); void cpu_disable_scheduler(void); int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity); -int vcpu_lock_affinity(struct vcpu *v, cpumask_t *affinity); -int vcpu_locked_change_affinity(struct vcpu *v, cpumask_t *affinity); -void vcpu_unlock_affinity(struct vcpu *v, cpumask_t *affinity); void vcpu_runstate_get(struct vcpu *v, struct vcpu_runstate_info *runstate); uint64_t get_cpu_idle_time(unsigned int cpu); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |