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

Re: [Xen-devel] [PATCH RFC LINUX v1] xen: arm: enable migration on ARM.



On Wed, 6 Jan 2016, Stefano Stabellini wrote:
> Please CC linux-arm for the non-RFC patches
> 
> On Wed, 9 Dec 2015, Ian Campbell wrote:
> > Replace various stub functions with real functionality, including
> > reestablishing the shared info page and the per-vcpu info pages on
> > restore.
> > 
> > Reestablishing the vcpu info page is a little subtle. The
> > VCPUOP_register_vcpu_info hypercall can only be called on either the
> > current VCPU or on an offline different VCPU. Since migration occurs
> > with all VCPUS online they are all therefore online at the point of
> > resume.
> > 
> > Therefore we must perform a cross VCPU call to each non-boot VCPU,
> > which cannot be done in the xen_arch_post_suspend() callback since
> > that is run from stop_machine() with interrupts disabled.
> > 
> > Furthermore VCPUOP_register_vcpu_info can only be called once per-VCPU
> > in a given domain, so it must not be called after a cancelled suspend
> > (which resumes in the same domain).
> > 
> > Therefore xen_arch_resume() gains a suspend_cancelled parameter and we
> > resume the secondary VCPUs there only if needed.
> 
> This is a bit complex, maybe we could use a cpu notifier like we do on
> x86?

Sorry forget this email, it was sent by mistake.


