[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Do not pickle vcpu state on save/restore. We can construct



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID bf6119a5865514ba9dcfecb23e505049437e9c2c
# Parent  f22fba6731968547f2826e78005c8466e4f14847
Do not pickle vcpu state on save/restore. We can construct
suitable initial state for each vcpu during restore, without
need for pickle/unpickle.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r f22fba673196 -r bf6119a58655 
linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c       Mon Oct  3 
09:26:29 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c       Mon Oct  3 
14:02:23 2005
@@ -141,6 +141,13 @@
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
+void cpu_restore(void)
+{
+       play_dead();
+       local_irq_enable();
+       cpu_idle();
+}
+
 /*
  * The idle thread. There's no useful work to be
  * done, so just try to conserve power and have a
diff -r f22fba673196 -r bf6119a58655 
linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Mon Oct  3 
09:26:29 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Mon Oct  3 
14:02:23 2005
@@ -802,7 +802,6 @@
        extern void hypervisor_callback(void);
        extern void failsafe_callback(void);
        extern void smp_trap_init(trap_info_t *);
-       int i;
 
        cpu = ++cpucount;
        /*
@@ -853,12 +852,6 @@
        /* FPU is set up to default initial state. */
        memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
 
-       /* Virtual IDT is empty at start-of-day. */
-       for ( i = 0; i < 256; i++ )
-       {
-               ctxt.trap_ctxt[i].vector = i;
-               ctxt.trap_ctxt[i].cs     = FLAT_KERNEL_CS;
-       }
        smp_trap_init(ctxt.trap_ctxt);
 
        /* No LDT. */
@@ -1585,61 +1578,48 @@
        local_setup_timer_irq();
 }
 
