diff options
author | Dario Faggioli <dario.faggioli@citrix.com> | 2012-01-04 16:12:44 +0000 |
---|---|---|
committer | Dario Faggioli <dario.faggioli@citrix.com> | 2012-01-04 16:12:44 +0000 |
commit | a33389c34e9dd9e4877dd96c5b189fc9d6230ff7 (patch) | |
tree | 63d9bf351eb96ecfc42e975b702b8da3009dd4bd /xen/common/sched_credit2.c | |
parent | 4da8a5edbd7800568eb4af5adc118e174e876694 (diff) | |
download | xen-a33389c34e9dd9e4877dd96c5b189fc9d6230ff7.tar.gz xen-a33389c34e9dd9e4877dd96c5b189fc9d6230ff7.tar.bz2 xen-a33389c34e9dd9e4877dd96c5b189fc9d6230ff7.zip |
Rework locking for sched_adjust.
The main idea is to move (as much as possible) locking logic
from generic code to the various pluggable schedulers.
While at it, the following is also accomplished:
- pausing all the non-current VCPUs of a domain while changing its
scheduling parameters is not effective in avoiding races and it is
prone to deadlock, so that is removed.
- sedf needs a global lock for preventing races while adjusting
domains' scheduling parameters (as it is for credit and credit2),
so that is added.
Signed-off-by: Dario Faggioli <dario.faggioli@citrix.com>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
Committed-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/common/sched_credit2.c')
-rw-r--r-- | xen/common/sched_credit2.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c index e1838c1db7..65825b4fb3 100644 --- a/xen/common/sched_credit2.c +++ b/xen/common/sched_credit2.c @@ -1384,6 +1384,10 @@ csched_dom_cntl( struct csched_private *prv = CSCHED_PRIV(ops); unsigned long flags; + /* Must hold csched_priv lock to read and update sdom, + * runq lock to update csvcs. */ + spin_lock_irqsave(&prv->lock, flags); + if ( op->cmd == XEN_DOMCTL_SCHEDOP_getinfo ) { op->u.credit2.weight = sdom->weight; @@ -1397,10 +1401,6 @@ csched_dom_cntl( struct list_head *iter; int old_weight; - /* Must hold csched_priv lock to update sdom, runq lock to - * update csvcs. */ - spin_lock_irqsave(&prv->lock, flags); - old_weight = sdom->weight; sdom->weight = op->u.credit2.weight; @@ -1411,22 +1411,23 @@ csched_dom_cntl( struct csched_vcpu *svc = list_entry(iter, struct csched_vcpu, sdom_elem); /* NB: Locking order is important here. Because we grab this lock here, we - * must never lock csched_priv.lock if we're holding a runqueue - * lock. */ - vcpu_schedule_lock_irq(svc->vcpu); + * must never lock csched_priv.lock if we're holding a runqueue lock. + * Also, calling vcpu_schedule_lock() is enough, since IRQs have already + * been disabled. */ + vcpu_schedule_lock(svc->vcpu); BUG_ON(svc->rqd != RQD(ops, svc->vcpu->processor)); svc->weight = sdom->weight; update_max_weight(svc->rqd, svc->weight, old_weight); - vcpu_schedule_unlock_irq(svc->vcpu); + vcpu_schedule_unlock(svc->vcpu); } - - spin_unlock_irqrestore(&prv->lock, flags); } } + spin_unlock_irqrestore(&prv->lock, flags); + return 0; } |