[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH V5 2/3] x86/mm: allocate logdirty_ranges for altp2ms
This patch is a pre-requisite for the one fixing VGA logdirty freezes when using altp2m. It only concerns itself with the ranges allocation / deallocation / initialization part. While touching the code, I've switched global_logdirty from bool_t to bool. Signed-off-by: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx> --- CC: George Dunlap <george.dunlap@xxxxxxxxxxxxx> CC: Jan Beulich <jbeulich@xxxxxxxx> CC: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CC: Wei Liu <wei.liu2@xxxxxxxxxx> --- Changes since V4: - Always call p2m_free_logdirty() in p2m_free_one() (previously the call was gated on hap_enabled(p2m->domain) && cpu_has_vmx). --- xen/arch/x86/mm/p2m.c | 74 ++++++++++++++++++++++++++++++++++++----------- xen/include/asm-x86/p2m.h | 2 +- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 42b9ef4..69536c1 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -59,6 +59,28 @@ static void p2m_nestedp2m_init(struct p2m_domain *p2m) #endif } +static int p2m_init_logdirty(struct p2m_domain *p2m) +{ + if ( p2m->logdirty_ranges ) + return 0; + + p2m->logdirty_ranges = rangeset_new(p2m->domain, "log-dirty", + RANGESETF_prettyprint_hex); + if ( !p2m->logdirty_ranges ) + return -ENOMEM; + + return 0; +} + +static void p2m_free_logdirty(struct p2m_domain *p2m) +{ + if ( !p2m->logdirty_ranges ) + return; + + rangeset_destroy(p2m->logdirty_ranges); + p2m->logdirty_ranges = NULL; +} + /* Init the datastructures for later use by the p2m code */ static int p2m_initialise(struct domain *d, struct p2m_domain *p2m) { @@ -107,6 +129,7 @@ free_p2m: static void p2m_free_one(struct p2m_domain *p2m) { + p2m_free_logdirty(p2m); if ( hap_enabled(p2m->domain) && cpu_has_vmx ) ept_p2m_uninit(p2m); free_cpumask_var(p2m->dirty_cpumask); @@ -116,19 +139,19 @@ static void p2m_free_one(struct p2m_domain *p2m) static int p2m_init_hostp2m(struct domain *d) { struct p2m_domain *p2m = p2m_init_one(d); + int rc; - if ( p2m ) - { - p2m->logdirty_ranges = rangeset_new(d, "log-dirty", - RANGESETF_prettyprint_hex); - if ( p2m->logdirty_ranges ) - { - d->arch.p2m = p2m; - return 0; - } + if ( !p2m ) + return -ENOMEM; + + rc = p2m_init_logdirty(p2m); + + if ( !rc ) + d->arch.p2m = p2m; + else p2m_free_one(p2m); - } - return -ENOMEM; + + return rc; } static void p2m_teardown_hostp2m(struct domain *d) @@ -138,7 +161,6 @@ static void p2m_teardown_hostp2m(struct domain *d) if ( p2m ) { - rangeset_destroy(p2m->logdirty_ranges); p2m_free_one(p2m); d->arch.p2m = NULL; } @@ -2279,6 +2301,18 @@ void p2m_flush_altp2m(struct domain *d) altp2m_list_unlock(d); } +static int p2m_init_altp2m_logdirty(struct p2m_domain *p2m) +{ + struct p2m_domain *hostp2m = p2m_get_hostp2m(p2m->domain); + int rc = p2m_init_logdirty(p2m); + + if ( rc ) + return rc; + + /* The following is really just a rangeset copy. */ + return rangeset_merge(p2m->logdirty_ranges, hostp2m->logdirty_ranges); +} + int p2m_init_altp2m_by_id(struct domain *d, unsigned int idx) { int rc = -EINVAL; @@ -2290,8 +2324,9 @@ int p2m_init_altp2m_by_id(struct domain *d, unsigned int idx) if ( d->arch.altp2m_eptp[idx] == mfn_x(INVALID_MFN) ) { - p2m_init_altp2m_ept(d, idx); - rc = 0; + rc = p2m_init_altp2m_logdirty(d->arch.altp2m_p2m[idx]); + if ( !rc ) + p2m_init_altp2m_ept(d, idx); } altp2m_list_unlock(d); @@ -2310,9 +2345,13 @@ int p2m_init_next_altp2m(struct domain *d, uint16_t *idx) if ( d->arch.altp2m_eptp[i] != mfn_x(INVALID_MFN) ) continue; - p2m_init_altp2m_ept(d, i); - *idx = i; - rc = 0; + rc = p2m_init_altp2m_logdirty(d->arch.altp2m_p2m[i]); + + if ( !rc ) + { + p2m_init_altp2m_ept(d, i); + *idx = i; + } break; } @@ -2341,6 +2380,7 @@ int p2m_destroy_altp2m_by_id(struct domain *d, unsigned int idx) { p2m_flush_table(d->arch.altp2m_p2m[idx]); /* Uninit and reinit ept to force TLB shootdown */ + p2m_free_logdirty(d->arch.altp2m_p2m[idx]); ept_p2m_uninit(d->arch.altp2m_p2m[idx]); ept_p2m_init(d->arch.altp2m_p2m[idx]); d->arch.altp2m_eptp[idx] = mfn_x(INVALID_MFN); diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h index ac33f50..c7f5710 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -222,7 +222,7 @@ struct p2m_domain { struct rangeset *logdirty_ranges; /* Host p2m: Global log-dirty mode enabled for the domain. */ - bool_t global_logdirty; + bool global_logdirty; /* Host p2m: when this flag is set, don't flush all the nested-p2m * tables on every host-p2m change. The setter of this flag -- 2.7.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |