]> xenbits.xensource.com Git - xen.git/commitdiff
sched: fix locking when allocating an RTDS pCPU
authorDario Faggioli <dario.faggioli@citrix.com>
Thu, 24 Mar 2016 14:56:56 +0000 (15:56 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 24 Mar 2016 14:56:56 +0000 (15:56 +0100)
as doing that include changing the scheduler lock
mapping for the pCPU itself, and the correct way
of doing that is:
 - take the lock that the pCPU is using right now
   (which may be the lock of another scheduler);
 - change the mapping of the lock to the RTDS one;
 - release the lock (the one that has actually been
   taken!)

Signed-off-by: Dario Faggioli <dario.faggioli@citrix.com>
Reviewed-by: Meng Xu <mengxu@cis.upenn.edu>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
xen/common/sched_rt.c

index c896a6f83eb375be7b03366a756ddc68f262337c..d98bfb606b108c5e568351dc3645ab68f107b63b 100644 (file)
@@ -653,11 +653,16 @@ static void *
 rt_alloc_pdata(const struct scheduler *ops, int cpu)
 {
     struct rt_private *prv = rt_priv(ops);
+    spinlock_t *old_lock;
     unsigned long flags;
 
-    spin_lock_irqsave(&prv->lock, flags);
+    /* Move the scheduler lock to our global runqueue lock.  */
+    old_lock = pcpu_schedule_lock_irqsave(cpu, &flags);
+
     per_cpu(schedule_data, cpu).schedule_lock = &prv->lock;
-    spin_unlock_irqrestore(&prv->lock, flags);
+
+    /* _Not_ pcpu_schedule_unlock(): per_cpu().schedule_lock changed! */
+    spin_unlock_irqrestore(old_lock, flags);
 
     if ( !alloc_cpumask_var(&_cpumask_scratch[cpu]) )
         return NULL;