> > The VCPU which is running the suspend is resumed earlier in the
> > xen_arch_post_suspend callback, again conditionally only for
> > non-cancelled suspends.
> > 
> > Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
> > ---
> >  arch/arm/xen/Makefile    |  2 +-
> >  arch/arm/xen/enlighten.c | 54 
> > +++++++++++++++++++++++++++++++-----------------
> >  arch/arm/xen/suspend.c   | 54 
> > ++++++++++++++++++++++++++++++++++++++++++++++++
> >  arch/arm/xen/xen-ops.h   |  9 ++++++++
> >  arch/x86/xen/suspend.c   |  2 +-
> >  drivers/xen/manage.c     |  2 +-
> >  include/xen/xen-ops.h    |  2 +-
> >  7 files changed, 102 insertions(+), 23 deletions(-)
> >  create mode 100644 arch/arm/xen/suspend.c
> >  create mode 100644 arch/arm/xen/xen-ops.h
> > 
> > diff --git a/arch/arm/xen/Makefile b/arch/arm/xen/Makefile
> > index 1296952..677022c 100644
> > --- a/arch/arm/xen/Makefile
> > +++ b/arch/arm/xen/Makefile
> > @@ -1 +1 @@
> > -obj-y              := enlighten.o hypercall.o grant-table.o p2m.o mm.o
> > +obj-y      := enlighten.o hypercall.o grant-table.o p2m.o mm.o suspend.o
> > diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
> > index eeeab07..72f314e 100644
> > --- a/arch/arm/xen/enlighten.c
> > +++ b/arch/arm/xen/enlighten.c
> > @@ -182,10 +182,41 @@ void __init xen_early_init(void)
> >             add_preferred_console("hvc", 0, NULL);
> >  }
> >  
> > -static int __init xen_guest_init(void)
> > +static struct shared_info *shared_info_page;
> > +
> > +int xen_register_shared_info(void)
> >  {
> >     struct xen_add_to_physmap xatp;
> > -   struct shared_info *shared_info_page = NULL;
> > +
> > +   /*
> > +         * This function is called on boot and on restore. On boot we
> > +         * allocate this page immediately before calling this function
> > +         * and bail on failure. On resume that allocation must have
> > +         * succeeded or we couldn't be doing a save/restore.
> > +         */
> > +   BUG_ON(!shared_info_page);
> > +
> > +   xatp.domid = DOMID_SELF;
> > +   xatp.idx = 0;
> > +   xatp.space = XENMAPSPACE_shared_info;
> > +   xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
> > +   if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
> > +           BUG();
> > +
> > +   HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
> > +
> > +   return 0;
> > +}
> > +
> > +void xen_vcpu_restore(void)
> > +{
> > +   xen_percpu_init();
> > +
> > +   /* XXX TODO: xen_setup_runstate_info(cpu); */
> > +}
> > +
> > +static int __init xen_guest_init(void)
> > +{
> >     struct resource res;
> >     phys_addr_t grant_frames;
> >  
> > @@ -210,18 +241,12 @@ static int __init xen_guest_init(void)
> >             pr_err("not enough memory\n");
> >             return -ENOMEM;
> >     }
> > -   xatp.domid = DOMID_SELF;
> > -   xatp.idx = 0;
> > -   xatp.space = XENMAPSPACE_shared_info;
> > -   xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
> > -   if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
> > -           BUG();
> >  
> > -   HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
> > +   xen_register_shared_info();
> >  
> >     /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
> >      * page, we use it in the event channel upcall and in some pvclock
> > -    * related functions. 
> > +    * related functions.
> >      * The shared info contains exactly 1 CPU (the boot CPU). The guest
> >      * is required to use VCPUOP_register_vcpu_info to place vcpu info
> >      * for secondary CPUs as they are brought up.
> > @@ -275,15 +300,6 @@ static int __init xen_pm_init(void)
> >  }
> >  late_initcall(xen_pm_init);
> >  
> > -
> > -/* empty stubs */
> > -void xen_arch_pre_suspend(void) { }
> > -void xen_arch_post_suspend(int suspend_cancelled) { }
> > -void xen_timer_resume(void) { }
> > -void xen_arch_resume(void) { }
> > -void xen_arch_suspend(void) { }
> > -
> > -
> >  /* In the hypervisor.S file. */
> >  EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op);
> >  EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op);
> > diff --git a/arch/arm/xen/suspend.c b/arch/arm/xen/suspend.c
> > new file mode 100644
> > index 0000000..b420758
> > --- /dev/null
> > +++ b/arch/arm/xen/suspend.c
> > @@ -0,0 +1,54 @@
> > +#include <linux/types.h>
> > +#include <linux/tick.h>
> > +
> > +#include <xen/interface/xen.h>
> > +
> > +#include <asm/xen/hypercall.h>
> > +
> > +#include "xen-ops.h"
> > +
> > +void xen_arch_pre_suspend(void) {
> > +   /* Nothing to do */
> > +}
> > +
> > +void xen_arch_post_suspend(int suspend_cancelled)
> > +{
> > +   xen_register_shared_info();
> > +   if (!suspend_cancelled)
> > +           xen_vcpu_restore();
> > +}
> > +
> > +static void xen_vcpu_notify_suspend(void *data)
> > +{
> > +   tick_suspend_local();
> > +}
> > +
> > +static void xen_vcpu_notify_resume(void *data)
> > +{
> > +   int suspend_cancelled = *(int *)data;
> > +
> > +   if (smp_processor_id() == 0)
> > +           return;
> > +
> > +   /* Boot processor done in post_suspend */
> > +   if (!suspend_cancelled)
> > +           xen_vcpu_restore();
> > +
> > +   /* Boot processor notified via generic timekeeping_resume() */
> > +   tick_resume_local();
> > +}
> > +
> > +void xen_arch_suspend(void)
> > +{
> > +   on_each_cpu(xen_vcpu_notify_suspend, NULL, 1);
> > +}
> > +
> > +void xen_arch_resume(int suspend_cancelled)
> > +{
> > +   on_each_cpu(xen_vcpu_notify_resume, &suspend_cancelled, 1);
> > +}
> > +
> > +void xen_timer_resume(void)
> > +{
> > +   /* Nothing to do */
> > +}
> > diff --git a/arch/arm/xen/xen-ops.h b/arch/arm/xen/xen-ops.h
> > new file mode 100644
> > index 0000000..de23e91
> > --- /dev/null
> > +++ b/arch/arm/xen/xen-ops.h
> > @@ -0,0 +1,9 @@
> > +#ifndef XEN_OPS_H
> > +#define XEN_OPS_H
> > +
> > +#include <xen/xen-ops.h>
> > +
> > +void xen_register_shared_info(void);
> > +void xen_vcpu_restore(void);
> > +
> > +#endif /* XEN_OPS_H */
> > diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
> > index feddabd..ce2545a 100644
> > --- a/arch/x86/xen/suspend.c
> > +++ b/arch/x86/xen/suspend.c
> > @@ -104,7 +104,7 @@ static void xen_vcpu_notify_suspend(void *data)
> >     tick_suspend_local();
> >  }
> >  
> > -void xen_arch_resume(void)
> > +void xen_arch_resume(int suspend_cancelled)
> >  {
> >     on_each_cpu(xen_vcpu_notify_restore, NULL, 1);
> >  }
> > diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
> > index b6e4c40..a1a64bc 100644
> > --- a/drivers/xen/manage.c
> > +++ b/drivers/xen/manage.c
> > @@ -156,7 +156,7 @@ static void do_suspend(void)
> >             si.cancelled = 1;
> >     }
> >  
> > -   xen_arch_resume();
> > +   xen_arch_resume(si.cancelled);
> >  
> >  out_resume:
> >     if (!si.cancelled)
> > diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
> > index e4e214a..d93da50 100644
> > --- a/include/xen/xen-ops.h
> > +++ b/include/xen/xen-ops.h
> > @@ -12,7 +12,7 @@ void xen_arch_pre_suspend(void);
> >  void xen_arch_post_suspend(int suspend_cancelled);
> >  
> >  void xen_timer_resume(void);
> > -void xen_arch_resume(void);
> > +void xen_arch_resume(int suspend_cancelled);
> >  void xen_arch_suspend(void);
> >  
> >  void xen_resume_notifier_register(struct notifier_block *nb);
> > -- 
> > 2.1.4
> > 
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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