debuggers.hg
changeset 21219:ecdc14634425
Improvements and bug fixes to continue_hypercall_on_cpu().
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Wed Apr 14 13:35:05 2010 +0100 (2010-04-14) |
parents | 3cdd4cf2c20e |
children | 373daaeb636e |
files | xen/common/domain.c xen/include/xen/sched.h |
line diff
1.1 --- a/xen/common/domain.c Wed Apr 14 12:10:19 2010 +0100 1.2 +++ b/xen/common/domain.c Wed Apr 14 13:35:05 2010 +0100 1.3 @@ -147,6 +147,8 @@ struct vcpu *alloc_vcpu( 1.4 1.5 spin_lock_init(&v->virq_lock); 1.6 1.7 + tasklet_init(&v->continue_hypercall_tasklet, NULL, 0); 1.8 + 1.9 if ( is_idle_domain(d) ) 1.10 { 1.11 v->runstate.state = RUNSTATE_running; 1.12 @@ -587,6 +589,7 @@ static void complete_domain_destroy(stru 1.13 { 1.14 if ( (v = d->vcpu[i]) == NULL ) 1.15 continue; 1.16 + tasklet_kill(&v->continue_hypercall_tasklet); 1.17 vcpu_destroy(v); 1.18 sched_destroy_vcpu(v); 1.19 } 1.20 @@ -902,6 +905,7 @@ struct migrate_info { 1.21 long (*func)(void *data); 1.22 void *data; 1.23 struct vcpu *vcpu; 1.24 + unsigned int cpu; 1.25 unsigned int nest; 1.26 }; 1.27 1.28 @@ -912,30 +916,48 @@ static void continue_hypercall_tasklet_h 1.29 struct migrate_info *info = (struct migrate_info *)_info; 1.30 struct vcpu *v = info->vcpu; 1.31 1.32 - vcpu_sleep_sync(v); 1.33 + /* 1.34 + * Wait for vcpu to be entirely descheduled. We re-schedule ourselves 1.35 + * meanwhile to allow other work to be done (e.g., descheduling the vcpu!). 1.36 + */ 1.37 + BUG_ON(vcpu_runnable(v)); 1.38 + if ( v->is_running ) 1.39 + { 1.40 + tasklet_schedule(&v->continue_hypercall_tasklet); 1.41 + return; 1.42 + } 1.43 + 1.44 + /* Once descheduled, we need to gain access to its register state. */ 1.45 + sync_vcpu_execstate(v); 1.46 1.47 this_cpu(continue_info) = info; 1.48 - return_reg(v) = info->func(info->data); 1.49 + return_reg(v) = (info->cpu == smp_processor_id()) 1.50 + ? info->func(info->data) : -EINVAL; 1.51 this_cpu(continue_info) = NULL; 1.52 1.53 if ( info->nest-- == 0 ) 1.54 { 1.55 xfree(info); 1.56 vcpu_unpause(v); 1.57 + put_domain(v->domain); 1.58 } 1.59 } 1.60 1.61 int continue_hypercall_on_cpu(int cpu, long (*func)(void *data), void *data) 1.62 { 1.63 - struct vcpu *curr = current; 1.64 struct migrate_info *info; 1.65 1.66 + if ( (cpu >= NR_CPUS) || !cpu_online(cpu) ) 1.67 + return -EINVAL; 1.68 + 1.69 if ( cpu == smp_processor_id() ) 1.70 return func(data); 1.71 1.72 info = this_cpu(continue_info); 1.73 if ( info == NULL ) 1.74 { 1.75 + struct vcpu *curr = current; 1.76 + 1.77 info = xmalloc(struct migrate_info); 1.78 if ( info == NULL ) 1.79 return -ENOMEM; 1.80 @@ -943,11 +965,14 @@ int continue_hypercall_on_cpu(int cpu, l 1.81 info->vcpu = curr; 1.82 info->nest = 0; 1.83 1.84 + tasklet_kill( 1.85 + &curr->continue_hypercall_tasklet); 1.86 tasklet_init( 1.87 &curr->continue_hypercall_tasklet, 1.88 continue_hypercall_tasklet_handler, 1.89 (unsigned long)info); 1.90 1.91 + get_knownalive_domain(curr->domain); 1.92 vcpu_pause_nosync(curr); 1.93 } 1.94 else 1.95 @@ -958,8 +983,9 @@ int continue_hypercall_on_cpu(int cpu, l 1.96 1.97 info->func = func; 1.98 info->data = data; 1.99 + info->cpu = cpu; 1.100 1.101 - tasklet_schedule_on_cpu(&curr->continue_hypercall_tasklet, cpu); 1.102 + tasklet_schedule_on_cpu(&info->vcpu->continue_hypercall_tasklet, cpu); 1.103 1.104 /* Dummy return value will be overwritten by tasklet. */ 1.105 return 0;
2.1 --- a/xen/include/xen/sched.h Wed Apr 14 12:10:19 2010 +0100 2.2 +++ b/xen/include/xen/sched.h Wed Apr 14 13:35:05 2010 +0100 2.3 @@ -375,14 +375,6 @@ static inline void get_knownalive_domain 2.4 ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTROYED)); 2.5 } 2.6 2.7 -/* Obtain a reference to the currently-running domain. */ 2.8 -static inline struct domain *get_current_domain(void) 2.9 -{ 2.10 - struct domain *d = current->domain; 2.11 - get_knownalive_domain(d); 2.12 - return d; 2.13 -} 2.14 - 2.15 struct domain *domain_create( 2.16 domid_t domid, unsigned int domcr_flags, ssidref_t ssidref); 2.17 /* DOMCRF_hvm: Create an HVM domain, as opposed to a PV domain. */