direct-io.hg
changeset 8503:3eeabf448f91
Clean up domain shutdown and modification of vcpu
processor affinity.
Signed-off-by: Keir Fraser <keir@xensource.com>
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) )