From: Juergen Gross <jgross@suse.com>
To: Andrew Cooper <andrew.cooper3@citrix.com>,
xen-devel@lists.xen.org, Ian.Campbell@citrix.com,
ian.jackson@eu.citrix.com, stefano.stabellini@eu.citrix.com,
wei.liu2@citrix.com
Subject: Re: [PATCH 3/4] libxc: stop migration in case of p2m list structural changes
Date: Fri, 11 Dec 2015 17:02:19 +0100 [thread overview]
Message-ID: <566AF38B.9070708@suse.com> (raw)
In-Reply-To: <566AE9BD.9090805@citrix.com>
On 11/12/15 16:20, Andrew Cooper wrote:
> On 11/12/15 11:31, Juergen Gross wrote:
>> With support of the virtual mapped linear p2m list for migration it is
>> now possible to detect structural changes of the p2m list which before
>> would either lead to a crashing or otherwise wrong behaving domU.
>>
>> A guest supporting the linear p2m list will increment the
>> p2m_generation counter located in the shared info page before and after
>> each modification of a mapping related to the p2m list. A change of
>> that counter can be detected by the tools and reacted upon.
>>
>> As such a change should occur only very rarely once the domU is up the
>> most simple reaction is to cancel migration in such an event.
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
>> ---
>> tools/libxc/xc_sr_common.h | 11 ++++++++++
>> tools/libxc/xc_sr_save.c | 4 ++++
>> tools/libxc/xc_sr_save_x86_hvm.c | 7 +++++++
>> tools/libxc/xc_sr_save_x86_pv.c | 44 ++++++++++++++++++++++++++++++++++++++++
>> 4 files changed, 66 insertions(+)
>>
>> diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
>> index 9aecde2..bfb9602 100644
>> --- a/tools/libxc/xc_sr_common.h
>> +++ b/tools/libxc/xc_sr_common.h
>> @@ -83,6 +83,14 @@ struct xc_sr_save_ops
>> int (*end_of_checkpoint)(struct xc_sr_context *ctx);
>>
>> /**
>> + * Check whether new iteration can be started. This is called before each
>> + * iteration to check whether all criteria for the migration are still
>> + * met. If that's not the case either migration is cancelled via a bad rc
>> + * or the situation is handled, e.g. by sending appropriate records.
>> + */
>> + int (*check_iteration)(struct xc_sr_context *ctx);
>> +
>
> This is slightly ambiguous, especially with the not-so-different
> differences between live migration and remus checkpoints.
>
> I would be tempted to name it check_vm_state() and document simply that
> it is called periodically, to allow for fixup (or abort) for guest state
> which may have changed while the VM was running.
Yes, this is better.
> On the remus side, it needs to be called between start_of_checkpoint()
> and send_memory_***() in save(), as the guest gets to run between the
> checkpoints.
Okay.
>
>> + /**
>> * Clean up the local environment. Will be called exactly once, either
>> * after a successful save, or upon encountering an error.
>> */
>> @@ -280,6 +288,9 @@ struct xc_sr_context
>> /* Read-only mapping of guests shared info page */
>> shared_info_any_t *shinfo;
>>
>> + /* p2m generation count for verifying validity of local p2m. */
>> + uint64_t p2m_generation;
>> +
>> union
>> {
>> struct
>> diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
>> index cefcef5..c235706 100644
>> --- a/tools/libxc/xc_sr_save.c
>> +++ b/tools/libxc/xc_sr_save.c
>> @@ -370,6 +370,10 @@ static int send_dirty_pages(struct xc_sr_context *ctx,
>> DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap,
>> &ctx->save.dirty_bitmap_hbuf);
>>
>> + rc = ctx->save.ops.check_iteration(ctx);
>> + if ( rc )
>> + return rc;
>> +
>
> As there is now a call at each start of checkpoint, this call
> essentially becomes back-to-back. I would suggest having it after the
> batch, rather than ahead.
Okay.
>
>> for ( p = 0, written = 0; p < ctx->save.p2m_size; ++p )
>> {
>> if ( !test_bit(p, dirty_bitmap) )
>> diff --git a/tools/libxc/xc_sr_save_x86_hvm.c b/tools/libxc/xc_sr_save_x86_hvm.c
>> index f3d6cee..aa24f90 100644
>> --- a/tools/libxc/xc_sr_save_x86_hvm.c
>> +++ b/tools/libxc/xc_sr_save_x86_hvm.c
>> @@ -175,6 +175,12 @@ static int x86_hvm_start_of_checkpoint(struct xc_sr_context *ctx)
>> return 0;
>> }
>>
>> +static int x86_hvm_check_iteration(struct xc_sr_context *ctx)
>> +{
>> + /* no-op */
>> + return 0;
>> +}
>> +
>> static int x86_hvm_end_of_checkpoint(struct xc_sr_context *ctx)
>> {
>> int rc;
>> @@ -221,6 +227,7 @@ struct xc_sr_save_ops save_ops_x86_hvm =
>> .start_of_stream = x86_hvm_start_of_stream,
>> .start_of_checkpoint = x86_hvm_start_of_checkpoint,
>> .end_of_checkpoint = x86_hvm_end_of_checkpoint,
>> + .check_iteration = x86_hvm_check_iteration,
>> .cleanup = x86_hvm_cleanup,
>> };
>>
>> diff --git a/tools/libxc/xc_sr_save_x86_pv.c b/tools/libxc/xc_sr_save_x86_pv.c
>> index 0237378..3a58d0d 100644
>> --- a/tools/libxc/xc_sr_save_x86_pv.c
>> +++ b/tools/libxc/xc_sr_save_x86_pv.c
>> @@ -268,6 +268,39 @@ err:
>> }
>>
>> /*
>> + * Get p2m_generation count.
>> + * Returns an error if the generation count has changed since the last call.
>> + */
>> +static int get_p2m_generation(struct xc_sr_context *ctx)
>> +{
>> + uint64_t p2m_generation;
>> + int rc;
>> +
>> + p2m_generation = GET_FIELD(ctx->x86_pv.shinfo, arch.p2m_generation,
>> + ctx->x86_pv.width);
>> +
>> + rc = (p2m_generation == ctx->x86_pv.p2m_generation) ? 0 : -1;
>> + ctx->x86_pv.p2m_generation = p2m_generation;
>> +
>> + return rc;
>> +}
>> +
>> +static int x86_pv_check_iteration_p2m_list(struct xc_sr_context *ctx)
>> +{
>> + xc_interface *xch = ctx->xch;
>> + int rc;
>> +
>> + if ( !ctx->save.live )
>> + return 0;
>> +
>> + rc = get_p2m_generation(ctx);
>> + if ( rc )
>> + ERROR("p2m generation count changed. Migration aborted.");
>> +
>> + return rc;
>> +}
>> +
>> +/*
>> * Map the guest p2m frames specified via a cr3 value, a virtual address, and
>> * the maximum pfn.
>> */
>> @@ -281,6 +314,9 @@ static int map_p2m_list(struct xc_sr_context *ctx, uint64_t p2m_cr3)
>> unsigned fpp, n_pages, level, shift, idx_start, idx_end, idx, saved_idx;
>> int rc = -1;
>>
>> + /* Before each iteration check for local p2m list still valid. */
>> + ctx->save.ops.check_iteration = x86_pv_check_iteration_p2m_list;
>> +
>
> This is admittedly the first, but definitely not the only eventual thing
> needed for check iteration. To avoid clobbering one check with another
> in the future, it would be cleaner to have a single
> x86_pv_check_iteration() which performs the get_p2m_generation() check
> iff linear p2m is in use.
Agreed.
Juergen
next prev parent reply other threads:[~2015-12-11 16:02 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-11 11:31 [PATCH 0/4] support linear p2m list in migrate stream v2 Juergen Gross
2015-12-11 11:31 ` [PATCH 1/4] libxc: split mapping p2m leaves into a separate function Juergen Gross
2015-12-11 14:21 ` Andrew Cooper
2015-12-11 11:31 ` [PATCH 2/4] libxc: support of linear p2m list for migration of pv-domains Juergen Gross
2015-12-11 14:51 ` Andrew Cooper
2015-12-11 15:12 ` Juergen Gross
2015-12-11 15:24 ` Andrew Cooper
2015-12-11 16:00 ` Juergen Gross
2015-12-11 16:09 ` Andrew Cooper
2015-12-11 16:17 ` Juergen Gross
2015-12-11 11:31 ` [PATCH 3/4] libxc: stop migration in case of p2m list structural changes Juergen Gross
2015-12-11 15:20 ` Andrew Cooper
2015-12-11 16:02 ` Juergen Gross [this message]
2015-12-11 11:31 ` [PATCH 4/4] libxc: set flag for support of linear p2m list in domain builder Juergen Gross
2015-12-11 14:18 ` [PATCH 0/4] support linear p2m list in migrate stream v2 Andrew Cooper
2015-12-11 14:20 ` Juergen Gross
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=566AF38B.9070708@suse.com \
--to=jgross@suse.com \
--cc=Ian.Campbell@citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=ian.jackson@eu.citrix.com \
--cc=stefano.stabellini@eu.citrix.com \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.