-static atomic_t vcpus_rebooting;
-
-static void restore_vcpu_ready(void)
-{
-
-       atomic_dec(&vcpus_rebooting);
-}
-
-void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
-{
-       int r;
-       int gdt_pages;
-       r = HYPERVISOR_vcpu_pickle(vcpu, ctxt);
-       if (r != 0)
-               panic("pickling vcpu %d -> %d!\n", vcpu, r);
-
-       /* Translate from machine to physical addresses where necessary,
-          so that they can be translated to our new machine address space
-          after resume.  libxc is responsible for doing this to vcpu0,
-          but we do it to the others. */
-       gdt_pages = (ctxt->gdt_ents + 511) / 512;
-       ctxt->ctrlreg[3] = machine_to_phys(ctxt->ctrlreg[3]);
-       for (r = 0; r < gdt_pages; r++)
-               ctxt->gdt_frames[r] = mfn_to_pfn(ctxt->gdt_frames[r]);
-}
-
-int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
-{
-       int r;
-       int gdt_pages = (ctxt->gdt_ents + 511) / 512;
-
-       /* This is kind of a hack, and implicitly relies on the fact that
-          the vcpu stops in a place where all of the call clobbered
-          registers are already dead. */
-       ctxt->user_regs.esp -= 4;
-       ((unsigned long *)ctxt->user_regs.esp)[0] = ctxt->user_regs.eip;
-       ctxt->user_regs.eip = (unsigned long)restore_vcpu_ready;
-
-       /* De-canonicalise.  libxc handles this for vcpu 0, but we need
-          to do it for the other vcpus. */
-       ctxt->ctrlreg[3] = phys_to_machine(ctxt->ctrlreg[3]);
-       for (r = 0; r < gdt_pages; r++)
-               ctxt->gdt_frames[r] = pfn_to_mfn(ctxt->gdt_frames[r]);
-
-       atomic_set(&vcpus_rebooting, 1);
-       r = HYPERVISOR_boot_vcpu(vcpu, ctxt);
-       if (r != 0) {
-               printk(KERN_EMERG "Failed to reboot vcpu %d (%d)\n", vcpu, r);
-               return -1;
-       }
-
-       /* Make sure we wait for the new vcpu to come up before trying to do
-          anything with it or starting the next one. */
-       while (atomic_read(&vcpus_rebooting))
-               barrier();
-
-       return 0;
-}
+void vcpu_prepare(int vcpu)
+{
+       extern void hypervisor_callback(void);
+       extern void failsafe_callback(void);
+       extern void smp_trap_init(trap_info_t *);
+       extern void cpu_restore(void);
+       vcpu_guest_context_t ctxt;
+       struct task_struct *idle = idle_task(vcpu);
+
+       if (vcpu == 0)
+               return;
+
+       memset(&ctxt, 0, sizeof(ctxt));
+
+       ctxt.user_regs.ds = __USER_DS;
+       ctxt.user_regs.es = __USER_DS;
+       ctxt.user_regs.fs = 0;
+       ctxt.user_regs.gs = 0;
+       ctxt.user_regs.ss = __KERNEL_DS;
+       ctxt.user_regs.cs = __KERNEL_CS;
+       ctxt.user_regs.eip = (unsigned long)cpu_restore;
+       ctxt.user_regs.esp = idle->thread.esp;
+       ctxt.user_regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_IOPL_RING1;
+
+       memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
+
+       smp_trap_init(ctxt.trap_ctxt);
+
+       ctxt.ldt_ents = 0;
+
+       ctxt.gdt_frames[0] = virt_to_mfn(cpu_gdt_descr[vcpu].address);
+       ctxt.gdt_ents      = cpu_gdt_descr[vcpu].size / 8;
+
+       ctxt.kernel_ss = __KERNEL_DS;
+       ctxt.kernel_sp = idle->thread.esp0;
+
+       ctxt.event_callback_cs     = __KERNEL_CS;
+       ctxt.event_callback_eip    = (unsigned long)hypervisor_callback;
+       ctxt.failsafe_callback_cs  = __KERNEL_CS;
+       ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
+
+       ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT;
+
+       (void)HYPERVISOR_boot_vcpu(vcpu, &ctxt);
+}
diff -r f22fba673196 -r bf6119a58655 
linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Mon Oct  3 09:26:29 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Mon Oct  3 14:02:23 2005
@@ -1012,6 +1012,12 @@
 void smp_trap_init(trap_info_t *trap_ctxt)
 {
        trap_info_t *t = trap_table;
+       int i;
+
+       for (i = 0; i < 256; i++) {
+               trap_ctxt[i].vector = i;
+               trap_ctxt[i].cs     = FLAT_KERNEL_CS;
+       }
 
        for (t = trap_table; t->address; t++) {
                trap_ctxt[t->vector].flags = t->flags;
diff -r f22fba673196 -r bf6119a58655 
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Mon Oct  3 09:26:29 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Mon Oct  3 14:02:23 2005
@@ -74,11 +74,8 @@
        extern unsigned long *pfn_to_mfn_frame_list[];
 
 #ifdef CONFIG_SMP
-       static vcpu_guest_context_t suspended_cpu_records[NR_CPUS];
-       cpumask_t prev_online_cpus, prev_present_cpus;
-
-       void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
-       int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
+       cpumask_t prev_online_cpus;
+       int vcpu_prepare(int vcpu);
 #endif
 
        extern void xencons_resume(void);
@@ -132,16 +129,6 @@
 
        preempt_enable();
 
-#ifdef CONFIG_SMP
-       cpus_clear(prev_present_cpus);
-       for_each_present_cpu(i) {
-               if (i == 0)
-                       continue;
-               save_vcpu_context(i, &suspended_cpu_records[i]);
-               cpu_set(i, prev_present_cpus);
-       }
-#endif
-
        gnttab_suspend();
 
 #ifdef __i386__
@@ -189,18 +176,16 @@
 
        time_resume();
 
+       __sti();
+
+       xencons_resume();
+
+       xenbus_resume();
+
 #ifdef CONFIG_SMP
-       for_each_cpu_mask(i, prev_present_cpus)
-               restore_vcpu_context(i, &suspended_cpu_records[i]);
-#endif
-
-       __sti();
-
-       xencons_resume();
-
-       xenbus_resume();
-
-#ifdef CONFIG_SMP
+       for_each_present_cpu(i)
+               vcpu_prepare(i);
+
  out_reenable_cpus:
        for_each_cpu_mask(i, prev_online_cpus) {
                j = cpu_up(i);
diff -r f22fba673196 -r bf6119a58655 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c     Mon Oct  3 
09:26:29 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c     Mon Oct  3 
14:02:23 2005
@@ -742,12 +742,6 @@
        /* FPU is set up to default initial state. */
        memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
 
-       /* Virtual IDT is empty at start-of-day. */
-       for ( i = 0; i < 256; i++ )
-       {
-               ctxt.trap_ctxt[i].vector = i;
-               ctxt.trap_ctxt[i].cs     = FLAT_KERNEL_CS;
-       }
        smp_trap_init(ctxt.trap_ctxt);
 
        /* No LDT. */
@@ -1267,13 +1261,8 @@
        local_setup_timer_irq();
 }
 
-void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
-{
-}
-
-int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
-{
-       return 0;
-}
-
-#endif
+void vcpu_prepare(int vcpu)
+{
+}
+
+#endif
diff -r f22fba673196 -r bf6119a58655 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c       Mon Oct  3 
09:26:29 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c       Mon Oct  3 
14:02:23 2005
@@ -956,6 +956,12 @@
 void smp_trap_init(trap_info_t *trap_ctxt)
 {
        trap_info_t *t = trap_table;
+       int i;
+
+       for (i = 0; i < 256; i++) {
+               trap_ctxt[i].vector = i;
+               trap_ctxt[i].cs     = FLAT_KERNEL_CS;
+       }
 
        for (t = trap_table; t->address; t++) {
                trap_ctxt[t->vector].flags = t->flags;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.