bitkeeper revision 1.891.1.25 (40a531dfFMvbTlnuYexvPVp5Q8CzFA)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 14 May 2004 20:53:51 +0000 (20:53 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 14 May 2004 20:53:51 +0000 (20:53 +0000)
Slight possibility of deadlock during domain creation is now fixed.

xen/common/dom0_ops.c

index 9370a61a8d60d552f8fa27a3ff2074af4c639b56..595658101883291edacfa19d16e7b66ba1069477 100644 (file)
 
 extern unsigned int alloc_new_dom_mem(struct task_struct *, unsigned int);
 
-/* Basically used to protect the domain-id space. */
-static spinlock_t create_dom_lock = SPIN_LOCK_UNLOCKED;
-
-static domid_t get_domnr(void)
-{
-    static domid_t domnr = 0;
-    return ++domnr;
-}
-
 static int msr_cpu_mask;
 static unsigned long msr_addr;
 static unsigned long msr_lo;
@@ -109,23 +100,24 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     case DOM0_CREATEDOMAIN:
     {
         struct task_struct *p;
-        static unsigned int pro = 0;
+        static domid_t    domnr = 0;
+        static spinlock_t domnr_lock = SPIN_LOCK_UNLOCKED;
+        unsigned int pro;
         domid_t dom;
         ret = -ENOMEM;
 
-        spin_lock_irq(&create_dom_lock);
-        
-        if ( (dom = get_domnr()) == 0 ) 
-            goto exit_create;
+        spin_lock(&domnr_lock);
+        dom = ++domnr;
+        spin_unlock(&domnr_lock);
 
        if (op->u.createdomain.cpu == -1 )
-           pro = (pro+1) % smp_num_cpus;
+           pro = (unsigned int)dom % smp_num_cpus;
        else
            pro = op->u.createdomain.cpu % smp_num_cpus;
 
         p = do_createdomain(dom, pro);
         if ( p == NULL ) 
-            goto exit_create;
+            break;
 
        if ( op->u.createdomain.name[0] )
         {
@@ -137,16 +129,13 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
         if ( ret != 0 ) 
         {
             __kill_domain(p);
-            goto exit_create;
+            break;
         }
 
         ret = 0;
         
         op->u.createdomain.domain = p->domain;
         copy_to_user(u_dom0_op, op, sizeof(*op));
-    exit_create:
-        spin_unlock_irq(&create_dom_lock);
     }
     break;