|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH for-4.6 v2] x86/mm: Make {hap, shadow}_teardown() preemptible
On Wed, Aug 5, 2015 at 4:47 PM, Andrew Cooper <andrew.cooper3@xxxxxxxxxx> wrote:
> From: Anshul Makkar <anshul.makkar@xxxxxxxxxx>
>
> A domain with sufficient shadow allocation can cause a watchdog timeout
> during domain destruction. Expand the existing -ERESTART logic in
> paging_teardown() to allow {hap/sh}_set_allocation() to become
> restartable during the DOMCTL_destroydomain hypercall.
>
> Signed-off-by: Anshul Makkar <anshul.makkar@xxxxxxxxxx>
> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
> Reviewed-by: Tim Deegan <tim@xxxxxxx>
Looks good, thanks:
Reviewed-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
> ---
> CC: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
> CC: Jan Beulich <JBeulich@xxxxxxxx>
> CC: Wei Liu <wei.liu2@xxxxxxxxxx>
>
> v2:
> * Drop {HAP,SHADOW}_PRINTK(). They are not very useful, and will get
> very noisy if enabled.
>
> Wei: Currently, Xen can't actually run 1TB guests without suffering a
> watchdog timeout when destroying the domain. Therefore this is fairly
> important for 4.6 (and backport), or we will have to retroactively drop
> the currently-stated supported limits on the wiki.
>
> The patch has had extensive testing in XenServer, although has been
> forward ported from 4.5.
> ---
> xen/arch/x86/mm/hap/hap.c | 22 ++++++++--------------
> xen/arch/x86/mm/paging.c | 9 ++++++---
> xen/arch/x86/mm/shadow/common.c | 24 +++++++++---------------
> xen/include/asm-x86/hap.h | 2 +-
> xen/include/asm-x86/shadow.h | 4 ++--
> 5 files changed, 26 insertions(+), 35 deletions(-)
>
> diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c
> index d375c4d..e9c0080 100644
> --- a/xen/arch/x86/mm/hap/hap.c
> +++ b/xen/arch/x86/mm/hap/hap.c
> @@ -551,7 +551,7 @@ void hap_final_teardown(struct domain *d)
> }
>
> if ( d->arch.paging.hap.total_pages != 0 )
> - hap_teardown(d);
> + hap_teardown(d, NULL);
>
> p2m_teardown(p2m_get_hostp2m(d));
> /* Free any memory that the p2m teardown released */
> @@ -561,7 +561,7 @@ void hap_final_teardown(struct domain *d)
> paging_unlock(d);
> }
>
> -void hap_teardown(struct domain *d)
> +void hap_teardown(struct domain *d, int *preempted)
> {
> struct vcpu *v;
> mfn_t mfn;
> @@ -589,18 +589,11 @@ void hap_teardown(struct domain *d)
>
> if ( d->arch.paging.hap.total_pages != 0 )
> {
> - HAP_PRINTK("teardown of domain %u starts."
> - " pages total = %u, free = %u, p2m=%u\n",
> - d->domain_id,
> - d->arch.paging.hap.total_pages,
> - d->arch.paging.hap.free_pages,
> - d->arch.paging.hap.p2m_pages);
> - hap_set_allocation(d, 0, NULL);
> - HAP_PRINTK("teardown done."
> - " pages total = %u, free = %u, p2m=%u\n",
> - d->arch.paging.hap.total_pages,
> - d->arch.paging.hap.free_pages,
> - d->arch.paging.hap.p2m_pages);
> + hap_set_allocation(d, 0, preempted);
> +
> + if ( preempted && *preempted )
> + goto out;
> +
> ASSERT(d->arch.paging.hap.total_pages == 0);
> }
>
> @@ -609,6 +602,7 @@ void hap_teardown(struct domain *d)
> xfree(d->arch.hvm_domain.dirty_vram);
> d->arch.hvm_domain.dirty_vram = NULL;
>
> +out:
> paging_unlock(d);
> }
>
> diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c
> index 618f475..5becee8 100644
> --- a/xen/arch/x86/mm/paging.c
> +++ b/xen/arch/x86/mm/paging.c
> @@ -799,12 +799,15 @@ long
> paging_domctl_continuation(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
> /* Call when destroying a domain */
> int paging_teardown(struct domain *d)
> {
> - int rc;
> + int rc, preempted = 0;
>
> if ( hap_enabled(d) )
> - hap_teardown(d);
> + hap_teardown(d, &preempted);
> else
> - shadow_teardown(d);
> + shadow_teardown(d, &preempted);
> +
> + if ( preempted )
> + return -ERESTART;
>
> /* clean up log dirty resources. */
> rc = paging_free_log_dirty_bitmap(d, 0);
> diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c
> index abce8e2..0264b91 100644
> --- a/xen/arch/x86/mm/shadow/common.c
> +++ b/xen/arch/x86/mm/shadow/common.c
> @@ -3071,7 +3071,7 @@ int shadow_enable(struct domain *d, u32 mode)
> return rv;
> }
>
> -void shadow_teardown(struct domain *d)
> +void shadow_teardown(struct domain *d, int *preempted)
> /* Destroy the shadow pagetables of this domain and free its shadow memory.
> * Should only be called for dying domains. */
> {
> @@ -3132,23 +3132,16 @@ void shadow_teardown(struct domain *d)
>
> if ( d->arch.paging.shadow.total_pages != 0 )
> {
> - SHADOW_PRINTK("teardown of domain %u starts."
> - " Shadow pages total = %u, free = %u, p2m=%u\n",
> - d->domain_id,
> - d->arch.paging.shadow.total_pages,
> - d->arch.paging.shadow.free_pages,
> - d->arch.paging.shadow.p2m_pages);
> /* Destroy all the shadows and release memory to domheap */
> - sh_set_allocation(d, 0, NULL);
> + sh_set_allocation(d, 0, preempted);
> +
> + if ( preempted && *preempted )
> + goto out;
> +
> /* Release the hash table back to xenheap */
> if (d->arch.paging.shadow.hash_table)
> shadow_hash_teardown(d);
> - /* Should not have any more memory held */
> - SHADOW_PRINTK("teardown done."
> - " Shadow pages total = %u, free = %u, p2m=%u\n",
> - d->arch.paging.shadow.total_pages,
> - d->arch.paging.shadow.free_pages,
> - d->arch.paging.shadow.p2m_pages);
> +
> ASSERT(d->arch.paging.shadow.total_pages == 0);
> }
>
> @@ -3177,6 +3170,7 @@ void shadow_teardown(struct domain *d)
> d->arch.hvm_domain.dirty_vram = NULL;
> }
>
> +out:
> paging_unlock(d);
>
> /* Must be called outside the lock */
> @@ -3198,7 +3192,7 @@ void shadow_final_teardown(struct domain *d)
> * It is possible for a domain that never got domain_kill()ed
> * to get here with its shadow allocation intact. */
> if ( d->arch.paging.shadow.total_pages != 0 )
> - shadow_teardown(d);
> + shadow_teardown(d, NULL);
>
> /* It is now safe to pull down the p2m map. */
> p2m_teardown(p2m_get_hostp2m(d));
> diff --git a/xen/include/asm-x86/hap.h b/xen/include/asm-x86/hap.h
> index bd87481..c613836 100644
> --- a/xen/include/asm-x86/hap.h
> +++ b/xen/include/asm-x86/hap.h
> @@ -38,7 +38,7 @@ int hap_domctl(struct domain *d, xen_domctl_shadow_op_t
> *sc,
> XEN_GUEST_HANDLE_PARAM(void) u_domctl);
> int hap_enable(struct domain *d, u32 mode);
> void hap_final_teardown(struct domain *d);
> -void hap_teardown(struct domain *d);
> +void hap_teardown(struct domain *d, int *preempted);
> void hap_vcpu_init(struct vcpu *v);
> int hap_track_dirty_vram(struct domain *d,
> unsigned long begin_pfn,
> diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h
> index 9cd653e..6d0aefb 100644
> --- a/xen/include/asm-x86/shadow.h
> +++ b/xen/include/asm-x86/shadow.h
> @@ -73,7 +73,7 @@ int shadow_domctl(struct domain *d,
> XEN_GUEST_HANDLE_PARAM(void) u_domctl);
>
> /* Call when destroying a domain */
> -void shadow_teardown(struct domain *d);
> +void shadow_teardown(struct domain *d, int *preempted);
>
> /* Call once all of the references to the domain have gone away */
> void shadow_final_teardown(struct domain *d);
> @@ -85,7 +85,7 @@ int shadow_domctl(struct domain *d,
>
> #else /* !CONFIG_SHADOW_PAGING */
>
> -#define shadow_teardown(d) ASSERT(is_pv_domain(d))
> +#define shadow_teardown(d, p) ASSERT(is_pv_domain(d))
> #define shadow_final_teardown(d) ASSERT(is_pv_domain(d))
> #define shadow_enable(d, mode) \
> ({ ASSERT(is_pv_domain(d)); -EOPNOTSUPP; })
> --
> 1.7.10.4
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxx
> http://lists.xen.org/xen-devel
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |