[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Improvements and bug fixes to continue_hypercall_on_cpu().



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1271248505 -3600
# Node ID ecdc146344250119b0e81b7aff625f8d2d09a672
# Parent  3cdd4cf2c20e480fc90b088bef0bd37d8696e90e
Improvements and bug fixes to continue_hypercall_on_cpu().

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/common/domain.c     |   36 +++++++++++++++++++++++++++++++-----
 xen/include/xen/sched.h |    8 --------
 2 files changed, 31 insertions(+), 13 deletions(-)

diff -r 3cdd4cf2c20e -r ecdc14634425 xen/common/domain.c
--- a/xen/common/domain.c       Wed Apr 14 12:10:19 2010 +0100
+++ b/xen/common/domain.c       Wed Apr 14 13:35:05 2010 +0100
@@ -147,6 +147,8 @@ struct vcpu *alloc_vcpu(
 
     spin_lock_init(&v->virq_lock);
 
+    tasklet_init(&v->continue_hypercall_tasklet, NULL, 0);
+
     if ( is_idle_domain(d) )
     {
         v->runstate.state = RUNSTATE_running;
@@ -587,6 +589,7 @@ static void complete_domain_destroy(stru
     {
         if ( (v = d->vcpu[i]) == NULL )
             continue;
+        tasklet_kill(&v->continue_hypercall_tasklet);
         vcpu_destroy(v);
         sched_destroy_vcpu(v);
     }
@@ -902,6 +905,7 @@ struct migrate_info {
     long (*func)(void *data);
     void *data;
     struct vcpu *vcpu;
+    unsigned int cpu;
     unsigned int nest;
 };
 
@@ -912,23 +916,39 @@ static void continue_hypercall_tasklet_h
     struct migrate_info *info = (struct migrate_info *)_info;
     struct vcpu *v = info->vcpu;
 
-    vcpu_sleep_sync(v);
+    /*
+     * Wait for vcpu to be entirely descheduled. We re-schedule ourselves
+     * meanwhile to allow other work to be done (e.g., descheduling the vcpu!).
+     */
+    BUG_ON(vcpu_runnable(v));
+    if ( v->is_running )
+    {
+        tasklet_schedule(&v->continue_hypercall_tasklet);
+        return;
+    }
+
+    /* Once descheduled, we need to gain access to its register state. */
+    sync_vcpu_execstate(v);
 
     this_cpu(continue_info) = info;
-    return_reg(v) = info->func(info->data);
+    return_reg(v) = (info->cpu == smp_processor_id())
+        ? info->func(info->data) : -EINVAL;
     this_cpu(continue_info) = NULL;
 
     if ( info->nest-- == 0 )
     {
         xfree(info);
         vcpu_unpause(v);
+        put_domain(v->domain);
     }
 }
 
 int continue_hypercall_on_cpu(int cpu, long (*func)(void *data), void *data)
 {
-    struct vcpu *curr = current;
     struct migrate_info *info;
+
+    if ( (cpu >= NR_CPUS) || !cpu_online(cpu) )
+        return -EINVAL;
 
     if ( cpu == smp_processor_id() )
         return func(data);
@@ -936,6 +956,8 @@ int continue_hypercall_on_cpu(int cpu, l
     info = this_cpu(continue_info);
     if ( info == NULL )
     {
+        struct vcpu *curr = current;
+
         info = xmalloc(struct migrate_info);
         if ( info == NULL )
             return -ENOMEM;
@@ -943,11 +965,14 @@ int continue_hypercall_on_cpu(int cpu, l
         info->vcpu = curr;
         info->nest = 0;
 
+        tasklet_kill(
+            &curr->continue_hypercall_tasklet);
         tasklet_init(
             &curr->continue_hypercall_tasklet,
             continue_hypercall_tasklet_handler,
             (unsigned long)info);
 
+        get_knownalive_domain(curr->domain);
         vcpu_pause_nosync(curr);
     }
     else
@@ -958,8 +983,9 @@ int continue_hypercall_on_cpu(int cpu, l
 
     info->func = func;
     info->data = data;
-
-    tasklet_schedule_on_cpu(&curr->continue_hypercall_tasklet, cpu);
+    info->cpu  = cpu;
+
+    tasklet_schedule_on_cpu(&info->vcpu->continue_hypercall_tasklet, cpu);
 
     /* Dummy return value will be overwritten by tasklet. */
     return 0;
diff -r 3cdd4cf2c20e -r ecdc14634425 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Wed Apr 14 12:10:19 2010 +0100
+++ b/xen/include/xen/sched.h   Wed Apr 14 13:35:05 2010 +0100
@@ -375,14 +375,6 @@ static inline void get_knownalive_domain
     ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTROYED));
 }
 
-/* Obtain a reference to the currently-running domain. */
-static inline struct domain *get_current_domain(void)
-{
-    struct domain *d = current->domain;
-    get_knownalive_domain(d);
-    return d;
-}
-
 struct domain *domain_create(
     domid_t domid, unsigned int domcr_flags, ssidref_t ssidref);
  /* DOMCRF_hvm: Create an HVM domain, as opposed to a PV domain. */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.