[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN] Re-jig VCPU initialisation -- VMX init requires generic VCPU
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID e793dad2114d678b9ce8ebd36145f205943bf1cb # Parent 31985f348d2e388d973500816899fde97c4dbeda [XEN] Re-jig VCPU initialisation -- VMX init requires generic VCPU fields to already be allocated. This has led to a general cleanup of domain and vcpu initialisation and destruction. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/ia64/xen/domain.c | 103 ++++++++++++++------------- xen/arch/powerpc/domain.c | 23 +++--- xen/arch/x86/domain.c | 44 ++++++----- xen/arch/x86/hvm/vmx/vmcs.c | 163 ++++++++++++-------------------------------- xen/arch/x86/hvm/vmx/vmx.c | 12 --- xen/common/domain.c | 30 +++++--- xen/common/sched_credit.c | 81 ++++++++++----------- xen/common/sched_sedf.c | 35 +++++---- xen/common/schedule.c | 21 +++-- xen/include/xen/domain.h | 14 +++ xen/include/xen/sched-if.h | 5 + xen/include/xen/sched.h | 4 - 12 files changed, 253 insertions(+), 282 deletions(-) diff -r 31985f348d2e -r e793dad2114d xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Mon Nov 06 09:46:13 2006 +0000 +++ b/xen/arch/ia64/xen/domain.c Mon Nov 06 11:03:04 2006 +0000 @@ -275,40 +275,61 @@ void hlt_timer_fn(void *data) vcpu_unblock(v); } -struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) +void relinquish_vcpu_resources(struct vcpu *v) +{ + if (HAS_PERVCPU_VHPT(v->domain)) + pervcpu_vhpt_free(v); + if (v->arch.privregs != NULL) { + free_xenheap_pages(v->arch.privregs, + get_order_from_shift(XMAPPEDREGS_SHIFT)); + v->arch.privregs = NULL; + } + kill_timer(&v->arch.hlt_timer); +} + +struct vcpu *alloc_vcpu_struct(void) { struct vcpu *v; struct thread_info *ti; - - /* Still keep idle vcpu0 static allocated at compilation, due - * to some code from Linux still requires it in early phase. + static int first_allocation = 1; + + if (first_allocation) { + first_allocation = 0; + /* Still keep idle vcpu0 static allocated at compilation, due + * to some code from Linux still requires it in early phase. + */ + return idle_vcpu[0]; + } + + if ((v = alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER)) == NULL) + return NULL; + memset(v, 0, sizeof(*v)); + + ti = alloc_thread_info(v); + /* Clear thread_info to clear some important fields, like + * preempt_count */ - if (is_idle_domain(d) && !vcpu_id) - v = idle_vcpu[0]; - else { - if ((v = alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER)) == NULL) - return NULL; - memset(v, 0, sizeof(*v)); - - ti = alloc_thread_info(v); - /* Clear thread_info to clear some important fields, like - * preempt_count - */ - memset(ti, 0, sizeof(struct thread_info)); - init_switch_stack(v); - } + memset(ti, 0, sizeof(struct thread_info)); + init_switch_stack(v); + + return v; +} + +void free_vcpu_struct(struct vcpu *v) +{ + free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER); +} + +int vcpu_initialise(struct vcpu *v) +{ + struct domain *d = v->domain; + int rc, order, i; if (!is_idle_domain(d)) { if (!d->arch.is_vti) { - int order; - int i; - // vti domain has its own vhpt policy. - if (HAS_PERVCPU_VHPT(d)) { - if (pervcpu_vhpt_alloc(v) < 0) { - free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER); - return NULL; - } - } + if (HAS_PERVCPU_VHPT(d)) + if ((rc = pervcpu_vhpt_alloc(v)) != 0) + return rc; /* Create privregs page only if not VTi. */ order = get_order_from_shift(XMAPPEDREGS_SHIFT); @@ -344,34 +365,20 @@ struct vcpu *alloc_vcpu_struct(struct do v->arch.breakimm = d->arch.breakimm; v->arch.last_processor = INVALID_PROCESSOR; } - if (!VMX_DOMAIN(v)){ + + if (!VMX_DOMAIN(v)) init_timer(&v->arch.hlt_timer, hlt_timer_fn, v, first_cpu(cpu_online_map)); - } - - return v; -} - -void relinquish_vcpu_resources(struct vcpu *v) -{ - if (HAS_PERVCPU_VHPT(v->domain)) - pervcpu_vhpt_free(v); - if (v->arch.privregs != NULL) { - free_xenheap_pages(v->arch.privregs, - get_order_from_shift(XMAPPEDREGS_SHIFT)); - v->arch.privregs = NULL; - } - kill_timer(&v->arch.hlt_timer); -} - -void free_vcpu_struct(struct vcpu *v) + + return 0; +} + +void vcpu_destroy(struct vcpu *v) { if (v->domain->arch.is_vti) vmx_relinquish_vcpu_resources(v); else relinquish_vcpu_resources(v); - - free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER); } static void init_switch_stack(struct vcpu *v) diff -r 31985f348d2e -r e793dad2114d xen/arch/powerpc/domain.c --- a/xen/arch/powerpc/domain.c Mon Nov 06 09:46:13 2006 +0000 +++ b/xen/arch/powerpc/domain.c Mon Nov 06 11:03:04 2006 +0000 @@ -109,25 +109,26 @@ void machine_restart(char * __unused) while(1); } -struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) +struct vcpu *alloc_vcpu_struct(void) { struct vcpu *v; - - if ( (v = xmalloc(struct vcpu)) == NULL ) - return NULL; - - memset(v, 0, sizeof(*v)); - v->vcpu_id = vcpu_id; - + if ( (v = xmalloc(struct vcpu)) != NULL ) + memset(v, 0, sizeof(*v)); return v; } void free_vcpu_struct(struct vcpu *v) { - BUG_ON(v->next_in_list != NULL); - if ( v->vcpu_id != 0 ) - v->domain->vcpu[v->vcpu_id - 1]->next_in_list = NULL; xfree(v); +} + +int vcpu_initialise(struct vcpu *v) +{ + return 0; +} + +void vcpu_destroy(struct vcpu *v) +{ } int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_t *c) diff -r 31985f348d2e -r e793dad2114d xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Mon Nov 06 09:46:13 2006 +0000 +++ b/xen/arch/x86/domain.c Mon Nov 06 11:03:04 2006 +0000 @@ -114,27 +114,30 @@ void dump_pageframe_info(struct domain * } } -struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) +struct vcpu *alloc_vcpu_struct(void) { struct vcpu *v; - - if ( (v = xmalloc(struct vcpu)) == NULL ) - return NULL; - - memset(v, 0, sizeof(*v)); - - v->vcpu_id = vcpu_id; - v->domain = d; + if ( (v = xmalloc(struct vcpu)) != NULL ) + memset(v, 0, sizeof(*v)); + return v; +} + +void free_vcpu_struct(struct vcpu *v) +{ + xfree(v); +} + +int vcpu_initialise(struct vcpu *v) +{ + struct domain *d = v->domain; + int rc; v->arch.flags = TF_kernel_mode; if ( is_hvm_domain(d) ) { - if ( hvm_vcpu_initialise(v) != 0 ) - { - xfree(v); - return NULL; - } + if ( (rc = hvm_vcpu_initialise(v)) != 0 ) + return rc; } else { @@ -150,16 +153,15 @@ struct vcpu *alloc_vcpu_struct(struct do } v->arch.perdomain_ptes = - d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT); + d->arch.mm_perdomain_pt + (v->vcpu_id << GDT_LDT_VCPU_SHIFT); pae_l3_cache_init(&v->arch.pae_l3_cache); - return v; -} - -void free_vcpu_struct(struct vcpu *v) -{ - xfree(v); + return 0; +} + +void vcpu_destroy(struct vcpu *v) +{ } int arch_domain_create(struct domain *d) diff -r 31985f348d2e -r e793dad2114d xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Mon Nov 06 09:46:13 2006 +0000 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Mon Nov 06 11:03:04 2006 +0000 @@ -193,11 +193,9 @@ void vmx_vmcs_enter(struct vcpu *v) { /* * NB. We must *always* run an HVM VCPU on its own VMCS, except for - * vmx_vmcs_enter/exit critical regions. This leads to some XXX TODOs XXX: - * 1. Move construct_vmcs() much earlier, to domain creation or - * context initialisation. - * 2. VMPTRLD as soon as we context-switch to a HVM VCPU. - * 3. VMCS destruction needs to happen later (from domain_destroy()). + * vmx_vmcs_enter/exit critical regions. This leads to some TODOs: + * 1. VMPTRLD as soon as we context-switch to a HVM VCPU. + * 2. VMCS destruction needs to happen later (from domain_destroy()). * We can relax this a bit if a paused VCPU always commits its * architectural state to a software structure. */ @@ -233,17 +231,6 @@ void vmx_free_host_vmcs(struct vmcs_stru void vmx_free_host_vmcs(struct vmcs_struct *vmcs) { vmx_free_vmcs(vmcs); -} - -static inline int construct_vmcs_controls(struct arch_vmx_struct *arch_vmx) -{ - int error = 0; - - error |= __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control); - error |= __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control); - error |= __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control); - - return error; } #define GUEST_LAUNCH_DS 0x08 @@ -366,17 +353,40 @@ static void vmx_do_launch(struct vcpu *v v->arch.schedule_tail = arch_vmx_do_resume; } -/* - * Initially set the same environement as host. - */ -static inline int construct_init_vmcs_guest(cpu_user_regs_t *regs) +static int construct_vmcs(struct vcpu *v, cpu_user_regs_t *regs) { int error = 0; + unsigned long tmp, eflags; union vmcs_arbytes arbytes; - unsigned long dr7; - unsigned long eflags; - - /* MSR */ + + /* VMCS controls. */ + error |= __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control); + error |= __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control); + error |= __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control); + + /* Host data selectors. */ + error |= __vmwrite(HOST_SS_SELECTOR, __HYPERVISOR_DS); + error |= __vmwrite(HOST_DS_SELECTOR, __HYPERVISOR_DS); + error |= __vmwrite(HOST_ES_SELECTOR, __HYPERVISOR_DS); +#if defined(__i386__) + error |= __vmwrite(HOST_FS_SELECTOR, __HYPERVISOR_DS); + error |= __vmwrite(HOST_GS_SELECTOR, __HYPERVISOR_DS); + error |= __vmwrite(HOST_FS_BASE, 0); + error |= __vmwrite(HOST_GS_BASE, 0); +#elif defined(__x86_64__) + rdmsrl(MSR_FS_BASE, tmp); error |= __vmwrite(HOST_FS_BASE, tmp); + rdmsrl(MSR_GS_BASE, tmp); error |= __vmwrite(HOST_GS_BASE, tmp); +#endif + + /* Host control registers. */ + error |= __vmwrite(HOST_CR0, read_cr0()); + error |= __vmwrite(HOST_CR4, read_cr4()); + + /* Host CS:RIP. */ + error |= __vmwrite(HOST_CS_SELECTOR, __HYPERVISOR_CS); + error |= __vmwrite(HOST_RIP, (unsigned long)vmx_asm_vmexit_handler); + + /* MSR intercepts. */ error |= __vmwrite(VM_EXIT_MSR_LOAD_ADDR, 0); error |= __vmwrite(VM_EXIT_MSR_STORE_ADDR, 0); error |= __vmwrite(VM_EXIT_MSR_STORE_COUNT, 0); @@ -395,7 +405,7 @@ static inline int construct_init_vmcs_gu error |= __vmwrite(GUEST_ACTIVITY_STATE, 0); - /* Guest Selectors */ + /* Guest selectors. */ error |= __vmwrite(GUEST_ES_SELECTOR, GUEST_LAUNCH_DS); error |= __vmwrite(GUEST_SS_SELECTOR, GUEST_LAUNCH_DS); error |= __vmwrite(GUEST_DS_SELECTOR, GUEST_LAUNCH_DS); @@ -403,7 +413,7 @@ static inline int construct_init_vmcs_gu error |= __vmwrite(GUEST_GS_SELECTOR, GUEST_LAUNCH_DS); error |= __vmwrite(GUEST_CS_SELECTOR, GUEST_LAUNCH_CS); - /* Guest segment bases */ + /* Guest segment bases. */ error |= __vmwrite(GUEST_ES_BASE, 0); error |= __vmwrite(GUEST_SS_BASE, 0); error |= __vmwrite(GUEST_DS_BASE, 0); @@ -411,7 +421,7 @@ static inline int construct_init_vmcs_gu error |= __vmwrite(GUEST_GS_BASE, 0); error |= __vmwrite(GUEST_CS_BASE, 0); - /* Guest segment Limits */ + /* Guest segment limits. */ error |= __vmwrite(GUEST_ES_LIMIT, GUEST_SEGMENT_LIMIT); error |= __vmwrite(GUEST_SS_LIMIT, GUEST_SEGMENT_LIMIT); error |= __vmwrite(GUEST_DS_LIMIT, GUEST_SEGMENT_LIMIT); @@ -419,7 +429,7 @@ static inline int construct_init_vmcs_gu error |= __vmwrite(GUEST_GS_LIMIT, GUEST_SEGMENT_LIMIT); error |= __vmwrite(GUEST_CS_LIMIT, GUEST_SEGMENT_LIMIT); - /* Guest segment AR bytes */ + /* Guest segment AR bytes. */ arbytes.bytes = 0; arbytes.fields.seg_type = 0x3; /* type = 3 */ arbytes.fields.s = 1; /* code or data, i.e. not system */ @@ -428,131 +438,54 @@ static inline int construct_init_vmcs_gu arbytes.fields.default_ops_size = 1; /* 32-bit */ arbytes.fields.g = 1; arbytes.fields.null_bit = 0; /* not null */ - error |= __vmwrite(GUEST_ES_AR_BYTES, arbytes.bytes); error |= __vmwrite(GUEST_SS_AR_BYTES, arbytes.bytes); error |= __vmwrite(GUEST_DS_AR_BYTES, arbytes.bytes); error |= __vmwrite(GUEST_FS_AR_BYTES, arbytes.bytes); error |= __vmwrite(GUEST_GS_AR_BYTES, arbytes.bytes); - arbytes.fields.seg_type = 0xb; /* type = 0xb */ error |= __vmwrite(GUEST_CS_AR_BYTES, arbytes.bytes); - /* Guest GDT */ + /* Guest GDT. */ error |= __vmwrite(GUEST_GDTR_BASE, 0); error |= __vmwrite(GUEST_GDTR_LIMIT, 0); - /* Guest IDT */ + /* Guest IDT. */ error |= __vmwrite(GUEST_IDTR_BASE, 0); error |= __vmwrite(GUEST_IDTR_LIMIT, 0); - /* Guest LDT & TSS */ + /* Guest LDT and TSS. */ arbytes.fields.s = 0; /* not code or data segement */ arbytes.fields.seg_type = 0x2; /* LTD */ arbytes.fields.default_ops_size = 0; /* 16-bit */ arbytes.fields.g = 0; error |= __vmwrite(GUEST_LDTR_AR_BYTES, arbytes.bytes); - arbytes.fields.seg_type = 0xb; /* 32-bit TSS (busy) */ error |= __vmwrite(GUEST_TR_AR_BYTES, arbytes.bytes); - /* CR3 is set in vmx_final_setup_guest */ error |= __vmwrite(GUEST_RSP, 0); error |= __vmwrite(GUEST_RIP, regs->eip); - /* Guest EFLAGS */ + /* Guest EFLAGS. */ eflags = regs->eflags & ~HVM_EFLAGS_RESERVED_0; /* clear 0s */ eflags |= HVM_EFLAGS_RESERVED_1; /* set 1s */ error |= __vmwrite(GUEST_RFLAGS, eflags); error |= __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0); - __asm__ __volatile__ ("mov %%dr7, %0\n" : "=r" (dr7)); - error |= __vmwrite(GUEST_DR7, dr7); + __asm__ __volatile__ ("mov %%dr7, %0\n" : "=r" (tmp)); + error |= __vmwrite(GUEST_DR7, tmp); error |= __vmwrite(VMCS_LINK_POINTER, ~0UL); #if defined(__i386__) error |= __vmwrite(VMCS_LINK_POINTER_HIGH, ~0UL); #endif - return error; -} - -static inline int construct_vmcs_host(void) -{ - int error = 0; -#ifdef __x86_64__ - unsigned long fs_base; - unsigned long gs_base; -#endif - unsigned long crn; - - /* Host Selectors */ - error |= __vmwrite(HOST_ES_SELECTOR, __HYPERVISOR_DS); - error |= __vmwrite(HOST_SS_SELECTOR, __HYPERVISOR_DS); - error |= __vmwrite(HOST_DS_SELECTOR, __HYPERVISOR_DS); -#if defined(__i386__) - error |= __vmwrite(HOST_FS_SELECTOR, __HYPERVISOR_DS); - error |= __vmwrite(HOST_GS_SELECTOR, __HYPERVISOR_DS); - error |= __vmwrite(HOST_FS_BASE, 0); - error |= __vmwrite(HOST_GS_BASE, 0); - -#else - rdmsrl(MSR_FS_BASE, fs_base); - rdmsrl(MSR_GS_BASE, gs_base); - error |= __vmwrite(HOST_FS_BASE, fs_base); - error |= __vmwrite(HOST_GS_BASE, gs_base); - -#endif - error |= __vmwrite(HOST_CS_SELECTOR, __HYPERVISOR_CS); - - __asm__ __volatile__ ("mov %%cr0,%0" : "=r" (crn) : ); - error |= __vmwrite(HOST_CR0, crn); /* same CR0 */ - - /* CR3 is set in vmx_final_setup_hostos */ - __asm__ __volatile__ ("mov %%cr4,%0" : "=r" (crn) : ); - error |= __vmwrite(HOST_CR4, crn); - - error |= __vmwrite(HOST_RIP, (unsigned long) vmx_asm_vmexit_handler); - - return error; -} - -/* - * the working VMCS pointer has been set properly - * just before entering this function. - */ -static int construct_vmcs(struct vcpu *v, - cpu_user_regs_t *regs) -{ - struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx; - int error; - - if ( (error = construct_vmcs_controls(arch_vmx)) ) { - printk("construct_vmcs: construct_vmcs_controls failed.\n"); - return error; - } - - /* host selectors */ - if ( (error = construct_vmcs_host()) ) { - printk("construct_vmcs: construct_vmcs_host failed.\n"); - return error; - } - - /* guest selectors */ - if ( (error = construct_init_vmcs_guest(regs)) ) { - printk("construct_vmcs: construct_vmcs_guest failed.\n"); - return error; - } - - if ( (error = __vmwrite(EXCEPTION_BITMAP, - MONITOR_DEFAULT_EXCEPTION_BITMAP)) ) { - printk("construct_vmcs: setting exception bitmap failed.\n"); - return error; - } + error |= __vmwrite(EXCEPTION_BITMAP, + MONITOR_DEFAULT_EXCEPTION_BITMAP); if ( regs->eflags & EF_TF ) - error = __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB); + error |= __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB); else - error = __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB); + error |= __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB); return error; } diff -r 31985f348d2e -r e793dad2114d xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Mon Nov 06 09:46:13 2006 +0000 +++ b/xen/arch/x86/hvm/vmx/vmx.c Mon Nov 06 11:03:04 2006 +0000 @@ -566,8 +566,6 @@ static unsigned long vmx_get_ctrl_reg(st return 0; /* dummy */ } - - /* Make sure that xen intercepts any FP accesses from current */ static void vmx_stts(struct vcpu *v) { @@ -591,19 +589,15 @@ static void vmx_stts(struct vcpu *v) } } - static void vmx_set_tsc_offset(struct vcpu *v, u64 offset) { - /* VMX depends on operating on the current vcpu */ - ASSERT(v == current); - + vmx_vmcs_enter(v); __vmwrite(TSC_OFFSET, offset); #if defined (__i386__) __vmwrite(TSC_OFFSET_HIGH, offset >> 32); #endif -} - - + vmx_vmcs_exit(v); +} /* SMP VMX guest support */ static void vmx_init_ap_context(struct vcpu_guest_context *ctxt, diff -r 31985f348d2e -r e793dad2114d xen/common/domain.c --- a/xen/common/domain.c Mon Nov 06 09:46:13 2006 +0000 +++ b/xen/common/domain.c Mon Nov 06 11:03:04 2006 +0000 @@ -64,12 +64,16 @@ void free_domain(struct domain *d) struct vcpu *v; int i; + for ( i = MAX_VIRT_CPUS-1; i >= 0; i-- ) + { + if ( (v = d->vcpu[i]) == NULL ) + continue; + vcpu_destroy(v); + sched_destroy_vcpu(v); + free_vcpu_struct(v); + } + sched_destroy_domain(d); - - for ( i = MAX_VIRT_CPUS-1; i >= 0; i-- ) - if ( (v = d->vcpu[i]) != NULL ) - free_vcpu_struct(v); - xfree(d); } @@ -80,7 +84,7 @@ struct vcpu *alloc_vcpu( BUG_ON(d->vcpu[vcpu_id] != NULL); - if ( (v = alloc_vcpu_struct(d, vcpu_id)) == NULL ) + if ( (v = alloc_vcpu_struct()) == NULL ) return NULL; v->domain = d; @@ -94,8 +98,15 @@ struct vcpu *alloc_vcpu( if ( (vcpu_id != 0) && !is_idle_domain(d) ) set_bit(_VCPUF_down, &v->vcpu_flags); - if ( sched_init_vcpu(v, cpu_id) < 0 ) - { + if ( sched_init_vcpu(v, cpu_id) != 0 ) + { + free_vcpu_struct(v); + return NULL; + } + + if ( vcpu_initialise(v) != 0 ) + { + sched_destroy_vcpu(v); free_vcpu_struct(v); return NULL; } @@ -151,6 +162,9 @@ struct domain *domain_create(domid_t dom d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex); d->irq_caps = rangeset_new(d, "Interrupts", 0); if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) ) + goto fail4; + + if ( sched_init_domain(d) != 0 ) goto fail4; if ( !is_idle_domain(d) ) diff -r 31985f348d2e -r e793dad2114d xen/common/sched_credit.c --- a/xen/common/sched_credit.c Mon Nov 06 09:46:13 2006 +0000 +++ b/xen/common/sched_credit.c Mon Nov 06 11:03:04 2006 +0000 @@ -115,8 +115,10 @@ _MACRO(steal_peer_idle) \ _MACRO(steal_peer_running) \ _MACRO(steal_peer_pinned) \ + _MACRO(dom_init) \ + _MACRO(dom_destroy) \ _MACRO(vcpu_init) \ - _MACRO(dom_destroy) + _MACRO(vcpu_destroy) #ifndef NDEBUG #define CSCHED_STATS_EXPAND_CHECKS(_MACRO) \ @@ -454,43 +456,14 @@ csched_vcpu_init(struct vcpu *vc) csched_vcpu_init(struct vcpu *vc) { struct domain * const dom = vc->domain; - struct csched_dom *sdom; + struct csched_dom *sdom = CSCHED_DOM(dom); struct csched_vcpu *svc; - int16_t pri; CSCHED_STAT_CRANK(vcpu_init); - - /* Allocate, if appropriate, per-domain info */ - if ( is_idle_vcpu(vc) ) - { - sdom = NULL; - pri = CSCHED_PRI_IDLE; - } - else if ( CSCHED_DOM(dom) ) - { - sdom = CSCHED_DOM(dom); - pri = CSCHED_PRI_TS_UNDER; - } - else - { - sdom = xmalloc(struct csched_dom); - if ( !sdom ) - return -1; - - /* Initialize credit and weight */ - INIT_LIST_HEAD(&sdom->active_vcpu); - sdom->active_vcpu_count = 0; - INIT_LIST_HEAD(&sdom->active_sdom_elem); - sdom->dom = dom; - sdom->weight = CSCHED_DEFAULT_WEIGHT; - sdom->cap = 0U; - dom->sched_priv = sdom; - pri = CSCHED_PRI_TS_UNDER; - } /* Allocate per-VCPU info */ svc = xmalloc(struct csched_vcpu); - if ( !svc ) + if ( svc == NULL ) return -1; INIT_LIST_HEAD(&svc->runq_elem); @@ -498,7 +471,7 @@ csched_vcpu_init(struct vcpu *vc) svc->sdom = sdom; svc->vcpu = vc; atomic_set(&svc->credit, 0); - svc->pri = pri; + svc->pri = is_idle_domain(dom) ? CSCHED_PRI_IDLE : CSCHED_PRI_TS_UNDER; memset(&svc->stats, 0, sizeof(svc->stats)); vc->sched_priv = svc; @@ -521,11 +494,13 @@ csched_vcpu_init(struct vcpu *vc) } static void -csched_vcpu_free(struct vcpu *vc) +csched_vcpu_destroy(struct vcpu *vc) { struct csched_vcpu * const svc = CSCHED_VCPU(vc); struct csched_dom * const sdom = svc->sdom; unsigned long flags; + + CSCHED_STAT_CRANK(vcpu_destroy); BUG_ON( sdom == NULL ); BUG_ON( !list_empty(&svc->runq_elem) ); @@ -641,19 +616,38 @@ csched_dom_cntl( return 0; } +static int +csched_dom_init(struct domain *dom) +{ + struct csched_dom *sdom; + + CSCHED_STAT_CRANK(dom_init); + + if ( is_idle_domain(dom) ) + return 0; + + sdom = xmalloc(struct csched_dom); + if ( sdom == NULL ) + return -ENOMEM; + + /* Initialize credit and weight */ + INIT_LIST_HEAD(&sdom->active_vcpu); + sdom->active_vcpu_count = 0; + INIT_LIST_HEAD(&sdom->active_sdom_elem); + sdom->dom = dom; + sdom->weight = CSCHED_DEFAULT_WEIGHT; + sdom->cap = 0U; + dom->sched_priv = sdom; + + return 0; +} + static void csched_dom_destroy(struct domain *dom) { struct csched_dom * const sdom = CSCHED_DOM(dom); - int i; CSCHED_STAT_CRANK(dom_destroy); - - for ( i = 0; i < MAX_VIRT_CPUS; i++ ) - { - if ( dom->vcpu[i] ) - csched_vcpu_free(dom->vcpu[i]); - } xfree(sdom); } @@ -1226,8 +1220,11 @@ struct scheduler sched_credit_def = { .opt_name = "credit", .sched_id = XEN_SCHEDULER_CREDIT, + .init_domain = csched_dom_init, + .destroy_domain = csched_dom_destroy, + .init_vcpu = csched_vcpu_init, - .destroy_domain = csched_dom_destroy, + .destroy_vcpu = csched_vcpu_destroy, .sleep = csched_vcpu_sleep, .wake = csched_vcpu_wake, diff -r 31985f348d2e -r e793dad2114d xen/common/sched_sedf.c --- a/xen/common/sched_sedf.c Mon Nov 06 09:46:13 2006 +0000 +++ b/xen/common/sched_sedf.c Mon Nov 06 11:03:04 2006 +0000 @@ -333,14 +333,6 @@ static int sedf_init_vcpu(struct vcpu *v { struct sedf_vcpu_info *inf; - if ( v->domain->sched_priv == NULL ) - { - v->domain->sched_priv = xmalloc(struct sedf_dom_info); - if ( v->domain->sched_priv == NULL ) - return -1; - memset(v->domain->sched_priv, 0, sizeof(struct sedf_dom_info)); - } - if ( (v->sched_priv = xmalloc(struct sedf_vcpu_info)) == NULL ) return -1; memset(v->sched_priv, 0, sizeof(struct sedf_vcpu_info)); @@ -398,15 +390,25 @@ static int sedf_init_vcpu(struct vcpu *v return 0; } +static void sedf_destroy_vcpu(struct vcpu *v) +{ + xfree(v->sched_priv); +} + +static int sedf_init_domain(struct domain *d) +{ + d->sched_priv = xmalloc(struct sedf_dom_info); + if ( d->sched_priv == NULL ) + return -ENOMEM; + + memset(d->sched_priv, 0, sizeof(struct sedf_dom_info)); + + return 0; +} + static void sedf_destroy_domain(struct domain *d) { - int i; - xfree(d->sched_priv); - - for ( i = 0; i < MAX_VIRT_CPUS; i++ ) - if ( d->vcpu[i] ) - xfree(d->vcpu[i]->sched_priv); } /* @@ -1427,8 +1429,11 @@ struct scheduler sched_sedf_def = { .opt_name = "sedf", .sched_id = XEN_SCHEDULER_SEDF, + .init_domain = sedf_init_domain, + .destroy_domain = sedf_destroy_domain, + .init_vcpu = sedf_init_vcpu, - .destroy_domain = sedf_destroy_domain, + .destroy_vcpu = sedf_destroy_vcpu, .do_schedule = sedf_do_schedule, .dump_cpu_state = sedf_dump_cpu_state, diff -r 31985f348d2e -r e793dad2114d xen/common/schedule.c --- a/xen/common/schedule.c Mon Nov 06 09:46:13 2006 +0000 +++ b/xen/common/schedule.c Mon Nov 06 11:03:04 2006 +0000 @@ -132,17 +132,20 @@ int sched_init_vcpu(struct vcpu *v, unsi return SCHED_OP(init_vcpu, v); } +void sched_destroy_vcpu(struct vcpu *v) +{ + kill_timer(&v->timer); + kill_timer(&v->poll_timer); + SCHED_OP(destroy_vcpu, v); +} + +int sched_init_domain(struct domain *d) +{ + return SCHED_OP(init_domain, d); +} + void sched_destroy_domain(struct domain *d) { - struct vcpu *v; - - for_each_vcpu ( d, v ) - { - kill_timer(&v->timer); - kill_timer(&v->poll_timer); - TRACE_2D(TRC_SCHED_DOM_REM, v->domain->domain_id, v->vcpu_id); - } - SCHED_OP(destroy_domain, d); } diff -r 31985f348d2e -r e793dad2114d xen/include/xen/domain.h --- a/xen/include/xen/domain.h Mon Nov 06 09:46:13 2006 +0000 +++ b/xen/include/xen/domain.h Mon Nov 06 11:03:04 2006 +0000 @@ -15,9 +15,19 @@ void free_domain(struct domain *d); * Arch-specifics. */ -struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id); +/* Allocate/free a VCPU structure. */ +struct vcpu *alloc_vcpu_struct(void); +void free_vcpu_struct(struct vcpu *v); -void free_vcpu_struct(struct vcpu *v); +/* + * Initialise/destroy arch-specific details of a VCPU. + * - vcpu_initialise() is called after the basic generic fields of the + * VCPU structure are initialised. Many operations can be applied to the + * VCPU at this point (e.g., vcpu_pause()). + * - vcpu_destroy() is called only if vcpu_initialise() previously succeeded. + */ +int vcpu_initialise(struct vcpu *v); +void vcpu_destroy(struct vcpu *v); int arch_domain_create(struct domain *d); diff -r 31985f348d2e -r e793dad2114d xen/include/xen/sched-if.h --- a/xen/include/xen/sched-if.h Mon Nov 06 09:46:13 2006 +0000 +++ b/xen/include/xen/sched-if.h Mon Nov 06 11:03:04 2006 +0000 @@ -63,8 +63,11 @@ struct scheduler { void (*init) (void); void (*tick) (unsigned int cpu); + int (*init_domain) (struct domain *); + void (*destroy_domain) (struct domain *); + int (*init_vcpu) (struct vcpu *); - void (*destroy_domain) (struct domain *); + void (*destroy_vcpu) (struct vcpu *); void (*sleep) (struct vcpu *); void (*wake) (struct vcpu *); diff -r 31985f348d2e -r e793dad2114d xen/include/xen/sched.h --- a/xen/include/xen/sched.h Mon Nov 06 09:46:13 2006 +0000 +++ b/xen/include/xen/sched.h Mon Nov 06 11:03:04 2006 +0000 @@ -291,7 +291,9 @@ void scheduler_init(void); void scheduler_init(void); void schedulers_start(void); int sched_init_vcpu(struct vcpu *v, unsigned int processor); -void sched_destroy_domain(struct domain *); +void sched_destroy_vcpu(struct vcpu *v); +int sched_init_domain(struct domain *d); +void sched_destroy_domain(struct domain *d); long sched_adjust(struct domain *, struct xen_domctl_scheduler_op *); int sched_id(void); void vcpu_wake(struct vcpu *d); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |