* [PATCH for-4.6] x86/mm: Make {hap, shadow}_teardown() preemptible
@ 2015-08-05 12:36 Andrew Cooper
2015-08-05 14:26 ` Tim Deegan
0 siblings, 1 reply; 2+ messages in thread
From: Andrew Cooper @ 2015-08-05 12:36 UTC (permalink / raw)
To: Xen-devel
Cc: Wei Liu, George Dunlap, Andrew Cooper, Anshul Makkar, Tim Deegan,
Jan Beulich
From: Anshul Makkar <anshul.makkar@citrix.com>
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@citrix.com>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Tim Deegan <tim@xen.org>
CC: George Dunlap <george.dunlap@eu.citrix.com>
CC: Jan Beulich <JBeulich@suse.com>
CC: Wei Liu <wei.liu2@citrix.com>
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 | 9 ++++++---
xen/arch/x86/mm/paging.c | 8 +++++---
xen/arch/x86/mm/shadow/common.c | 9 ++++++---
xen/include/asm-x86/hap.h | 2 +-
xen/include/asm-x86/shadow.h | 4 ++--
5 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c
index d375c4d..21ae5d4 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;
@@ -595,7 +595,9 @@ void hap_teardown(struct domain *d)
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_set_allocation(d, 0, preempted);
+ if ( preempted && *preempted )
+ goto out;
HAP_PRINTK("teardown done."
" pages total = %u, free = %u, p2m=%u\n",
d->arch.paging.hap.total_pages,
@@ -609,6 +611,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..43fdd48 100644
--- a/xen/arch/x86/mm/paging.c
+++ b/xen/arch/x86/mm/paging.c
@@ -799,12 +799,14 @@ 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..953cacf 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. */
{
@@ -3139,7 +3139,9 @@ void shadow_teardown(struct domain *d)
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);
@@ -3177,6 +3179,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 +3201,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
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH for-4.6] x86/mm: Make {hap, shadow}_teardown() preemptible
2015-08-05 12:36 [PATCH for-4.6] x86/mm: Make {hap, shadow}_teardown() preemptible Andrew Cooper
@ 2015-08-05 14:26 ` Tim Deegan
0 siblings, 0 replies; 2+ messages in thread
From: Tim Deegan @ 2015-08-05 14:26 UTC (permalink / raw)
To: Andrew Cooper
Cc: George Dunlap, Anshul Makkar, Wei Liu, Jan Beulich, Xen-devel
Hi,
At 13:36 +0100 on 05 Aug (1438781760), Andrew Cooper wrote:
> From: Anshul Makkar <anshul.makkar@citrix.com>
>
> 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@citrix.com>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Good catch, thanks.
> @@ -3139,7 +3139,9 @@ void shadow_teardown(struct domain *d)
> 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);
If the debug printout just above this is ever enabled, it will get
very loud since the printout will make preemption likely. Please just
delete the SHADOW_PRINTK above; you can also delete the one below if
you like. The HAP side looks like it needs the same adjustment.
With that done, Reviewed-by: Tim Deegan <tim@xen.org>
Cheers,
Tim.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-08-05 14:26 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-05 12:36 [PATCH for-4.6] x86/mm: Make {hap, shadow}_teardown() preemptible Andrew Cooper
2015-08-05 14:26 ` Tim Deegan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.