diff options
author | iap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk> | 2004-05-12 09:11:22 +0000 |
---|---|---|
committer | iap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk> | 2004-05-12 09:11:22 +0000 |
commit | 303ca01553d72c480448a085c62854bc3ec1d4d5 (patch) | |
tree | 405aacab05cd87d75e19ac982fa7c49b767d2041 /xen | |
parent | 68f817997c9fc419a76d4c9677e663e63d487e22 (diff) | |
download | xen-303ca01553d72c480448a085c62854bc3ec1d4d5.tar.gz xen-303ca01553d72c480448a085c62854bc3ec1d4d5.tar.bz2 xen-303ca01553d72c480448a085c62854bc3ec1d4d5.zip |
bitkeeper revision 1.899 (40a1ea3a_7ZmXmUq-RTnUSd3QZ_X1Q)
live migration cleanups
Diffstat (limited to 'xen')
-rw-r--r-- | xen/Rules.mk | 5 | ||||
-rw-r--r-- | xen/common/dom0_ops.c | 12 | ||||
-rw-r--r-- | xen/common/kernel.c | 3 | ||||
-rw-r--r-- | xen/common/shadow.c | 131 | ||||
-rw-r--r-- | xen/include/hypervisor-ifs/dom0_ops.h | 1 | ||||
-rw-r--r-- | xen/include/xen/shadow.h | 1 |
6 files changed, 110 insertions, 43 deletions
diff --git a/xen/Rules.mk b/xen/Rules.mk index a9db6358a4..e75a79cbe2 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -3,6 +3,7 @@ TARGET_ARCH ?= $(COMPILE_ARCH) nodev ?= n debug ?= n +trace ?= n TARGET := $(BASEDIR)/xen HDRS := $(wildcard $(BASEDIR)/include/xen/*.h) @@ -50,6 +51,10 @@ ifeq ($(nodev),y) CFLAGS += -DNO_DEVICES_IN_XEN endif +ifeq ($(trace),y) +CFLAGS += -DTRACE_BUFFER +endif + %.o: %.c $(HDRS) Makefile $(CC) $(CFLAGS) -c $< -o $@ diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index dee7552bdd..f768edd5ff 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -21,6 +21,11 @@ #include <xen/shadow.h> #include <hypervisor-ifs/sched_ctl.h> + +#define TRC_DOM0OP_START_BASE 0x00020000 +#define TRC_DOM0OP_FINISH_BASE 0x00030000 + + extern unsigned int alloc_new_dom_mem(struct task_struct *, unsigned int); /* Basically used to protect the domain-id space. */ @@ -68,6 +73,9 @@ long do_dom0_op(dom0_op_t *u_dom0_op) return -EACCES; } + TRACE_5D( TRC_DOM0OP_START_BASE + op->cmd, + 0, op->u.dummy[0], op->u.dummy[1], op->u.dummy[2], op->u.dummy[3] ); + switch ( op->cmd ) { @@ -671,5 +679,9 @@ long do_dom0_op(dom0_op_t *u_dom0_op) } + TRACE_5D( TRC_DOM0OP_FINISH_BASE + op->cmd, ret, + op->u.dummy[0], op->u.dummy[1], op->u.dummy[2], op->u.dummy[3] ); + + return ret; } diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 0d5fa023a1..b33524928d 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -31,6 +31,7 @@ #include <xen/console.h> #include <xen/net_headers.h> #include <xen/serial.h> +#include <xen/shadow.h> kmem_cache_t *task_struct_cachep; @@ -268,6 +269,8 @@ void cmain(unsigned long magic, multiboot_info_t *mbi) set_bit(PF_PRIVILEGED, &new_dom->flags); + shadow_mode_init(); + /* * We're going to setup domain0 using the module(s) that we stashed safely * above our MAX_DIRECTMAP_ADDRESS in boot/boot.S. The second module, if diff --git a/xen/common/shadow.c b/xen/common/shadow.c index fe142e3ee9..ec5ce29d5a 100644 --- a/xen/common/shadow.c +++ b/xen/common/shadow.c @@ -6,6 +6,8 @@ #include <xen/shadow.h> #include <asm/domain_page.h> #include <asm/page.h> +#include <xen/event.h> +#include <xen/trace.h> /******** @@ -26,6 +28,8 @@ hypercall lock anyhow (at least initially). ********/ +static spinlock_t cpu_stall_lock; + static inline void free_shadow_page( struct mm_struct *m, struct pfn_info *pfn_info ) { @@ -155,6 +159,11 @@ static void __scan_shadow_table( struct mm_struct *m, unsigned int op ) } +void shadow_mode_init(void) +{ + spin_lock_init( &cpu_stall_lock ); +} + int shadow_mode_enable( struct task_struct *p, unsigned int mode ) { struct mm_struct *m = &p->mm; @@ -260,11 +269,11 @@ void shadow_mode_disable( struct task_struct *p ) } static int shadow_mode_table_op( struct task_struct *p, - dom0_shadow_control_t *sc ) + dom0_shadow_control_t *sc ) { - unsigned int op = sc->op; + unsigned int op = sc->op; struct mm_struct *m = &p->mm; - int rc = 0; + int rc = 0; // since Dom0 did the hypercall, we should be running with it's page // tables right now. Calling flush on yourself would be really @@ -290,37 +299,50 @@ static int shadow_mode_table_op( struct task_struct *p, break; case DOM0_SHADOW_CONTROL_OP_CLEAN: + { + int i,j,zero=1; + + __scan_shadow_table( m, op ); + + if( p->tot_pages > sc->pages || + !sc->dirty_bitmap || !p->mm.shadow_dirty_bitmap ) { - int i; - - __scan_shadow_table( m, op ); - - if( p->tot_pages > sc->pages || - !sc->dirty_bitmap || !p->mm.shadow_dirty_bitmap ) - { - rc = -EINVAL; - goto out; - } - - sc->pages = p->tot_pages; - + rc = -EINVAL; + goto out; + } + + sc->pages = p->tot_pages; + #define chunk (8*1024) // do this in 1KB chunks for L1 cache - - for(i=0;i<p->tot_pages;i+=chunk) + + for(i=0;i<p->tot_pages;i+=chunk) + { + int bytes = (( ((p->tot_pages-i) > (chunk))? + (chunk):(p->tot_pages-i) ) + 7) / 8; + + copy_to_user( sc->dirty_bitmap + (i/(8*sizeof(unsigned long))), + p->mm.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))), + bytes ); + + for(j=0; zero && j<bytes/sizeof(unsigned long);j++) { - int bytes = (( ((p->tot_pages-i) > (chunk))? - (chunk):(p->tot_pages-i) ) + 7) / 8; - - copy_to_user( sc->dirty_bitmap + (i/(8*sizeof(unsigned long))), - p->mm.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))), - bytes ); + if( p->mm.shadow_dirty_bitmap[j] != 0 ) + zero = 0; + } - memset( p->mm.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))), - 0, bytes); - } + memset( p->mm.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))), + 0, bytes); + } - break; + if (zero) + { + /* might as well stop the domain as an optimization. */ + if ( p->state != TASK_STOPPED ) + send_guest_virq(p, VIRQ_STOP); } + + break; + } } @@ -338,22 +360,45 @@ out: return rc; } - int shadow_mode_control( struct task_struct *p, dom0_shadow_control_t *sc ) { - int we_paused = 0; - unsigned int cmd = sc->op; - int rc = 0; - + unsigned int cmd = sc->op; + int rc = 0, cpu; + // don't call if already shadowed... - // sychronously stop domain - if( 0 && !(p->state & TASK_STOPPED) && !(p->state & TASK_PAUSED)) - { - printk("about to pause domain\n"); - sched_pause_sync(p); - printk("paused domain\n"); - we_paused = 1; + /* The following is pretty hideous because we don't have a way of + synchronously pausing a domain. If it's assigned to the curernt CPU, + we don't have to worry -- it can't possibly actually be running. + If its on another CPU, for the moment, we do something really gross: + we cause the other CPU to spin regardless of what domain it is running. + + I know this is really grim, but it only lasts a few 10's of + microseconds. It needs fixing as soon as the last of the Linux-isms + get removed from the task structure... + + Oh, and let's hope someone doesn't repin the CPU while we're here. + Also, prey someone else doesn't do this in another domain. + At least there's only one dom0 at the moment... + */ +printk("SMC\n"); + spin_lock( &cpu_stall_lock ); + cpu = p->processor; +printk("got %d %d\n",cpu, current->processor ); + if ( cpu != current->processor ) + { +printk("CPU %d %d\n",cpu, current->processor ); + static void cpu_stall(void * data) + { + if ( current->processor == (int) data ) + { + printk("Stall %d\n",(int)data); + spin_lock( &cpu_stall_lock ); + spin_unlock( &cpu_stall_lock ); + } + } + + smp_call_function(cpu_stall, (void*)cpu, 1, 0); // don't wait! } if ( p->mm.shadow_mode && cmd == DOM0_SHADOW_CONTROL_OP_OFF ) @@ -376,11 +421,11 @@ int shadow_mode_control( struct task_struct *p, dom0_shadow_control_t *sc ) } else { - if ( we_paused ) wake_up(p); - return -EINVAL; + rc = -EINVAL; } - if ( we_paused ) wake_up(p); + spin_unlock( &cpu_stall_lock ); +printk("SMC-\n"); return rc; } diff --git a/xen/include/hypervisor-ifs/dom0_ops.h b/xen/include/hypervisor-ifs/dom0_ops.h index 0027e9df29..879a728bd4 100644 --- a/xen/include/hypervisor-ifs/dom0_ops.h +++ b/xen/include/hypervisor-ifs/dom0_ops.h @@ -289,6 +289,7 @@ typedef struct dom0_op_st unsigned long interface_version; /* DOM0_INTERFACE_VERSION */ union { + unsigned long dummy[4]; dom0_createdomain_t createdomain; dom0_startdomain_t startdomain; dom0_stopdomain_t stopdomain; diff --git a/xen/include/xen/shadow.h b/xen/include/xen/shadow.h index 01b46301aa..bfb2a04256 100644 --- a/xen/include/xen/shadow.h +++ b/xen/include/xen/shadow.h @@ -23,6 +23,7 @@ #define shadow_linear_pg_table ((l1_pgentry_t *)SH_LINEAR_PT_VIRT_START) #define shadow_linear_l2_table ((l2_pgentry_t *)(SH_LINEAR_PT_VIRT_START+(SH_LINEAR_PT_VIRT_START>>(L2_PAGETABLE_SHIFT-L1_PAGETABLE_SHIFT)))) +extern void shadow_mode_init(void); extern int shadow_mode_control( struct task_struct *p, dom0_shadow_control_t *sc ); extern int shadow_fault( unsigned long va, long error_code ); extern void shadow_l1_normal_pt_update( unsigned long pa, unsigned long gpte, |