ia64/xen-unstable

changeset 8511:3eeabf448f91

Clean up domain shutdown and modification of vcpu
processor affinity.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Jan 06 16:47:25 2006 +0100 (2006-01-06)
parents 01a854cd8848
children 82eafda1c710
files xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/xensetup.c xen/arch/x86/dom0_ops.c xen/arch/x86/domain.c xen/arch/x86/mm.c xen/arch/x86/vmx.c xen/arch/x86/vmx_vmcs.c xen/common/dom0_ops.c xen/common/domain.c xen/common/sched_bvt.c xen/common/sched_sedf.c xen/common/schedule.c xen/include/asm-x86/mm.h xen/include/asm-x86/shadow.h xen/include/asm-x86/vmx.h xen/include/asm-x86/vmx_vmcs.h xen/include/xen/domain.h xen/include/xen/sched-if.h xen/include/xen/sched.h
line diff
     1.1 --- a/xen/arch/ia64/xen/domain.c	Fri Jan 06 16:24:46 2006 +0100
     1.2 +++ b/xen/arch/ia64/xen/domain.c	Fri Jan 06 16:47:25 2006 +0100
     1.3 @@ -1070,15 +1070,6 @@ void domain_pend_keyboard_interrupt(int 
     1.4  	vcpu_pend_interrupt(dom0->vcpu[0],irq);
     1.5  }
     1.6  
     1.7 -void vcpu_migrate_cpu(struct vcpu *v, int newcpu)
     1.8 -{
     1.9 -	if ( v->processor == newcpu )
    1.10 -		return;
    1.11 -
    1.12 -	set_bit(_VCPUF_cpu_migrated, &v->vcpu_flags);
    1.13 -	v->processor = newcpu;
    1.14 -}
    1.15 -
    1.16  void sync_vcpu_execstate(struct vcpu *v)
    1.17  {
    1.18  	ia64_save_fpu(v->arch._thread.fph);
     2.1 --- a/xen/arch/ia64/xen/xensetup.c	Fri Jan 06 16:24:46 2006 +0100
     2.2 +++ b/xen/arch/ia64/xen/xensetup.c	Fri Jan 06 16:47:25 2006 +0100
     2.3 @@ -382,7 +382,7 @@ printk("About to call do_createdomain()\
     2.4          panic("Could not set up DOM0 guest OS\n");
     2.5  
     2.6      /* PIN domain0 on CPU 0.  */
     2.7 -    dom0->vcpu[0]->cpumask = cpumask_of_cpu(0);
     2.8 +    dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
     2.9  
    2.10  #ifdef CLONE_DOMAIN0
    2.11      {
     3.1 --- a/xen/arch/x86/dom0_ops.c	Fri Jan 06 16:24:46 2006 +0100
     3.2 +++ b/xen/arch/x86/dom0_ops.c	Fri Jan 06 16:47:25 2006 +0100
     3.3 @@ -36,13 +36,13 @@ static unsigned long msr_hi;
     3.4  
     3.5  static void write_msr_for(void *unused)
     3.6  {
     3.7 -    if ( ((1 << current->processor) & msr_cpu_mask) )
     3.8 +    if ( ((1 << smp_processor_id()) & msr_cpu_mask) )
     3.9          (void)wrmsr_user(msr_addr, msr_lo, msr_hi);
    3.10  }
    3.11  
    3.12  static void read_msr_for(void *unused)
    3.13  {
    3.14 -    if ( ((1 << current->processor) & msr_cpu_mask) )
    3.15 +    if ( ((1 << smp_processor_id()) & msr_cpu_mask) )
    3.16          (void)rdmsr_user(msr_addr, msr_lo, msr_hi);
    3.17  }
    3.18  
     4.1 --- a/xen/arch/x86/domain.c	Fri Jan 06 16:24:46 2006 +0100
     4.2 +++ b/xen/arch/x86/domain.c	Fri Jan 06 16:47:25 2006 +0100
     4.3 @@ -326,21 +326,6 @@ int arch_do_createdomain(struct vcpu *v)
     4.4      return 0;
     4.5  }
     4.6  
     4.7 -void vcpu_migrate_cpu(struct vcpu *v, int newcpu)
     4.8 -{
     4.9 -    if ( v->processor == newcpu )
    4.10 -        return;
    4.11 -
    4.12 -    set_bit(_VCPUF_cpu_migrated, &v->vcpu_flags);
    4.13 -    v->processor = newcpu;
    4.14 -
    4.15 -    if ( VMX_DOMAIN(v) )
    4.16 -    {
    4.17 -        __vmpclear(virt_to_phys(v->arch.arch_vmx.vmcs));
    4.18 -        v->arch.schedule_tail = arch_vmx_do_relaunch;
    4.19 -    }
    4.20 -}
    4.21 -
    4.22  /* This is called by arch_final_setup_guest and do_boot_vcpu */
    4.23  int arch_set_info_guest(
    4.24      struct vcpu *v, struct vcpu_guest_context *c)
     5.1 --- a/xen/arch/x86/mm.c	Fri Jan 06 16:24:46 2006 +0100
     5.2 +++ b/xen/arch/x86/mm.c	Fri Jan 06 16:47:25 2006 +0100
     5.3 @@ -2497,7 +2497,7 @@ int do_update_va_mapping(unsigned long v
     5.4      l1_pgentry_t   val = l1e_from_intpte(val64);
     5.5      struct vcpu   *v   = current;
     5.6      struct domain *d   = v->domain;
     5.7 -    unsigned int   cpu = v->processor;
     5.8 +    unsigned int   cpu = smp_processor_id();
     5.9      unsigned long  vmask, bmap_ptr;
    5.10      cpumask_t      pmask;
    5.11      int            rc  = 0;
     6.1 --- a/xen/arch/x86/vmx.c	Fri Jan 06 16:24:46 2006 +0100
     6.2 +++ b/xen/arch/x86/vmx.c	Fri Jan 06 16:47:25 2006 +0100
     6.3 @@ -53,7 +53,7 @@ unsigned int opt_vmx_debug_level = 0;
     6.4  integer_param("vmx_debug", opt_vmx_debug_level);
     6.5  
     6.6  static unsigned long trace_values[NR_CPUS][4];
     6.7 -#define TRACE_VMEXIT(index,value) trace_values[current->processor][index]=value
     6.8 +#define TRACE_VMEXIT(index,value) trace_values[smp_processor_id()][index]=value
     6.9  
    6.10  static int vmx_switch_on;
    6.11  
    6.12 @@ -1950,9 +1950,12 @@ asmlinkage void load_cr2(void)
    6.13  
    6.14  asmlinkage void trace_vmentry (void)
    6.15  {
    6.16 -    TRACE_5D(TRC_VMENTRY,trace_values[current->processor][0],
    6.17 -             trace_values[current->processor][1],trace_values[current->processor][2],
    6.18 -             trace_values[current->processor][3],trace_values[current->processor][4]);
    6.19 +    TRACE_5D(TRC_VMENTRY,
    6.20 +             trace_values[smp_processor_id()][0],
    6.21 +             trace_values[smp_processor_id()][1],
    6.22 +             trace_values[smp_processor_id()][2],
    6.23 +             trace_values[smp_processor_id()][3],
    6.24 +             trace_values[smp_processor_id()][4]);
    6.25      TRACE_VMEXIT(0,9);
    6.26      TRACE_VMEXIT(1,9);
    6.27      TRACE_VMEXIT(2,9);
     7.1 --- a/xen/arch/x86/vmx_vmcs.c	Fri Jan 06 16:24:46 2006 +0100
     7.2 +++ b/xen/arch/x86/vmx_vmcs.c	Fri Jan 06 16:47:25 2006 +0100
     7.3 @@ -355,6 +355,8 @@ static void vmx_do_launch(struct vcpu *v
     7.4      __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
     7.5  
     7.6      v->arch.schedule_tail = arch_vmx_do_resume;
     7.7 +    v->arch.arch_vmx.launch_cpu = smp_processor_id();
     7.8 +
     7.9      /* init guest tsc to start from 0 */
    7.10      rdtscll(host_tsc);
    7.11      v->arch.arch_vmx.tsc_offset = 0 - host_tsc;
    7.12 @@ -637,11 +639,21 @@ void vm_resume_fail(unsigned long eflags
    7.13  
    7.14  void arch_vmx_do_resume(struct vcpu *v)
    7.15  {
    7.16 -    u64 vmcs_phys_ptr = (u64) virt_to_phys(v->arch.arch_vmx.vmcs);
    7.17 -
    7.18 -    load_vmcs(&v->arch.arch_vmx, vmcs_phys_ptr);
    7.19 -    vmx_do_resume(v);
    7.20 -    reset_stack_and_jump(vmx_asm_do_resume);
    7.21 +    if ( v->arch.arch_vmx.launch_cpu == smp_processor_id() )
    7.22 +    {
    7.23 +        load_vmcs(&v->arch.arch_vmx, virt_to_phys(v->arch.arch_vmx.vmcs));
    7.24 +        vmx_do_resume(v);
    7.25 +        reset_stack_and_jump(vmx_asm_do_resume);
    7.26 +    }
    7.27 +    else
    7.28 +    {
    7.29 +        __vmpclear(virt_to_phys(v->arch.arch_vmx.vmcs));
    7.30 +        load_vmcs(&v->arch.arch_vmx, virt_to_phys(v->arch.arch_vmx.vmcs));
    7.31 +        vmx_do_resume(v);
    7.32 +        vmx_set_host_env(v);
    7.33 +        v->arch.arch_vmx.launch_cpu = smp_processor_id();
    7.34 +        reset_stack_and_jump(vmx_asm_do_relaunch);
    7.35 +    }
    7.36  }
    7.37  
    7.38  void arch_vmx_do_launch(struct vcpu *v)
    7.39 @@ -663,18 +675,6 @@ void arch_vmx_do_launch(struct vcpu *v)
    7.40      reset_stack_and_jump(vmx_asm_do_launch);
    7.41  }
    7.42  
    7.43 -void arch_vmx_do_relaunch(struct vcpu *v)
    7.44 -{
    7.45 -    u64 vmcs_phys_ptr = (u64) virt_to_phys(v->arch.arch_vmx.vmcs);
    7.46 -
    7.47 -    load_vmcs(&v->arch.arch_vmx, vmcs_phys_ptr);
    7.48 -    vmx_do_resume(v);
    7.49 -    vmx_set_host_env(v);
    7.50 -    v->arch.schedule_tail = arch_vmx_do_resume;
    7.51 -
    7.52 -    reset_stack_and_jump(vmx_asm_do_relaunch);
    7.53 -}
    7.54 -
    7.55  #endif /* CONFIG_VMX */
    7.56  
    7.57  /*
     8.1 --- a/xen/common/dom0_ops.c	Fri Jan 06 16:24:46 2006 +0100
     8.2 +++ b/xen/common/dom0_ops.c	Fri Jan 06 16:47:25 2006 +0100
     8.3 @@ -289,6 +289,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     8.4          domid_t dom = op->u.setvcpuaffinity.domain;
     8.5          struct domain *d = find_domain_by_id(dom);
     8.6          struct vcpu *v;
     8.7 +        cpumask_t new_affinity;
     8.8  
     8.9          if ( d == NULL )
    8.10          {
    8.11 @@ -319,14 +320,13 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
    8.12              break;
    8.13          }
    8.14  
    8.15 -        memcpy(cpus_addr(v->cpu_affinity),
    8.16 +        new_affinity = v->cpu_affinity;
    8.17 +        memcpy(cpus_addr(new_affinity),
    8.18                 &op->u.setvcpuaffinity.cpumap,
    8.19                 min((int)BITS_TO_LONGS(NR_CPUS),
    8.20                     (int)sizeof(op->u.setvcpuaffinity.cpumap)));
    8.21  
    8.22 -        vcpu_pause(v);
    8.23 -        vcpu_migrate_cpu(v, first_cpu(v->cpu_affinity));
    8.24 -        vcpu_unpause(v);
    8.25 +        ret = vcpu_set_affinity(v, &new_affinity);
    8.26  
    8.27          put_domain(d);
    8.28      }
     9.1 --- a/xen/common/domain.c	Fri Jan 06 16:24:46 2006 +0100
     9.2 +++ b/xen/common/domain.c	Fri Jan 06 16:47:25 2006 +0100
     9.3 @@ -173,8 +173,8 @@ static void domain_shutdown_finalise(voi
     9.4  
     9.5      BUG_ON(d == NULL);
     9.6      BUG_ON(d == current->domain);
     9.7 -    BUG_ON(!test_bit(_DOMF_shuttingdown, &d->domain_flags));
     9.8 -    BUG_ON(test_bit(_DOMF_shutdown, &d->domain_flags));
     9.9 +
    9.10 +    LOCK_BIGLOCK(d);
    9.11  
    9.12      /* Make sure that every vcpu is descheduled before we finalise. */
    9.13      for_each_vcpu ( d, v )
    9.14 @@ -183,10 +183,13 @@ static void domain_shutdown_finalise(voi
    9.15  
    9.16      sync_pagetable_state(d);
    9.17  
    9.18 -    set_bit(_DOMF_shutdown, &d->domain_flags);
    9.19 -    clear_bit(_DOMF_shuttingdown, &d->domain_flags);
    9.20 +    /* Don't set DOMF_shutdown until execution contexts are sync'ed. */
    9.21 +    if ( !test_and_set_bit(_DOMF_shutdown, &d->domain_flags) )
    9.22 +        send_guest_virq(dom0->vcpu[0], VIRQ_DOM_EXC);
    9.23  
    9.24 -    send_guest_virq(dom0->vcpu[0], VIRQ_DOM_EXC);
    9.25 +    UNLOCK_BIGLOCK(d);
    9.26 +
    9.27 +    put_domain(d);
    9.28  }
    9.29  
    9.30  static __init int domain_shutdown_finaliser_init(void)
    9.31 @@ -222,16 +225,17 @@ void domain_shutdown(struct domain *d, u
    9.32  
    9.33      /* Mark the domain as shutting down. */
    9.34      d->shutdown_code = reason;
    9.35 -    if ( !test_and_set_bit(_DOMF_shuttingdown, &d->domain_flags) )
    9.36 -    {
    9.37 -        /* This vcpu won the race to finalise the shutdown. */
    9.38 -        domain_shuttingdown[smp_processor_id()] = d;
    9.39 -        raise_softirq(DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ);
    9.40 -    }
    9.41  
    9.42      /* Put every vcpu to sleep, but don't wait (avoids inter-vcpu deadlock). */
    9.43      for_each_vcpu ( d, v )
    9.44 +    {
    9.45 +        atomic_inc(&v->pausecnt);
    9.46          vcpu_sleep_nosync(v);
    9.47 +    }
    9.48 +
    9.49 +    get_knownalive_domain(d);
    9.50 +    domain_shuttingdown[smp_processor_id()] = d;
    9.51 +    raise_softirq(DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ);
    9.52  }
    9.53  
    9.54  
    10.1 --- a/xen/common/sched_bvt.c	Fri Jan 06 16:24:46 2006 +0100
    10.2 +++ b/xen/common/sched_bvt.c	Fri Jan 06 16:47:25 2006 +0100
    10.3 @@ -31,7 +31,8 @@ struct bvt_vcpu_info
    10.4      struct list_head    run_list;         /* runqueue list pointers */
    10.5      u32                 avt;              /* actual virtual time */
    10.6      u32                 evt;              /* effective virtual time */
    10.7 -    struct vcpu  *vcpu;
    10.8 +    int                 migrated;         /* migrated to a new CPU */
    10.9 +    struct vcpu         *vcpu;
   10.10      struct bvt_dom_info *inf;
   10.11  };
   10.12  
   10.13 @@ -250,9 +251,11 @@ static void bvt_wake(struct vcpu *v)
   10.14  
   10.15      /* Set the BVT parameters. AVT should always be updated 
   10.16         if CPU migration ocurred.*/
   10.17 -    if ( einf->avt < CPU_SVT(cpu) || 
   10.18 -         unlikely(test_bit(_VCPUF_cpu_migrated, &v->vcpu_flags)) )
   10.19 +    if ( (einf->avt < CPU_SVT(cpu)) || einf->migrated )
   10.20 +    {
   10.21          einf->avt = CPU_SVT(cpu);
   10.22 +        einf->migrated = 0;
   10.23 +    }
   10.24  
   10.25      /* Deal with warping here. */
   10.26      einf->evt = calc_evt(v, einf->avt);
   10.27 @@ -280,6 +283,22 @@ static void bvt_sleep(struct vcpu *v)
   10.28          __del_from_runqueue(v);
   10.29  }
   10.30  
   10.31 +
   10.32 +static int bvt_set_affinity(struct vcpu *v, cpumask_t *affinity)
   10.33 +{
   10.34 +    if ( v == current )
   10.35 +        return cpu_isset(v->processor, *affinity) ? 0 : -EBUSY;
   10.36 +
   10.37 +    vcpu_pause(v);
   10.38 +    v->cpu_affinity = *affinity;
   10.39 +    v->processor = first_cpu(v->cpu_affinity);
   10.40 +    EBVT_INFO(v)->migrated = 1;
   10.41 +    vcpu_unpause(v);
   10.42 +
   10.43 +    return 0;
   10.44 +}
   10.45 +
   10.46 +
   10.47  /**
   10.48   * bvt_free_task - free BVT private structures for a task
   10.49   * @d:             task
   10.50 @@ -557,6 +576,7 @@ struct scheduler sched_bvt_def = {
   10.51      .dump_cpu_state = bvt_dump_cpu_state,
   10.52      .sleep          = bvt_sleep,
   10.53      .wake           = bvt_wake,
   10.54 +    .set_affinity   = bvt_set_affinity
   10.55  };
   10.56  
   10.57  /*
    11.1 --- a/xen/common/sched_sedf.c	Fri Jan 06 16:24:46 2006 +0100
    11.2 +++ b/xen/common/sched_sedf.c	Fri Jan 06 16:47:25 2006 +0100
    11.3 @@ -325,22 +325,30 @@ DOMAIN_COMPARER(runq, list, d1->deadl_ab
    11.4      list_insert_sort(RUNQ(d->processor), LIST(d), runq_comp);
    11.5  }
    11.6  
    11.7 +
    11.8  /* Allocates memory for per domain private scheduling data*/
    11.9 -static int sedf_alloc_task(struct vcpu *d) {
   11.10 -    PRINT(2,"sedf_alloc_task was called, domain-id %i.%i\n",d->domain->domain_id,
   11.11 -          d->vcpu_id);
   11.12 -    if (d->domain->sched_priv == NULL) {
   11.13 -        if ((d->domain->sched_priv = 
   11.14 -             xmalloc(struct sedf_dom_info)) == NULL )
   11.15 +static int sedf_alloc_task(struct vcpu *d)
   11.16 +{
   11.17 +    PRINT(2, "sedf_alloc_task was called, domain-id %i.%i\n",
   11.18 +          d->domain->domain_id, d->vcpu_id);
   11.19 +
   11.20 +    if ( d->domain->sched_priv == NULL )
   11.21 +    {
   11.22 +        d->domain->sched_priv = xmalloc(struct sedf_dom_info);
   11.23 +        if ( d->domain->sched_priv == NULL )
   11.24              return -1;
   11.25          memset(d->domain->sched_priv, 0, sizeof(struct sedf_dom_info));
   11.26      }
   11.27 -    if ((d->sched_priv = xmalloc(struct sedf_vcpu_info)) == NULL )
   11.28 +
   11.29 +    if ( (d->sched_priv = xmalloc(struct sedf_vcpu_info)) == NULL )
   11.30          return -1;
   11.31 +
   11.32      memset(d->sched_priv, 0, sizeof(struct sedf_vcpu_info));
   11.33 +
   11.34      return 0;
   11.35  }
   11.36  
   11.37 +
   11.38  /* Setup the sedf_dom_info */
   11.39  static void sedf_add_task(struct vcpu *d)
   11.40  {
   11.41 @@ -363,14 +371,17 @@ static void sedf_add_task(struct vcpu *d
   11.42          INIT_LIST_HEAD(EXTRAQ(d->processor,EXTRA_UTIL_Q));
   11.43      }
   11.44         
   11.45 -    if (d->domain->domain_id==0) {
   11.46 +    if ( d->domain->domain_id == 0 )
   11.47 +    {
   11.48          /*set dom0 to something useful to boot the machine*/
   11.49          inf->period    = MILLISECS(20);
   11.50          inf->slice     = MILLISECS(15);
   11.51          inf->latency   = 0;
   11.52          inf->deadl_abs = 0;
   11.53          inf->status     = EXTRA_AWARE | SEDF_ASLEEP;
   11.54 -    } else {
   11.55 +    }
   11.56 +    else
   11.57 +    {
   11.58          /*other domains run in best effort mode*/
   11.59          inf->period    = WEIGHT_PERIOD;
   11.60          inf->slice     = 0;
   11.61 @@ -379,14 +390,18 @@ static void sedf_add_task(struct vcpu *d
   11.62          inf->status     = EXTRA_AWARE | SEDF_ASLEEP;
   11.63          inf->extraweight = 1;
   11.64      }
   11.65 +
   11.66      inf->period_orig = inf->period; inf->slice_orig = inf->slice;
   11.67      INIT_LIST_HEAD(&(inf->list));
   11.68      INIT_LIST_HEAD(&(inf->extralist[EXTRA_PEN_Q]));
   11.69      INIT_LIST_HEAD(&(inf->extralist[EXTRA_UTIL_Q]));
   11.70   
   11.71 -    if (!is_idle_domain(d->domain)) {
   11.72 +    if ( !is_idle_domain(d->domain) )
   11.73 +    {
   11.74          extraq_check(d);
   11.75 -    } else {
   11.76 +    }
   11.77 +    else
   11.78 +    {
   11.79          EDOM_INFO(d)->deadl_abs = 0;
   11.80          EDOM_INFO(d)->status &= ~SEDF_ASLEEP;
   11.81      }
   11.82 @@ -396,19 +411,28 @@ static void sedf_add_task(struct vcpu *d
   11.83  static void sedf_free_task(struct domain *d)
   11.84  {
   11.85      int i;
   11.86 +
   11.87      PRINT(2,"sedf_free_task was called, domain-id %i\n",d->domain_id);
   11.88 +
   11.89      ASSERT(d->sched_priv != NULL);
   11.90      xfree(d->sched_priv);
   11.91   
   11.92 -    for (i = 0; i < MAX_VIRT_CPUS; i++)
   11.93 -        if ( d->vcpu[i] ) {
   11.94 +    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
   11.95 +    {
   11.96 +        if ( d->vcpu[i] )
   11.97 +        {
   11.98              ASSERT(d->vcpu[i]->sched_priv != NULL);
   11.99              xfree(d->vcpu[i]->sched_priv);
  11.100          }
  11.101 +    }
  11.102  }
  11.103  
  11.104 -/* handles the rescheduling, bookkeeping of domains running in their realtime-time :)*/
  11.105 -static inline void desched_edf_dom (s_time_t now, struct vcpu* d) {
  11.106 +/*
  11.107 + * Handles the rescheduling & bookkeeping of domains running in their
  11.108 + * guaranteed timeslice.
  11.109 + */
  11.110 +static void desched_edf_dom(s_time_t now, struct vcpu* d)
  11.111 +{
  11.112      struct sedf_vcpu_info* inf = EDOM_INFO(d);
  11.113      /*current domain is running in real time mode*/
  11.114   
  11.115 @@ -418,27 +442,30 @@ static inline void desched_edf_dom (s_ti
  11.116  
  11.117      /*scheduling decisions, which don't remove the running domain
  11.118        from the runq*/
  11.119 -    if ((inf->cputime < inf->slice) && sedf_runnable(d))
  11.120 +    if ( (inf->cputime < inf->slice) && sedf_runnable(d) )
  11.121          return;
  11.122    
  11.123      __del_from_queue(d);
  11.124    
  11.125      /*manage bookkeeping (i.e. calculate next deadline,
  11.126        memorize overun-time of slice) of finished domains*/
  11.127 -    if (inf->cputime >= inf->slice) {
  11.128 +    if ( inf->cputime >= inf->slice )
  11.129 +    {
  11.130          inf->cputime -= inf->slice;
  11.131    
  11.132 -        if (inf->period < inf->period_orig) {
  11.133 +        if ( inf->period < inf->period_orig )
  11.134 +        {
  11.135              /*this domain runs in latency scaling or burst mode*/
  11.136  #if (UNBLOCK == UNBLOCK_BURST)
  11.137              /*if we are runnig in burst scaling wait for two periods
  11.138                before scaling periods up again*/ 
  11.139 -            if (now - inf->unblock_abs >= 2 * inf->period)
  11.140 +            if ( (now - inf->unblock_abs) >= (2 * inf->period) )
  11.141  #endif
  11.142              {
  11.143                  inf->period *= 2; inf->slice *= 2;
  11.144 -                if ((inf->period > inf->period_orig) ||
  11.145 -                    (inf->slice > inf->slice_orig)) {
  11.146 +                if ( (inf->period > inf->period_orig) ||
  11.147 +                     (inf->slice > inf->slice_orig) )
  11.148 +                {
  11.149                      /*reset slice & period*/
  11.150                      inf->period = inf->period_orig;
  11.151                      inf->slice = inf->slice_orig;
  11.152 @@ -450,36 +477,46 @@ static inline void desched_edf_dom (s_ti
  11.153      }
  11.154   
  11.155      /*add a runnable domain to the waitqueue*/
  11.156 -    if (sedf_runnable(d))
  11.157 +    if ( sedf_runnable(d) )
  11.158 +    {
  11.159          __add_to_waitqueue_sort(d);
  11.160 -    else {
  11.161 +    }
  11.162 +    else
  11.163 +    {
  11.164          /*we have a blocked realtime task -> remove it from exqs too*/
  11.165  #if (EXTRA > EXTRA_OFF)
  11.166  #if (EXTRA == EXTRA_BLOCK_WEIGHT)
  11.167 -        if (extraq_on(d, EXTRA_PEN_Q)) extraq_del(d, EXTRA_PEN_Q);
  11.168 +        if ( extraq_on(d, EXTRA_PEN_Q) )
  11.169 +            extraq_del(d, EXTRA_PEN_Q);
  11.170  #endif
  11.171 -        if (extraq_on(d, EXTRA_UTIL_Q)) extraq_del(d, EXTRA_UTIL_Q);
  11.172 +        if ( extraq_on(d, EXTRA_UTIL_Q) )
  11.173 +            extraq_del(d, EXTRA_UTIL_Q);
  11.174  #endif
  11.175      }
  11.176 +
  11.177      ASSERT(EQ(sedf_runnable(d), __task_on_queue(d)));
  11.178      ASSERT(IMPLY(extraq_on(d, EXTRA_UTIL_Q) || extraq_on(d, EXTRA_PEN_Q), 
  11.179                   sedf_runnable(d)));
  11.180  }
  11.181  
  11.182 +
  11.183  /* Update all elements on the queues */
  11.184 -static inline void update_queues(s_time_t now, struct list_head* runq, 
  11.185 -                                 struct list_head* waitq) {
  11.186 -    struct list_head     *cur,*tmp;
  11.187 +static void update_queues(
  11.188 +    s_time_t now, struct list_head *runq, struct list_head *waitq)
  11.189 +{
  11.190 +    struct list_head     *cur, *tmp;
  11.191      struct sedf_vcpu_info *curinf;
  11.192   
  11.193      PRINT(3,"Updating waitq..\n");
  11.194 +
  11.195      /*check for the first elements of the waitqueue, whether their
  11.196        next period has already started*/
  11.197      list_for_each_safe(cur, tmp, waitq) {
  11.198          curinf = list_entry(cur, struct sedf_vcpu_info, list);
  11.199          PRINT(4,"\tLooking @ dom %i.%i\n",
  11.200                curinf->vcpu->domain->domain_id, curinf->vcpu->vcpu_id);
  11.201 -        if (PERIOD_BEGIN(curinf) <= now) {
  11.202 +        if ( PERIOD_BEGIN(curinf) <= now )
  11.203 +        {
  11.204              __del_from_queue(curinf->vcpu);
  11.205              __add_to_runqueue_sort(curinf->vcpu);
  11.206          }
  11.207 @@ -488,13 +525,16 @@ static inline void update_queues(s_time_
  11.208      }
  11.209   
  11.210      PRINT(3,"Updating runq..\n");
  11.211 +
  11.212      /*process the runq, find domains that are on
  11.213        the runqueue which shouldn't be there*/
  11.214      list_for_each_safe(cur, tmp, runq) {
  11.215          curinf = list_entry(cur,struct sedf_vcpu_info,list);
  11.216          PRINT(4,"\tLooking @ dom %i.%i\n",
  11.217                curinf->vcpu->domain->domain_id, curinf->vcpu->vcpu_id);
  11.218 -        if (unlikely(curinf->slice == 0)) {
  11.219 +
  11.220 +        if ( unlikely(curinf->slice == 0) )
  11.221 +        {
  11.222              /*ignore domains with empty slice*/
  11.223              PRINT(4,"\tUpdating zero-slice domain %i.%i\n",
  11.224                    curinf->vcpu->domain->domain_id,
  11.225 @@ -504,7 +544,8 @@ static inline void update_queues(s_time_
  11.226              /*move them to their next period*/
  11.227              curinf->deadl_abs += curinf->period;
  11.228              /*ensure that the start of the next period is in the future*/
  11.229 -            if (unlikely(PERIOD_BEGIN(curinf) < now)) {
  11.230 +            if ( unlikely(PERIOD_BEGIN(curinf) < now) )
  11.231 +            {
  11.232                  curinf->deadl_abs += 
  11.233                      (DIV_UP(now - PERIOD_BEGIN(curinf),
  11.234                             curinf->period)) * curinf->period;
  11.235 @@ -513,8 +554,10 @@ static inline void update_queues(s_time_
  11.236              __add_to_waitqueue_sort(curinf->vcpu);
  11.237              continue;
  11.238          }
  11.239 -        if (unlikely((curinf->deadl_abs < now) ||
  11.240 -                     (curinf->cputime > curinf->slice))) {
  11.241 +
  11.242 +        if ( unlikely((curinf->deadl_abs < now) ||
  11.243 +                      (curinf->cputime > curinf->slice)) )
  11.244 +        {
  11.245              /*we missed the deadline or the slice was
  11.246                already finished... might hapen because
  11.247                of dom_adj.*/
  11.248 @@ -550,6 +593,7 @@ static inline void update_queues(s_time_
  11.249      PRINT(3,"done updating the queues\n");
  11.250  }
  11.251  
  11.252 +
  11.253  #if (EXTRA > EXTRA_OFF)
  11.254  /* removes a domain from the head of the according extraQ and
  11.255     requeues it at a specified position:
  11.256 @@ -557,9 +601,10 @@ static inline void update_queues(s_time_
  11.257       weighted ext.: insert in sorted list by score
  11.258     if the domain is blocked / has regained its short-block-loss
  11.259     time it is not put on any queue */
  11.260 -static inline void desched_extra_dom(s_time_t now, struct vcpu* d) {
  11.261 +static void desched_extra_dom(s_time_t now, struct vcpu* d)
  11.262 +{
  11.263      struct sedf_vcpu_info *inf = EDOM_INFO(d);
  11.264 -    int    i    = extra_get_cur_q(inf);
  11.265 +    int i = extra_get_cur_q(inf);
  11.266   
  11.267  #if (EXTRA == EXTRA_SLICE_WEIGHT || EXTRA == EXTRA_BLOCK_WEIGHT)
  11.268      unsigned long         oldscore;
  11.269 @@ -575,14 +620,15 @@ static inline void desched_extra_dom(s_t
  11.270      extraq_del(d, i);
  11.271  
  11.272  #if (EXTRA == EXTRA_ROUNDR)
  11.273 -    if (sedf_runnable(d) && (inf->status & EXTRA_AWARE))
  11.274 +    if ( sedf_runnable(d) && (inf->status & EXTRA_AWARE) )
  11.275          /*add to the tail if it is runnable => round-robin*/
  11.276          extraq_add_tail(d, EXTRA_UTIL_Q);
  11.277  #elif (EXTRA == EXTRA_SLICE_WEIGHT || EXTRA == EXTRA_BLOCK_WEIGHT)
  11.278      /*update the score*/
  11.279 -    oldscore      = inf->score[i];
  11.280 +    oldscore = inf->score[i];
  11.281  #if (EXTRA == EXTRA_BLOCK_WEIGHT)
  11.282 -    if (i == EXTRA_PEN_Q) {
  11.283 +    if ( i == EXTRA_PEN_Q )
  11.284 +    {
  11.285          /*domain was running in L0 extraq*/
  11.286          /*reduce block lost, probably more sophistication here!*/
  11.287          /*inf->short_block_lost_tot -= EXTRA_QUANTUM;*/
  11.288 @@ -605,12 +651,13 @@ static inline void desched_extra_dom(s_t
  11.289          inf->score[EXTRA_PEN_Q] = (inf->period << 10) /
  11.290              inf->short_block_lost_tot;
  11.291          oldscore = 0;
  11.292 -    } else
  11.293 +    }
  11.294 +    else
  11.295  #endif
  11.296      {
  11.297          /*domain was running in L1 extraq => score is inverse of
  11.298            utilization and is used somewhat incremental!*/
  11.299 -        if (!inf->extraweight)
  11.300 +        if ( !inf->extraweight )
  11.301              /*NB: use fixed point arithmetic with 10 bits*/
  11.302              inf->score[EXTRA_UTIL_Q] = (inf->period << 10) /
  11.303                  inf->slice;
  11.304 @@ -619,24 +666,32 @@ static inline void desched_extra_dom(s_t
  11.305                full (ie 100%) utilization is equivalent to 128 extraweight*/
  11.306              inf->score[EXTRA_UTIL_Q] = (1<<17) / inf->extraweight;
  11.307      }
  11.308 +
  11.309   check_extra_queues:
  11.310      /* Adding a runnable domain to the right queue and removing blocked ones*/
  11.311 -    if (sedf_runnable(d)) {
  11.312 +    if ( sedf_runnable(d) )
  11.313 +    {
  11.314          /*add according to score: weighted round robin*/
  11.315          if (((inf->status & EXTRA_AWARE) && (i == EXTRA_UTIL_Q)) ||
  11.316              ((inf->status & EXTRA_WANT_PEN_Q) && (i == EXTRA_PEN_Q)))
  11.317              extraq_add_sort_update(d, i, oldscore);
  11.318      }
  11.319 -    else {
  11.320 +    else
  11.321 +    {
  11.322          /*remove this blocked domain from the waitq!*/
  11.323          __del_from_queue(d);
  11.324  #if (EXTRA == EXTRA_BLOCK_WEIGHT)
  11.325          /*make sure that we remove a blocked domain from the other
  11.326            extraq too*/
  11.327 -        if (i == EXTRA_PEN_Q) {
  11.328 -            if (extraq_on(d, EXTRA_UTIL_Q)) extraq_del(d, EXTRA_UTIL_Q);
  11.329 -        } else {
  11.330 -            if (extraq_on(d, EXTRA_PEN_Q)) extraq_del(d, EXTRA_PEN_Q);
  11.331 +        if ( i == EXTRA_PEN_Q )
  11.332 +        {
  11.333 +            if ( extraq_on(d, EXTRA_UTIL_Q) )
  11.334 +                extraq_del(d, EXTRA_UTIL_Q);
  11.335 +        }
  11.336 +        else
  11.337 +        {
  11.338 +            if ( extraq_on(d, EXTRA_PEN_Q) )
  11.339 +                extraq_del(d, EXTRA_PEN_Q);
  11.340          }
  11.341  #endif
  11.342      }
  11.343 @@ -647,16 +702,21 @@ static inline void desched_extra_dom(s_t
  11.344  }
  11.345  #endif
  11.346  
  11.347 -static inline struct task_slice sedf_do_extra_schedule (s_time_t now,
  11.348 -                                                        s_time_t end_xt, struct list_head *extraq[], int cpu) {
  11.349 +
  11.350 +static struct task_slice sedf_do_extra_schedule(
  11.351 +    s_time_t now, s_time_t end_xt, struct list_head *extraq[], int cpu)
  11.352 +{
  11.353      struct task_slice   ret;
  11.354      struct sedf_vcpu_info *runinf;
  11.355      ASSERT(end_xt > now);
  11.356 +
  11.357      /* Enough time left to use for extratime? */
  11.358 -    if (end_xt - now < EXTRA_QUANTUM)
  11.359 +    if ( end_xt - now < EXTRA_QUANTUM )
  11.360          goto return_idle;
  11.361 +
  11.362  #if (EXTRA == EXTRA_BLOCK_WEIGHT)
  11.363 -    if (!list_empty(extraq[EXTRA_PEN_Q])) {
  11.364 +    if ( !list_empty(extraq[EXTRA_PEN_Q]) )
  11.365 +    {
  11.366          /*we still have elements on the level 0 extraq 
  11.367            => let those run first!*/
  11.368          runinf   = list_entry(extraq[EXTRA_PEN_Q]->next, 
  11.369 @@ -667,9 +727,12 @@ static inline struct task_slice sedf_do_
  11.370  #ifdef SEDF_STATS
  11.371          runinf->pen_extra_slices++;
  11.372  #endif
  11.373 -    } else
  11.374 +    }
  11.375 +    else
  11.376  #endif
  11.377 -        if (!list_empty(extraq[EXTRA_UTIL_Q])) {
  11.378 +    {
  11.379 +        if ( !list_empty(extraq[EXTRA_UTIL_Q]) )
  11.380 +        {
  11.381              /*use elements from the normal extraqueue*/
  11.382              runinf   = list_entry(extraq[EXTRA_UTIL_Q]->next,
  11.383                                    struct sedf_vcpu_info,
  11.384 @@ -680,6 +743,7 @@ static inline struct task_slice sedf_do_
  11.385          }
  11.386          else
  11.387              goto return_idle;
  11.388 +    }
  11.389  
  11.390      ASSERT(ret.time > 0);
  11.391      ASSERT(sedf_runnable(ret.task));
  11.392 @@ -692,6 +756,8 @@ static inline struct task_slice sedf_do_
  11.393      ASSERT(sedf_runnable(ret.task));
  11.394      return ret;
  11.395  }
  11.396 +
  11.397 +
  11.398  /* Main scheduling function
  11.399     Reasons for calling this function are:
  11.400     -timeslice for the current period used up
  11.401 @@ -699,7 +765,7 @@ static inline struct task_slice sedf_do_
  11.402     -and various others ;) in general: determine which domain to run next*/
  11.403  static struct task_slice sedf_do_schedule(s_time_t now)
  11.404  {
  11.405 -    int                   cpu      = current->processor;
  11.406 +    int                   cpu      = smp_processor_id();
  11.407      struct list_head     *runq     = RUNQ(cpu);
  11.408      struct list_head     *waitq    = WAITQ(cpu);
  11.409  #if (EXTRA > EXTRA_OFF)
  11.410 @@ -717,14 +783,15 @@ static struct task_slice sedf_do_schedul
  11.411      /* create local state of the status of the domain, in order to avoid
  11.412         inconsistent state during scheduling decisions, because data for
  11.413         domain_runnable is not protected by the scheduling lock!*/
  11.414 -    if(!domain_runnable(current))
  11.415 +    if ( !domain_runnable(current) )
  11.416          inf->status |= SEDF_ASLEEP;
  11.417   
  11.418 -    if (inf->status & SEDF_ASLEEP)
  11.419 +    if ( inf->status & SEDF_ASLEEP )
  11.420          inf->block_abs = now;
  11.421  
  11.422  #if (EXTRA > EXTRA_OFF)
  11.423 -    if (unlikely(extra_runs(inf))) {
  11.424 +    if ( unlikely(extra_runs(inf)) )
  11.425 +    {
  11.426          /*special treatment of domains running in extra time*/
  11.427          desched_extra_dom(now, current);
  11.428      }
  11.429 @@ -739,10 +806,12 @@ static struct task_slice sedf_do_schedul
  11.430      /*now simply pick the first domain from the runqueue, which has the
  11.431        earliest deadline, because the list is sorted*/
  11.432   
  11.433 -    if (!list_empty(runq)) {
  11.434 +    if ( !list_empty(runq) )
  11.435 +    {
  11.436          runinf   = list_entry(runq->next,struct sedf_vcpu_info,list);
  11.437          ret.task = runinf->vcpu;
  11.438 -        if (!list_empty(waitq)) {
  11.439 +        if ( !list_empty(waitq) )
  11.440 +        {
  11.441              waitinf  = list_entry(waitq->next,
  11.442                                    struct sedf_vcpu_info,list);
  11.443              /*rerun scheduler, when scheduled domain reaches it's
  11.444 @@ -751,14 +820,16 @@ static struct task_slice sedf_do_schedul
  11.445              ret.time = MIN(now + runinf->slice - runinf->cputime,
  11.446                             PERIOD_BEGIN(waitinf)) - now;
  11.447          }
  11.448 -        else {
  11.449 +        else
  11.450 +        {
  11.451              ret.time = runinf->slice - runinf->cputime;
  11.452          }
  11.453          CHECK(ret.time > 0);
  11.454          goto sched_done;
  11.455      }
  11.456   
  11.457 -    if (!list_empty(waitq)) {
  11.458 +    if ( !list_empty(waitq) )
  11.459 +    {
  11.460          waitinf  = list_entry(waitq->next,struct sedf_vcpu_info, list);
  11.461          /*we could not find any suitable domain 
  11.462            => look for domains that are aware of extratime*/
  11.463 @@ -771,7 +842,8 @@ static struct task_slice sedf_do_schedul
  11.464  #endif
  11.465          CHECK(ret.time > 0);
  11.466      }
  11.467 -    else {
  11.468 +    else
  11.469 +    {
  11.470          /*this could probably never happen, but one never knows...*/
  11.471          /*it can... imagine a second CPU, which is pure scifi ATM,
  11.472            but one never knows ;)*/
  11.473 @@ -782,11 +854,13 @@ static struct task_slice sedf_do_schedul
  11.474   sched_done: 
  11.475      /*TODO: Do something USEFUL when this happens and find out, why it
  11.476        still can happen!!!*/
  11.477 -    if (ret.time<0) {
  11.478 +    if ( ret.time < 0)
  11.479 +    {
  11.480          printk("Ouch! We are seriously BEHIND schedule! %"PRIi64"\n",
  11.481                 ret.time);
  11.482          ret.time = EXTRA_QUANTUM;
  11.483      }
  11.484 +
  11.485      EDOM_INFO(ret.task)->sched_start_abs = now;
  11.486      CHECK(ret.time > 0);
  11.487      ASSERT(sedf_runnable(ret.task));
  11.488 @@ -794,31 +868,37 @@ static struct task_slice sedf_do_schedul
  11.489      return ret;
  11.490  }
  11.491  
  11.492 -static void sedf_sleep(struct vcpu *d) {
  11.493 -    PRINT(2,"sedf_sleep was called, domain-id %i.%i\n",d->domain->domain_id, d->vcpu_id);
  11.494 +
  11.495 +static void sedf_sleep(struct vcpu *d)
  11.496 +{
  11.497 +    PRINT(2,"sedf_sleep was called, domain-id %i.%i\n",
  11.498 +          d->domain->domain_id, d->vcpu_id);
  11.499   
  11.500 -    if (is_idle_domain(d->domain))
  11.501 +    if ( is_idle_domain(d->domain) )
  11.502          return;
  11.503  
  11.504      EDOM_INFO(d)->status |= SEDF_ASLEEP;
  11.505   
  11.506 -    if ( test_bit(_VCPUF_running, &d->vcpu_flags) ) {
  11.507 +    if ( test_bit(_VCPUF_running, &d->vcpu_flags) )
  11.508 +    {
  11.509          cpu_raise_softirq(d->processor, SCHEDULE_SOFTIRQ);
  11.510      }
  11.511 -    else  {
  11.512 +    else
  11.513 +    {
  11.514          if ( __task_on_queue(d) )
  11.515              __del_from_queue(d);
  11.516  #if (EXTRA > EXTRA_OFF)
  11.517 -        if (extraq_on(d, EXTRA_UTIL_Q)) 
  11.518 +        if ( extraq_on(d, EXTRA_UTIL_Q) ) 
  11.519              extraq_del(d, EXTRA_UTIL_Q);
  11.520  #endif
  11.521  #if (EXTRA == EXTRA_BLOCK_WEIGHT)
  11.522 -        if (extraq_on(d, EXTRA_PEN_Q))
  11.523 +        if ( extraq_on(d, EXTRA_PEN_Q) )
  11.524              extraq_del(d, EXTRA_PEN_Q);
  11.525  #endif
  11.526      }
  11.527  }
  11.528  
  11.529 +
  11.530  /* This function wakes up a domain, i.e. moves them into the waitqueue
  11.531   * things to mention are: admission control is taking place nowhere at
  11.532   * the moment, so we can't be sure, whether it is safe to wake the domain
  11.533 @@ -890,17 +970,21 @@ static void sedf_sleep(struct vcpu *d) {
  11.534   *     -either behaviour can lead to missed deadlines in other domains as
  11.535   *      opposed to approaches 1,2a,2b
  11.536   */
  11.537 -static inline void unblock_short_vcons
  11.538 -(struct sedf_vcpu_info* inf, s_time_t now) {
  11.539 +#if (UNBLOCK <= UNBLOCK_SHORT_RESUME)
  11.540 +static void unblock_short_vcons(struct sedf_vcpu_info* inf, s_time_t now)
  11.541 +{
  11.542      inf->deadl_abs += inf->period;
  11.543      inf->cputime = 0;
  11.544  }
  11.545 +#endif
  11.546  
  11.547 -static inline void unblock_short_cons(struct sedf_vcpu_info* inf, s_time_t now)
  11.548 +#if (UNBLOCK == UNBLOCK_SHORT_RESUME)
  11.549 +static void unblock_short_cons(struct sedf_vcpu_info* inf, s_time_t now)
  11.550  {
  11.551      /*treat blocked time as consumed by the domain*/
  11.552      inf->cputime += now - inf->block_abs; 
  11.553 -    if (inf->cputime + EXTRA_QUANTUM > inf->slice) {
  11.554 +    if ( (inf->cputime + EXTRA_QUANTUM) > inf->slice )
  11.555 +    {
  11.556          /*we don't have a reasonable amount of time in 
  11.557            our slice left :( => start in next period!*/
  11.558          unblock_short_vcons(inf, now);
  11.559 @@ -910,8 +994,11 @@ static inline void unblock_short_cons(st
  11.560          inf->short_cont++;
  11.561  #endif
  11.562  }
  11.563 -static inline void unblock_short_extra_support (struct sedf_vcpu_info* inf,
  11.564 -                                                s_time_t now) {
  11.565 +#endif
  11.566 +
  11.567 +static void unblock_short_extra_support(
  11.568 +    struct sedf_vcpu_info* inf, s_time_t now)
  11.569 +{
  11.570      /*this unblocking scheme tries to support the domain, by assigning it
  11.571      a priority in extratime distribution according to the loss of time
  11.572      in this slice due to blocking*/
  11.573 @@ -919,26 +1006,29 @@ static inline void unblock_short_extra_s
  11.574   
  11.575      /*no more realtime execution in this period!*/
  11.576      inf->deadl_abs += inf->period;
  11.577 -    if (likely(inf->block_abs)) {
  11.578 +    if ( likely(inf->block_abs) )
  11.579 +    {
  11.580          //treat blocked time as consumed by the domain*/
  11.581          /*inf->cputime += now - inf->block_abs;*/
  11.582          /*penalty is time the domain would have
  11.583            had if it continued to run */
  11.584          pen = (inf->slice - inf->cputime);
  11.585 -        if (pen < 0) pen = 0;
  11.586 +        if ( pen < 0 )
  11.587 +            pen = 0;
  11.588          /*accumulate all penalties over the periods*/
  11.589          /*inf->short_block_lost_tot += pen;*/
  11.590          /*set penalty to the current value*/
  11.591          inf->short_block_lost_tot = pen;
  11.592          /*not sure which one is better.. but seems to work well...*/
  11.593    
  11.594 -        if (inf->short_block_lost_tot) {
  11.595 +        if ( inf->short_block_lost_tot )
  11.596 +        {
  11.597              inf->score[0] = (inf->period << 10) /
  11.598                  inf->short_block_lost_tot;
  11.599  #ifdef SEDF_STATS
  11.600              inf->pen_extra_blocks++;
  11.601  #endif
  11.602 -            if (extraq_on(inf->vcpu, EXTRA_PEN_Q))
  11.603 +            if ( extraq_on(inf->vcpu, EXTRA_PEN_Q) )
  11.604                  /*remove domain for possible resorting!*/
  11.605                  extraq_del(inf->vcpu, EXTRA_PEN_Q);
  11.606              else
  11.607 @@ -951,36 +1041,53 @@ static inline void unblock_short_extra_s
  11.608              extraq_add_sort_update(inf->vcpu, EXTRA_PEN_Q, 0);
  11.609          }
  11.610      }
  11.611 +
  11.612      /*give it a fresh slice in the next period!*/
  11.613      inf->cputime = 0;
  11.614  }
  11.615 -static inline void unblock_long_vcons(struct sedf_vcpu_info* inf, s_time_t now)
  11.616 +
  11.617 +
  11.618 +#if (UNBLOCK == UNBLOCK_ISOCHRONOUS_EDF)
  11.619 +static void unblock_long_vcons(struct sedf_vcpu_info* inf, s_time_t now)
  11.620  {
  11.621      /* align to next future period */
  11.622      inf->deadl_abs += (DIV_UP(now - inf->deadl_abs, inf->period) +1)
  11.623          * inf->period;
  11.624      inf->cputime = 0;
  11.625  }
  11.626 +#endif
  11.627  
  11.628 -static inline void unblock_long_cons_a (struct sedf_vcpu_info* inf,
  11.629 -                                        s_time_t now) {
  11.630 +
  11.631 +#if 0
  11.632 +static void unblock_long_cons_a (struct sedf_vcpu_info* inf, s_time_t now)
  11.633 +{
  11.634      /*treat the time the domain was blocked in the
  11.635 -   CURRENT period as consumed by the domain*/
  11.636 +     CURRENT period as consumed by the domain*/
  11.637      inf->cputime = (now - inf->deadl_abs) % inf->period; 
  11.638 -    if (inf->cputime + EXTRA_QUANTUM > inf->slice) {
  11.639 +    if ( (inf->cputime + EXTRA_QUANTUM) > inf->slice )
  11.640 +    {
  11.641          /*we don't have a reasonable amount of time in our slice
  11.642            left :( => start in next period!*/
  11.643          unblock_long_vcons(inf, now);
  11.644      }
  11.645  }
  11.646 -static inline void unblock_long_cons_b(struct sedf_vcpu_info* inf,s_time_t now) {
  11.647 +#endif
  11.648 +
  11.649 +
  11.650 +static void unblock_long_cons_b(struct sedf_vcpu_info* inf,s_time_t now)
  11.651 +{
  11.652      /*Conservative 2b*/
  11.653      /*Treat the unblocking time as a start of a new period */
  11.654      inf->deadl_abs = now + inf->period;
  11.655      inf->cputime = 0;
  11.656  }
  11.657 -static inline void unblock_long_cons_c(struct sedf_vcpu_info* inf,s_time_t now) {
  11.658 -    if (likely(inf->latency)) {
  11.659 +
  11.660 +
  11.661 +#if (UNBLOCK == UNBLOCK_ATROPOS)
  11.662 +static void unblock_long_cons_c(struct sedf_vcpu_info* inf,s_time_t now)
  11.663 +{
  11.664 +    if ( likely(inf->latency) )
  11.665 +    {
  11.666          /*scale the slice and period accordingly to the latency hint*/
  11.667          /*reduce period temporarily to the latency hint*/
  11.668          inf->period = inf->latency;
  11.669 @@ -993,18 +1100,24 @@ static inline void unblock_long_cons_c(s
  11.670          inf->deadl_abs = now + inf->period;
  11.671          inf->cputime = 0;
  11.672      } 
  11.673 -    else {
  11.674 +    else
  11.675 +    {
  11.676          /*we don't have a latency hint.. use some other technique*/
  11.677          unblock_long_cons_b(inf, now);
  11.678      }
  11.679  }
  11.680 +#endif
  11.681 +
  11.682 +
  11.683 +#if (UNBLOCK == UNBLOCK_BURST)
  11.684  /*a new idea of dealing with short blocks: burst period scaling*/
  11.685 -static inline void unblock_short_burst(struct sedf_vcpu_info* inf, s_time_t now)
  11.686 +static void unblock_short_burst(struct sedf_vcpu_info* inf, s_time_t now)
  11.687  {
  11.688      /*treat blocked time as consumed by the domain*/
  11.689      inf->cputime += now - inf->block_abs;
  11.690   
  11.691 -    if (inf->cputime + EXTRA_QUANTUM <= inf->slice) {
  11.692 +    if ( (inf->cputime + EXTRA_QUANTUM) <= inf->slice )
  11.693 +    {
  11.694          /*if we can still use some time in the current slice
  11.695            then use it!*/
  11.696  #ifdef SEDF_STATS
  11.697 @@ -1012,10 +1125,12 @@ static inline void unblock_short_burst(s
  11.698          inf->short_cont++;
  11.699  #endif
  11.700      }
  11.701 -    else {
  11.702 +    else
  11.703 +    {
  11.704          /*we don't have a reasonable amount of time in
  11.705            our slice left => switch to burst mode*/
  11.706 -        if (likely(inf->unblock_abs)) {
  11.707 +        if ( likely(inf->unblock_abs) )
  11.708 +        {
  11.709              /*set the period-length to the current blocking
  11.710                interval, possible enhancements: average over last
  11.711                blocking intervals, user-specified minimum,...*/
  11.712 @@ -1030,17 +1145,23 @@ static inline void unblock_short_burst(s
  11.713              /*set new (shorter) deadline*/
  11.714              inf->deadl_abs += inf->period;
  11.715          }
  11.716 -        else {
  11.717 +        else
  11.718 +        {
  11.719              /*in case we haven't unblocked before
  11.720                start in next period!*/
  11.721              inf->cputime=0;
  11.722              inf->deadl_abs += inf->period;
  11.723          }
  11.724      }
  11.725 +
  11.726      inf->unblock_abs = now;
  11.727  }
  11.728 -static inline void unblock_long_burst(struct sedf_vcpu_info* inf, s_time_t now) {
  11.729 -    if (unlikely(inf->latency && (inf->period > inf->latency))) {
  11.730 +
  11.731 +
  11.732 +static void unblock_long_burst(struct sedf_vcpu_info* inf, s_time_t now)
  11.733 +{
  11.734 +    if ( unlikely(inf->latency && (inf->period > inf->latency)) )
  11.735 +    {
  11.736          /*scale the slice and period accordingly to the latency hint*/
  11.737          inf->period = inf->latency;
  11.738          /*check for overflows on multiplication*/
  11.739 @@ -1052,21 +1173,26 @@ static inline void unblock_long_burst(st
  11.740          inf->deadl_abs = now + inf->period;
  11.741          inf->cputime = 0;
  11.742      }
  11.743 -    else {
  11.744 +    else
  11.745 +    {
  11.746          /*we don't have a latency hint.. or we are currently in 
  11.747            "burst mode": use some other technique
  11.748            NB: this should be in fact the normal way of operation,
  11.749            when we are in sync with the device!*/
  11.750          unblock_long_cons_b(inf, now);
  11.751      }
  11.752 +
  11.753      inf->unblock_abs = now;
  11.754  }
  11.755 +#endif /* UNBLOCK == UNBLOCK_BURST */
  11.756 +
  11.757  
  11.758  #define DOMAIN_EDF   1
  11.759  #define DOMAIN_EXTRA_PEN  2
  11.760  #define DOMAIN_EXTRA_UTIL  3
  11.761  #define DOMAIN_IDLE   4
  11.762 -static inline int get_run_type(struct vcpu* d) {
  11.763 +static inline int get_run_type(struct vcpu* d)
  11.764 +{
  11.765      struct sedf_vcpu_info* inf = EDOM_INFO(d);
  11.766      if (is_idle_domain(d->domain))
  11.767          return DOMAIN_IDLE;
  11.768 @@ -1076,6 +1202,8 @@ static inline int get_run_type(struct vc
  11.769          return DOMAIN_EXTRA_UTIL;
  11.770      return DOMAIN_EDF;
  11.771  }
  11.772 +
  11.773 +
  11.774  /*Compares two domains in the relation of whether the one is allowed to
  11.775    interrupt the others execution.
  11.776    It returns true (!=0) if a switch to the other domain is good.
  11.777 @@ -1085,8 +1213,10 @@ static inline int get_run_type(struct vc
  11.778    In the same class priorities are assigned as following:
  11.779     EDF: early deadline > late deadline
  11.780     L0 extra-time: lower score > higher score*/
  11.781 -static inline int should_switch(struct vcpu* cur,
  11.782 -                                struct vcpu* other, s_time_t now) {
  11.783 +static inline int should_switch(struct vcpu *cur,
  11.784 +                                struct vcpu *other,
  11.785 +                                s_time_t now)
  11.786 +{
  11.787      struct sedf_vcpu_info *cur_inf, *other_inf;
  11.788      cur_inf   = EDOM_INFO(cur);
  11.789      other_inf = EDOM_INFO(other);
  11.790 @@ -1119,41 +1249,51 @@ static inline int should_switch(struct v
  11.791      }
  11.792      return 1;
  11.793  }
  11.794 -void sedf_wake(struct vcpu *d) {
  11.795 +
  11.796 +void sedf_wake(struct vcpu *d)
  11.797 +{
  11.798      s_time_t              now = NOW();
  11.799      struct sedf_vcpu_info* inf = EDOM_INFO(d);
  11.800  
  11.801      PRINT(3, "sedf_wake was called, domain-id %i.%i\n",d->domain->domain_id,
  11.802            d->vcpu_id);
  11.803  
  11.804 -    if (unlikely(is_idle_domain(d->domain)))
  11.805 +    if ( unlikely(is_idle_domain(d->domain)) )
  11.806          return;
  11.807     
  11.808 -    if ( unlikely(__task_on_queue(d)) ) {
  11.809 +    if ( unlikely(__task_on_queue(d)) )
  11.810 +    {
  11.811          PRINT(3,"\tdomain %i.%i is already in some queue\n",
  11.812                d->domain->domain_id, d->vcpu_id);
  11.813          return;
  11.814      }
  11.815 +
  11.816      ASSERT(!sedf_runnable(d));
  11.817      inf->status &= ~SEDF_ASLEEP;
  11.818      ASSERT(!extraq_on(d, EXTRA_UTIL_Q));
  11.819      ASSERT(!extraq_on(d, EXTRA_PEN_Q));
  11.820   
  11.821 -    if (unlikely(inf->deadl_abs == 0))
  11.822 +    if ( unlikely(inf->deadl_abs == 0) )
  11.823 +    {
  11.824          /*initial setup of the deadline*/
  11.825          inf->deadl_abs = now + inf->slice;
  11.826 +    }
  11.827    
  11.828 -    PRINT(3,"waking up domain %i.%i (deadl= %"PRIu64" period= %"PRIu64" "\
  11.829 -          "now= %"PRIu64")\n", d->domain->domain_id, d->vcpu_id, inf->deadl_abs,
  11.830 -          inf->period, now);
  11.831 +    PRINT(3, "waking up domain %i.%i (deadl= %"PRIu64" period= %"PRIu64
  11.832 +          "now= %"PRIu64")\n",
  11.833 +          d->domain->domain_id, d->vcpu_id, inf->deadl_abs, inf->period, now);
  11.834 +
  11.835  #ifdef SEDF_STATS 
  11.836      inf->block_tot++;
  11.837  #endif
  11.838 -    if (unlikely(now < PERIOD_BEGIN(inf))) {
  11.839 +
  11.840 +    if ( unlikely(now < PERIOD_BEGIN(inf)) )
  11.841 +    {
  11.842          PRINT(4,"extratime unblock\n");
  11.843          /* unblocking in extra-time! */
  11.844  #if (EXTRA == EXTRA_BLOCK_WEIGHT)
  11.845 -        if (inf->status & EXTRA_WANT_PEN_Q) {
  11.846 +        if ( inf->status & EXTRA_WANT_PEN_Q )
  11.847 +        {
  11.848              /*we have a domain that wants compensation
  11.849                for block penalty and did just block in
  11.850                its compensation time. Give it another
  11.851 @@ -1163,8 +1303,10 @@ void sedf_wake(struct vcpu *d) {
  11.852  #endif
  11.853          extraq_check_add_unblocked(d, 0);
  11.854      }  
  11.855 -    else {  
  11.856 -        if (now < inf->deadl_abs) {
  11.857 +    else
  11.858 +    {  
  11.859 +        if ( now < inf->deadl_abs )
  11.860 +        {
  11.861              PRINT(4,"short unblocking\n");
  11.862              /*short blocking*/
  11.863  #ifdef SEDF_STATS
  11.864 @@ -1182,7 +1324,8 @@ void sedf_wake(struct vcpu *d) {
  11.865  
  11.866              extraq_check_add_unblocked(d, 1);
  11.867          }
  11.868 -        else {
  11.869 +        else
  11.870 +        {
  11.871              PRINT(4,"long unblocking\n");
  11.872              /*long unblocking*/
  11.873  #ifdef SEDF_STATS
  11.874 @@ -1197,7 +1340,6 @@ void sedf_wake(struct vcpu *d) {
  11.875              unblock_long_cons_c(inf, now);
  11.876  #elif (UNBLOCK == UNBLOCK_SHORT_RESUME)
  11.877              unblock_long_cons_b(inf, now);
  11.878 -            /*unblock_short_cons_c(inf, now);*/
  11.879  #elif (UNBLOCK == UNBLOCK_BURST)
  11.880              unblock_long_burst(inf, now);
  11.881  #endif
  11.882 @@ -1205,26 +1347,33 @@ void sedf_wake(struct vcpu *d) {
  11.883              extraq_check_add_unblocked(d, 1);
  11.884          }
  11.885      }
  11.886 -    PRINT(3,"woke up domain %i.%i (deadl= %"PRIu64" period= %"PRIu64" "\
  11.887 -          "now= %"PRIu64")\n", d->domain->domain_id, d->vcpu_id, inf->deadl_abs,
  11.888 +
  11.889 +    PRINT(3, "woke up domain %i.%i (deadl= %"PRIu64" period= %"PRIu64
  11.890 +          "now= %"PRIu64")\n",
  11.891 +          d->domain->domain_id, d->vcpu_id, inf->deadl_abs,
  11.892            inf->period, now);
  11.893 -    if (PERIOD_BEGIN(inf) > now) {
  11.894 +
  11.895 +    if ( PERIOD_BEGIN(inf) > now )
  11.896 +    {
  11.897          __add_to_waitqueue_sort(d);
  11.898          PRINT(3,"added to waitq\n");
  11.899      }
  11.900 -    else {
  11.901 +    else
  11.902 +    {
  11.903          __add_to_runqueue_sort(d);
  11.904          PRINT(3,"added to runq\n");
  11.905      }
  11.906   
  11.907  #ifdef SEDF_STATS
  11.908      /*do some statistics here...*/
  11.909 -    if (inf->block_abs != 0) {
  11.910 +    if ( inf->block_abs != 0 )
  11.911 +    {
  11.912          inf->block_time_tot += now - inf->block_abs;
  11.913          inf->penalty_time_tot +=
  11.914              PERIOD_BEGIN(inf) + inf->cputime - inf->block_abs;
  11.915      }
  11.916  #endif
  11.917 +
  11.918      /*sanity check: make sure each extra-aware domain IS on the util-q!*/
  11.919      ASSERT(IMPLY(inf->status & EXTRA_AWARE, extraq_on(d, EXTRA_UTIL_Q)));
  11.920      ASSERT(__task_on_queue(d));
  11.921 @@ -1234,27 +1383,48 @@ void sedf_wake(struct vcpu *d) {
  11.922      ASSERT(d->processor >= 0);
  11.923      ASSERT(d->processor < NR_CPUS);
  11.924      ASSERT(schedule_data[d->processor].curr);
  11.925 -    if (should_switch(schedule_data[d->processor].curr, d, now))
  11.926 +
  11.927 +    if ( should_switch(schedule_data[d->processor].curr, d, now) )
  11.928          cpu_raise_softirq(d->processor, SCHEDULE_SOFTIRQ);
  11.929  }
  11.930  
  11.931 -/*Print a lot of use-{full, less} information about a domains in the system*/
  11.932 -static void sedf_dump_domain(struct vcpu *d) {
  11.933 +
  11.934 +static int sedf_set_affinity(struct vcpu *v, cpumask_t *affinity)
  11.935 +{
  11.936 +    if ( v == current )
  11.937 +        return cpu_isset(v->processor, *affinity) ? 0 : -EBUSY;
  11.938 +
  11.939 +    vcpu_pause(v);
  11.940 +    v->cpu_affinity = *affinity;
  11.941 +    v->processor = first_cpu(v->cpu_affinity);
  11.942 +    vcpu_unpause(v);
  11.943 +
  11.944 +    return 0;
  11.945 +}
  11.946 +
  11.947 +
  11.948 +/* Print a lot of useful information about a domains in the system */
  11.949 +static void sedf_dump_domain(struct vcpu *d)
  11.950 +{
  11.951      printk("%i.%i has=%c ", d->domain->domain_id, d->vcpu_id,
  11.952             test_bit(_VCPUF_running, &d->vcpu_flags) ? 'T':'F');
  11.953 -    printk("p=%"PRIu64" sl=%"PRIu64" ddl=%"PRIu64" w=%hu c=%"PRIu64" sc=%i xtr(%s)=%"PRIu64" ew=%hu",
  11.954 +    printk("p=%"PRIu64" sl=%"PRIu64" ddl=%"PRIu64" w=%hu c=%"PRIu64
  11.955 +           " sc=%i xtr(%s)=%"PRIu64" ew=%hu",
  11.956             EDOM_INFO(d)->period, EDOM_INFO(d)->slice, EDOM_INFO(d)->deadl_abs,
  11.957 -           EDOM_INFO(d)->weight, d->cpu_time, EDOM_INFO(d)->score[EXTRA_UTIL_Q],
  11.958 +           EDOM_INFO(d)->weight, d->cpu_time,
  11.959 +           EDOM_INFO(d)->score[EXTRA_UTIL_Q],
  11.960             (EDOM_INFO(d)->status & EXTRA_AWARE) ? "yes" : "no",
  11.961             EDOM_INFO(d)->extra_time_tot, EDOM_INFO(d)->extraweight);
  11.962 -    if (d->cpu_time !=0)
  11.963 +    
  11.964 +    if ( d->cpu_time != 0 )
  11.965          printf(" (%"PRIu64"%%)", (EDOM_INFO(d)->extra_time_tot * 100)
  11.966                 / d->cpu_time);
  11.967 +
  11.968  #ifdef SEDF_STATS
  11.969 -    if (EDOM_INFO(d)->block_time_tot!=0)
  11.970 +    if ( EDOM_INFO(d)->block_time_tot != 0 )
  11.971          printf(" pen=%"PRIu64"%%", (EDOM_INFO(d)->penalty_time_tot * 100) /
  11.972                 EDOM_INFO(d)->block_time_tot);
  11.973 -    if (EDOM_INFO(d)->block_tot!=0)
  11.974 +    if ( EDOM_INFO(d)->block_tot != 0 )
  11.975          printf("\n   blks=%u sh=%u (%u%%) (shc=%u (%u%%) shex=%i "\
  11.976                 "shexsl=%i) l=%u (%u%%) avg: b=%"PRIu64" p=%"PRIu64"",
  11.977                 EDOM_INFO(d)->block_tot, EDOM_INFO(d)->short_block_tot,
  11.978 @@ -1271,7 +1441,8 @@ static void sedf_dump_domain(struct vcpu
  11.979      printf("\n");
  11.980  }
  11.981  
  11.982 -/*dumps all domains on hte specified cpu*/
  11.983 +
  11.984 +/* dumps all domains on hte specified cpu */
  11.985  static void sedf_dump_cpu_state(int i)
  11.986  {
  11.987      struct list_head      *list, *queue, *tmp;
  11.988 @@ -1284,7 +1455,8 @@ static void sedf_dump_cpu_state(int i)
  11.989      queue = RUNQ(i);
  11.990      printk("RUNQ rq %lx   n: %lx, p: %lx\n",  (unsigned long)queue,
  11.991             (unsigned long) queue->next, (unsigned long) queue->prev);
  11.992 -    list_for_each_safe ( list, tmp, queue ) {
  11.993 +    list_for_each_safe ( list, tmp, queue )
  11.994 +    {
  11.995          printk("%3d: ",loop++);
  11.996          d_inf = list_entry(list, struct sedf_vcpu_info, list);
  11.997          sedf_dump_domain(d_inf->vcpu);
  11.998 @@ -1293,7 +1465,8 @@ static void sedf_dump_cpu_state(int i)
  11.999      queue = WAITQ(i); loop = 0;
 11.1000      printk("\nWAITQ rq %lx   n: %lx, p: %lx\n",  (unsigned long)queue,
 11.1001             (unsigned long) queue->next, (unsigned long) queue->prev);
 11.1002 -    list_for_each_safe ( list, tmp, queue ) {
 11.1003 +    list_for_each_safe ( list, tmp, queue )
 11.1004 +    {
 11.1005          printk("%3d: ",loop++);
 11.1006          d_inf = list_entry(list, struct sedf_vcpu_info, list);
 11.1007          sedf_dump_domain(d_inf->vcpu);
 11.1008 @@ -1303,7 +1476,8 @@ static void sedf_dump_cpu_state(int i)
 11.1009      printk("\nEXTRAQ (penalty) rq %lx   n: %lx, p: %lx\n",
 11.1010             (unsigned long)queue, (unsigned long) queue->next,
 11.1011             (unsigned long) queue->prev);
 11.1012 -    list_for_each_safe ( list, tmp, queue ) {
 11.1013 +    list_for_each_safe ( list, tmp, queue )
 11.1014 +    {
 11.1015          d_inf = list_entry(list, struct sedf_vcpu_info,
 11.1016                             extralist[EXTRA_PEN_Q]);
 11.1017          printk("%3d: ",loop++);
 11.1018 @@ -1314,7 +1488,8 @@ static void sedf_dump_cpu_state(int i)
 11.1019      printk("\nEXTRAQ (utilization) rq %lx   n: %lx, p: %lx\n",
 11.1020             (unsigned long)queue, (unsigned long) queue->next,
 11.1021             (unsigned long) queue->prev);
 11.1022 -    list_for_each_safe ( list, tmp, queue ) {
 11.1023 +    list_for_each_safe ( list, tmp, queue )
 11.1024 +    {
 11.1025          d_inf = list_entry(list, struct sedf_vcpu_info,
 11.1026                             extralist[EXTRA_UTIL_Q]);
 11.1027          printk("%3d: ",loop++);
 11.1028 @@ -1323,69 +1498,93 @@ static void sedf_dump_cpu_state(int i)
 11.1029   
 11.1030      loop = 0;
 11.1031      printk("\nnot on Q\n");
 11.1032 -    for_each_domain(d)
 11.1033 -        for_each_vcpu(d, ed)
 11.1034 +
 11.1035 +    for_each_domain ( d )
 11.1036      {
 11.1037 -        if (!__task_on_queue(ed) && (ed->processor == i)) {
 11.1038 -            printk("%3d: ",loop++);
 11.1039 -            sedf_dump_domain(ed);
 11.1040 +        for_each_vcpu(d, ed)
 11.1041 +        {
 11.1042 +            if ( !__task_on_queue(ed) && (ed->processor == i) )
 11.1043 +            {
 11.1044 +                printk("%3d: ",loop++);
 11.1045 +                sedf_dump_domain(ed);
 11.1046 +            }
 11.1047          }
 11.1048      }
 11.1049  }
 11.1050 -/*Adjusts periods and slices of the domains accordingly to their weights*/
 11.1051 -static inline int sedf_adjust_weights(struct sched_adjdom_cmd *cmd) {
 11.1052 +
 11.1053 +
 11.1054 +/* Adjusts periods and slices of the domains accordingly to their weights. */
 11.1055 +static int sedf_adjust_weights(struct sched_adjdom_cmd *cmd)
 11.1056 +{
 11.1057      struct vcpu *p;
 11.1058      struct domain      *d;
 11.1059      int                 sumw[NR_CPUS];
 11.1060      s_time_t            sumt[NR_CPUS];
 11.1061      int                 cpu;
 11.1062   
 11.1063 -    for (cpu=0; cpu < NR_CPUS; cpu++) {
 11.1064 +    for ( cpu = 0; cpu < NR_CPUS; cpu++ )
 11.1065 +    {
 11.1066          sumw[cpu] = 0;
 11.1067          sumt[cpu] = 0;
 11.1068      }
 11.1069 -    /*sum up all weights*/
 11.1070 -    for_each_domain(d)
 11.1071 -        for_each_vcpu(d, p) {
 11.1072 -        if (EDOM_INFO(p)->weight)
 11.1073 -            sumw[p->processor] += EDOM_INFO(p)->weight;
 11.1074 -        else {
 11.1075 -            /*don't modify domains who don't have a weight, but sum
 11.1076 -              up the time they need, projected to a WEIGHT_PERIOD,
 11.1077 -              so that this time is not given to the weight-driven
 11.1078 -              domains*/
 11.1079 -            /*check for overflows*/
 11.1080 -            ASSERT((WEIGHT_PERIOD < ULONG_MAX) 
 11.1081 -                   && (EDOM_INFO(p)->slice_orig < ULONG_MAX));
 11.1082 -            sumt[p->processor] += 
 11.1083 -                (WEIGHT_PERIOD * EDOM_INFO(p)->slice_orig) / 
 11.1084 -                EDOM_INFO(p)->period_orig;
 11.1085 +
 11.1086 +    /* sum up all weights */
 11.1087 +    for_each_domain( d )
 11.1088 +    {
 11.1089 +        for_each_vcpu( d, p )
 11.1090 +        {
 11.1091 +            if ( EDOM_INFO(p)->weight )
 11.1092 +            {
 11.1093 +                sumw[p->processor] += EDOM_INFO(p)->weight;
 11.1094 +            }
 11.1095 +            else
 11.1096 +            {
 11.1097 +                /*don't modify domains who don't have a weight, but sum
 11.1098 +                  up the time they need, projected to a WEIGHT_PERIOD,
 11.1099 +                  so that this time is not given to the weight-driven
 11.1100 +                  domains*/
 11.1101 +                /*check for overflows*/
 11.1102 +                ASSERT((WEIGHT_PERIOD < ULONG_MAX) 
 11.1103 +                       && (EDOM_INFO(p)->slice_orig < ULONG_MAX));
 11.1104 +                sumt[p->processor] += 
 11.1105 +                    (WEIGHT_PERIOD * EDOM_INFO(p)->slice_orig) / 
 11.1106 +                    EDOM_INFO(p)->period_orig;
 11.1107 +            }
 11.1108          }
 11.1109      }
 11.1110 -    /*adjust all slices (and periods) to the new weight*/
 11.1111 -    for_each_domain(d) 
 11.1112 -        for_each_vcpu(d, p) {
 11.1113 -        if (EDOM_INFO(p)->weight) {
 11.1114 -            EDOM_INFO(p)->period_orig = 
 11.1115 -                EDOM_INFO(p)->period  = WEIGHT_PERIOD;
 11.1116 -            EDOM_INFO(p)->slice_orig  =
 11.1117 -                EDOM_INFO(p)->slice   = 
 11.1118 -                (EDOM_INFO(p)->weight *
 11.1119 -                 (WEIGHT_PERIOD - WEIGHT_SAFETY - sumt[p->processor])) / 
 11.1120 -                sumw[p->processor];
 11.1121 +
 11.1122 +    /* adjust all slices (and periods) to the new weight */
 11.1123 +    for_each_domain( d )
 11.1124 +    {
 11.1125 +        for_each_vcpu ( d, p )
 11.1126 +        {
 11.1127 +            if ( EDOM_INFO(p)->weight )
 11.1128 +            {
 11.1129 +                EDOM_INFO(p)->period_orig = 
 11.1130 +                    EDOM_INFO(p)->period  = WEIGHT_PERIOD;
 11.1131 +                EDOM_INFO(p)->slice_orig  =
 11.1132 +                    EDOM_INFO(p)->slice   = 
 11.1133 +                    (EDOM_INFO(p)->weight *
 11.1134 +                     (WEIGHT_PERIOD - WEIGHT_SAFETY - sumt[p->processor])) / 
 11.1135 +                    sumw[p->processor];
 11.1136 +            }
 11.1137          }
 11.1138      }
 11.1139 +
 11.1140      return 0;
 11.1141  }
 11.1142  
 11.1143 +
 11.1144  /* set or fetch domain scheduling parameters */
 11.1145 -static int sedf_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd) {
 11.1146 +static int sedf_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd)
 11.1147 +{
 11.1148      struct vcpu *v;
 11.1149  
 11.1150      PRINT(2,"sedf_adjdom was called, domain-id %i new period %"PRIu64" "\
 11.1151            "new slice %"PRIu64"\nlatency %"PRIu64" extra:%s\n",
 11.1152            p->domain_id, cmd->u.sedf.period, cmd->u.sedf.slice,
 11.1153            cmd->u.sedf.latency, (cmd->u.sedf.extratime)?"yes":"no");
 11.1154 +
 11.1155      if ( cmd->direction == SCHED_INFO_PUT )
 11.1156      {
 11.1157          /*check for sane parameters*/
 11.1158 @@ -1458,6 +1657,7 @@ struct scheduler sched_sedf_def = {
 11.1159      .sleep          = sedf_sleep,
 11.1160      .wake           = sedf_wake,
 11.1161      .adjdom         = sedf_adjdom,
 11.1162 +    .set_affinity   = sedf_set_affinity
 11.1163  };
 11.1164  
 11.1165  /*
    12.1 --- a/xen/common/schedule.c	Fri Jan 06 16:24:46 2006 +0100
    12.2 +++ b/xen/common/schedule.c	Fri Jan 06 16:47:25 2006 +0100
    12.3 @@ -202,12 +202,19 @@ void vcpu_wake(struct vcpu *v)
    12.4          SCHED_OP(wake, v);
    12.5          v->wokenup = NOW();
    12.6      }
    12.7 -    clear_bit(_VCPUF_cpu_migrated, &v->vcpu_flags);
    12.8      spin_unlock_irqrestore(&schedule_data[v->processor].schedule_lock, flags);
    12.9  
   12.10      TRACE_2D(TRC_SCHED_WAKE, v->domain->domain_id, v->vcpu_id);
   12.11  }
   12.12  
   12.13 +int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity)
   12.14 +{
   12.15 +    if ( cpus_empty(*affinity) )
   12.16 +        return -EINVAL;
   12.17 +
   12.18 +    return SCHED_OP(set_affinity, v, affinity);
   12.19 +}
   12.20 +
   12.21  /* Block the currently-executing domain until a pertinent event occurs. */
   12.22  long do_block(void)
   12.23  {
    13.1 --- a/xen/include/asm-x86/mm.h	Fri Jan 06 16:24:46 2006 +0100
    13.2 +++ b/xen/include/asm-x86/mm.h	Fri Jan 06 16:47:25 2006 +0100
    13.3 @@ -336,11 +336,13 @@ int  ptwr_do_page_fault(struct domain *,
    13.4  int  revalidate_l1(struct domain *, l1_pgentry_t *, l1_pgentry_t *);
    13.5  
    13.6  void cleanup_writable_pagetable(struct domain *d);
    13.7 -#define sync_pagetable_state(d)                 \
    13.8 -    do {                                        \
    13.9 -        LOCK_BIGLOCK(d);                        \
   13.10 -        cleanup_writable_pagetable(d);          \
   13.11 -        UNLOCK_BIGLOCK(d);                      \
   13.12 +#define sync_pagetable_state(d)                                 \
   13.13 +    do {                                                        \
   13.14 +        LOCK_BIGLOCK(d);                                        \
   13.15 +        /* Avoid racing with ptwr_destroy(). */                 \
   13.16 +        if ( !test_bit(_DOMF_dying, &(d)->domain_flags) )       \
   13.17 +            cleanup_writable_pagetable(d);                      \
   13.18 +        UNLOCK_BIGLOCK(d);                                      \
   13.19      } while ( 0 )
   13.20  
   13.21  int audit_adjust_pgtables(struct domain *d, int dir, int noisy);
    14.1 --- a/xen/include/asm-x86/shadow.h	Fri Jan 06 16:24:46 2006 +0100
    14.2 +++ b/xen/include/asm-x86/shadow.h	Fri Jan 06 16:47:25 2006 +0100
    14.3 @@ -341,10 +341,10 @@ extern int shadow_status_noswap;
    14.4  #if SHADOW_VERBOSE_DEBUG
    14.5  #define SH_LOG(_f, _a...)                                               \
    14.6      printk("DOM%uP%u: SH_LOG(%d): " _f "\n",                            \
    14.7 -       current->domain->domain_id , current->processor, __LINE__ , ## _a )
    14.8 +       current->domain->domain_id , smp_processor_id(), __LINE__ , ## _a )
    14.9  #define SH_VLOG(_f, _a...)                                              \
   14.10      printk("DOM%uP%u: SH_VLOG(%d): " _f "\n",                           \
   14.11 -           current->domain->domain_id, current->processor, __LINE__ , ## _a )
   14.12 +           current->domain->domain_id, smp_processor_id(), __LINE__ , ## _a )
   14.13  #else
   14.14  #define SH_LOG(_f, _a...) ((void)0)
   14.15  #define SH_VLOG(_f, _a...) ((void)0)
   14.16 @@ -353,7 +353,7 @@ extern int shadow_status_noswap;
   14.17  #if SHADOW_VVERBOSE_DEBUG
   14.18  #define SH_VVLOG(_f, _a...)                                             \
   14.19      printk("DOM%uP%u: SH_VVLOG(%d): " _f "\n",                          \
   14.20 -           current->domain->domain_id, current->processor, __LINE__ , ## _a )
   14.21 +           current->domain->domain_id, smp_processor_id(), __LINE__ , ## _a )
   14.22  #else
   14.23  #define SH_VVLOG(_f, _a...) ((void)0)
   14.24  #endif
   14.25 @@ -361,7 +361,7 @@ extern int shadow_status_noswap;
   14.26  #if SHADOW_VVVERBOSE_DEBUG
   14.27  #define SH_VVVLOG(_f, _a...)                                            \
   14.28      printk("DOM%uP%u: SH_VVVLOG(%d): " _f "\n",                         \
   14.29 -           current->domain->domain_id, current->processor, __LINE__ , ## _a )
   14.30 +           current->domain->domain_id, smp_processor_id(), __LINE__ , ## _a )
   14.31  #else
   14.32  #define SH_VVVLOG(_f, _a...) ((void)0)
   14.33  #endif
   14.34 @@ -369,7 +369,7 @@ extern int shadow_status_noswap;
   14.35  #if FULLSHADOW_DEBUG
   14.36  #define FSH_LOG(_f, _a...)                                              \
   14.37      printk("DOM%uP%u: FSH_LOG(%d): " _f "\n",                           \
   14.38 -           current->domain->domain_id, current->processor, __LINE__ , ## _a )
   14.39 +           current->domain->domain_id, smp_processor_id(), __LINE__ , ## _a )
   14.40  #else
   14.41  #define FSH_LOG(_f, _a...) ((void)0)
   14.42  #endif
    15.1 --- a/xen/include/asm-x86/vmx.h	Fri Jan 06 16:24:46 2006 +0100
    15.2 +++ b/xen/include/asm-x86/vmx.h	Fri Jan 06 16:47:25 2006 +0100
    15.3 @@ -38,7 +38,6 @@ extern void pic_irq_request(int *interru
    15.4  
    15.5  extern void arch_vmx_do_launch(struct vcpu *);
    15.6  extern void arch_vmx_do_resume(struct vcpu *);
    15.7 -extern void arch_vmx_do_relaunch(struct vcpu *);
    15.8  
    15.9  extern unsigned int cpu_rev;
   15.10  
    16.1 --- a/xen/include/asm-x86/vmx_vmcs.h	Fri Jan 06 16:24:46 2006 +0100
    16.2 +++ b/xen/include/asm-x86/vmx_vmcs.h	Fri Jan 06 16:47:25 2006 +0100
    16.3 @@ -86,7 +86,8 @@ struct mmio_op {
    16.4  #define PC_DEBUG_PORT   0x80
    16.5  
    16.6  struct arch_vmx_struct {
    16.7 -    struct vmcs_struct      *vmcs;  /* VMCS pointer in virtual */
    16.8 +    struct vmcs_struct      *vmcs;  /* VMCS pointer in virtual. */
    16.9 +    unsigned int            launch_cpu; /* VMCS is valid on this CPU. */
   16.10      unsigned long           flags;  /* VMCS flags */
   16.11      unsigned long           cpu_cr0; /* copy of guest CR0 */
   16.12      unsigned long           cpu_shadow_cr0; /* copy of guest read shadow CR0 */
    17.1 --- a/xen/include/xen/domain.h	Fri Jan 06 16:24:46 2006 +0100
    17.2 +++ b/xen/include/xen/domain.h	Fri Jan 06 16:47:25 2006 +0100
    17.3 @@ -18,8 +18,6 @@ extern int arch_do_createdomain(struct v
    17.4  extern int arch_set_info_guest(
    17.5      struct vcpu *v, struct vcpu_guest_context *c);
    17.6  
    17.7 -extern void vcpu_migrate_cpu(struct vcpu *v, int newcpu);
    17.8 -
    17.9  extern void free_perdomain_pt(struct domain *d);
   17.10  
   17.11  extern void domain_relinquish_resources(struct domain *d);
    18.1 --- a/xen/include/xen/sched-if.h	Fri Jan 06 16:24:46 2006 +0100
    18.2 +++ b/xen/include/xen/sched-if.h	Fri Jan 06 16:47:25 2006 +0100
    18.3 @@ -39,6 +39,7 @@ struct scheduler {
    18.4      void         (*rem_task)       (struct vcpu *);
    18.5      void         (*sleep)          (struct vcpu *);
    18.6      void         (*wake)           (struct vcpu *);
    18.7 +    int          (*set_affinity)   (struct vcpu *, cpumask_t *);
    18.8      struct task_slice (*do_schedule) (s_time_t);
    18.9      int          (*control)        (struct sched_ctl_cmd *);
   18.10      int          (*adjdom)         (struct domain *,
    19.1 --- a/xen/include/xen/sched.h	Fri Jan 06 16:24:46 2006 +0100
    19.2 +++ b/xen/include/xen/sched.h	Fri Jan 06 16:47:25 2006 +0100
    19.3 @@ -362,14 +362,11 @@ extern struct domain *domain_list;
    19.4   /* Currently running on a CPU? */
    19.5  #define _VCPUF_running         3
    19.6  #define VCPUF_running          (1UL<<_VCPUF_running)
    19.7 - /* Domain migrated between CPUs. */
    19.8 -#define _VCPUF_cpu_migrated    4
    19.9 -#define VCPUF_cpu_migrated     (1UL<<_VCPUF_cpu_migrated)
   19.10   /* Initialization completed. */
   19.11 -#define _VCPUF_initialised     5
   19.12 +#define _VCPUF_initialised     4
   19.13  #define VCPUF_initialised      (1UL<<_VCPUF_initialised)
   19.14   /* VCPU is not-runnable */
   19.15 -#define _VCPUF_down            6
   19.16 +#define _VCPUF_down            5
   19.17  #define VCPUF_down             (1UL<<_VCPUF_down)
   19.18  
   19.19  /*
   19.20 @@ -384,17 +381,14 @@ extern struct domain *domain_list;
   19.21   /* Guest shut itself down for some reason. */
   19.22  #define _DOMF_shutdown         2
   19.23  #define DOMF_shutdown          (1UL<<_DOMF_shutdown)
   19.24 - /* Guest is in process of shutting itself down (becomes DOMF_shutdown). */
   19.25 -#define _DOMF_shuttingdown     3
   19.26 -#define DOMF_shuttingdown      (1UL<<_DOMF_shuttingdown)
   19.27   /* Death rattle. */
   19.28 -#define _DOMF_dying            4
   19.29 +#define _DOMF_dying            3
   19.30  #define DOMF_dying             (1UL<<_DOMF_dying)
   19.31   /* Domain is paused by controller software. */
   19.32 -#define _DOMF_ctrl_pause       5
   19.33 +#define _DOMF_ctrl_pause       4
   19.34  #define DOMF_ctrl_pause        (1UL<<_DOMF_ctrl_pause)
   19.35   /* Domain is being debugged by controller software. */
   19.36 -#define _DOMF_debugging        6
   19.37 +#define _DOMF_debugging        5
   19.38  #define DOMF_debugging         (1UL<<_DOMF_debugging)
   19.39  
   19.40  
   19.41 @@ -402,8 +396,7 @@ static inline int domain_runnable(struct
   19.42  {
   19.43      return ( (atomic_read(&v->pausecnt) == 0) &&
   19.44               !(v->vcpu_flags & (VCPUF_blocked|VCPUF_down)) &&
   19.45 -             !(v->domain->domain_flags &
   19.46 -               (DOMF_shutdown|DOMF_shuttingdown|DOMF_ctrl_pause)) );
   19.47 +             !(v->domain->domain_flags & (DOMF_shutdown|DOMF_ctrl_pause)) );
   19.48  }
   19.49  
   19.50  void vcpu_pause(struct vcpu *v);
   19.51 @@ -414,6 +407,8 @@ void domain_pause_by_systemcontroller(st
   19.52  void domain_unpause_by_systemcontroller(struct domain *d);
   19.53  void cpu_init(void);
   19.54  
   19.55 +int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity);
   19.56 +
   19.57  static inline void vcpu_unblock(struct vcpu *v)
   19.58  {
   19.59      if ( test_and_clear_bit(_VCPUF_blocked, &v->vcpu_flags) )