ia64/xen-unstable

changeset 8713:85b79ab1e56d

Fix VCPU locking in sched_adjdom for multi-VCPU guests
author ack@kneesa.uk.xensource.com
date Tue Jan 31 15:24:16 2006 +0000 (2006-01-31)
parents efd7c2f3b496
children bcbe322d80d9
files xen/common/schedule.c
line diff
     1.1 --- a/xen/common/schedule.c	Tue Jan 31 14:29:26 2006 +0100
     1.2 +++ b/xen/common/schedule.c	Tue Jan 31 15:24:16 2006 +0000
     1.3 @@ -305,7 +305,7 @@ long sched_ctl(struct sched_ctl_cmd *cmd
     1.4  long sched_adjdom(struct sched_adjdom_cmd *cmd)
     1.5  {
     1.6      struct domain *d;
     1.7 -    struct vcpu *v;
     1.8 +    struct vcpu *v, *vme;
     1.9      
    1.10      if ( (cmd->sched_id != ops.sched_id) ||
    1.11           ((cmd->direction != SCHED_INFO_PUT) &&
    1.12 @@ -319,24 +319,37 @@ long sched_adjdom(struct sched_adjdom_cm
    1.13      /*
    1.14       * Most VCPUs we can simply pause. If we are adjusting this VCPU then
    1.15       * we acquire the local schedule_lock to guard against concurrent updates.
    1.16 +     *
    1.17 +     * We only acquire the local schedule lock after we have paused all other
    1.18 +     * VCPUs in this domain. There are two reasons for this:
    1.19 +     * 1- We don't want to hold up interrupts as pausing a VCPU can
    1.20 +     *    trigger a tlb shootdown.
    1.21 +     * 2- Pausing other VCPUs involves briefly locking the schedule
    1.22 +     *    lock of the CPU they are running on. This CPU could be the
    1.23 +     *    same as ours.
    1.24       */
    1.25 +    vme = NULL;
    1.26 +
    1.27      for_each_vcpu ( d, v )
    1.28      {
    1.29          if ( v == current )
    1.30 -            vcpu_schedule_lock_irq(v);
    1.31 +            vme = current;
    1.32          else
    1.33              vcpu_pause(v);
    1.34      }
    1.35  
    1.36 -    SCHED_OP(adjdom, d, cmd);
    1.37 +    if (vme)
    1.38 +            vcpu_schedule_lock_irq(vme);
    1.39  
    1.40 +    SCHED_OP(adjdom, d, cmd);
    1.41      TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id);
    1.42  
    1.43 +    if (vme)
    1.44 +            vcpu_schedule_unlock_irq(vme);
    1.45 +
    1.46      for_each_vcpu ( d, v )
    1.47      {
    1.48 -        if ( v == current )
    1.49 -            vcpu_schedule_unlock_irq(v);
    1.50 -        else
    1.51 +        if ( v != vme )
    1.52              vcpu_unpause(v);
    1.53      }
    1.54