[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH for-2.5 7/8] s390x: Migrate guest storage keys (
From: |
Thomas Huth |
Subject: |
Re: [Qemu-devel] [PATCH for-2.5 7/8] s390x: Migrate guest storage keys (initial memory only) |
Date: |
Tue, 21 Jul 2015 10:08:43 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 |
On 20/07/15 15:49, Cornelia Huck wrote:
> From: "Jason J. Herne" <address@hidden>
>
> Routines to save/load guest storage keys are provided. register_savevm is
> called to register them as migration handlers.
>
> We prepare the protocol to support more complex parameters. So we will
> later be able to support standby memory (having empty holes), compression
> and "state live migration" like done for ram.
>
> Reviewed-by: David Hildenbrand <address@hidden>
> Signed-off-by: Jason J. Herne <address@hidden>
> Signed-off-by: Cornelia Huck <address@hidden>
> ---
> hw/s390x/s390-skeys.c | 113
> ++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 113 insertions(+)
>
> diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
> index d355c8f..a927c98 100644
> --- a/hw/s390x/s390-skeys.c
> +++ b/hw/s390x/s390-skeys.c
> @@ -11,10 +11,13 @@
>
> #include "hw/boards.h"
> #include "qmp-commands.h"
> +#include "migration/qemu-file.h"
> #include "hw/s390x/storage-keys.h"
> #include "qemu/error-report.h"
>
> #define S390_SKEYS_BUFFER_SIZE 131072 /* Room for 128k storage keys */
> +#define S390_SKEYS_SAVE_FLAG_EOS 0x01
> +#define S390_SKEYS_SAVE_FLAG_SKEYS 0x02
>
> S390SKeysState *s390_get_skeys_device(void)
> {
> @@ -241,6 +244,115 @@ static const TypeInfo qemu_s390_skeys_info = {
> .instance_size = sizeof(S390SKeysClass),
> };
>
> +static void s390_storage_keys_save(QEMUFile *f, void *opaque)
> +{
> + S390SKeysState *ss = S390_SKEYS(opaque);
> + S390SKeysClass *skeyclass = S390_SKEYS_GET_CLASS(ss);
> + const uint64_t total_count = ram_size / TARGET_PAGE_SIZE;
> + uint64_t cur_count, handled_count = 0;
> + vaddr cur_gfn = 0;
> + uint8_t *buf;
> + int ret;
> +
> + if (!skeyclass->skeys_enabled(ss)) {
> + goto end_stream;
> + }
> +
> + buf = g_try_malloc(S390_SKEYS_BUFFER_SIZE);
> + if (!buf) {
> + error_report("storage key save could not allocate memory\n");
> + goto end_stream;
> + }
> +
> + /* We only support initital memory. Standby memory is not handled yet. */
> + qemu_put_be64(f, (cur_gfn * TARGET_PAGE_SIZE) |
> + S390_SKEYS_SAVE_FLAG_SKEYS);
> + qemu_put_be64(f, total_count);
So if I've got this code right, you send here a "header" that announces
a packet with all pages ...
> + while (handled_count < total_count) {
> + cur_count = MIN(total_count - handled_count, S390_SKEYS_BUFFER_SIZE);
> +
> + ret = skeyclass->get_skeys(ss, cur_gfn, cur_count, buf);
> + if (ret < 0) {
> + error_report("S390_GET_KEYS error %d\n", ret);
> + break;
... but when an error occurs here, you suddenly stop in the middle of
that "packet" with all pages ...
> + }
> +
> + /* write keys to stream */
> + qemu_put_buffer(f, buf, cur_count);
> +
> + cur_gfn += cur_count;
> + handled_count += cur_count;
> + }
> +
> + g_free(buf);
> +end_stream:
> + qemu_put_be64(f, S390_SKEYS_SAVE_FLAG_EOS);
... and send an EOS marker here instead ...
> +}
> +
> +static int s390_storage_keys_load(QEMUFile *f, void *opaque, int version_id)
> +{
> + S390SKeysState *ss = S390_SKEYS(opaque);
> + S390SKeysClass *skeyclass = S390_SKEYS_GET_CLASS(ss);
> + int ret = 0;
> +
> + while (!ret) {
> + ram_addr_t addr;
> + int flags;
> +
> + addr = qemu_get_be64(f);
> + flags = addr & ~TARGET_PAGE_MASK;
> + addr &= TARGET_PAGE_MASK;
> +
> + switch (flags) {
> + case S390_SKEYS_SAVE_FLAG_SKEYS: {
> + const uint64_t total_count = qemu_get_be64(f);
> + uint64_t handled_count = 0, cur_count;
> + uint64_t cur_gfn = addr / TARGET_PAGE_SIZE;
> + uint8_t *buf = g_try_malloc(S390_SKEYS_BUFFER_SIZE);
> +
> + if (!buf) {
> + error_report("storage key load could not allocate memory\n");
> + ret = -ENOMEM;
> + break;
> + }
> +
> + while (handled_count < total_count) {
> + cur_count = MIN(total_count - handled_count,
> + S390_SKEYS_BUFFER_SIZE);
> + qemu_get_buffer(f, buf, cur_count);
... while the receiver can not handle the EOS marker here.
This looks fishy to me (or I might have just missed something), but
anyway please double check whether your error handling in the sender
really makes sense.
> + ret = skeyclass->set_skeys(ss, cur_gfn, cur_count, buf);
> + if (ret < 0) {
> + error_report("S390_SET_KEYS error %d\n", ret);
> + break;
> + }
> + handled_count += cur_count;
> + cur_gfn += cur_count;
> + }
> + g_free(buf);
> + break;
> + }
> + case S390_SKEYS_SAVE_FLAG_EOS:
> + /* normal exit */
> + return 0;
> + default:
> + error_report("Unexpected storage key flag data: %#x", flags);
> + ret = -EINVAL;
> + }
> + }
> +
> + return ret;
> +}
Thomas
signature.asc
Description: OpenPGP digital signature
[Qemu-devel] [PATCH for-2.5 6/8] s390x: Info skeys sub-command, Cornelia Huck, 2015/07/20
[Qemu-devel] [PATCH for-2.5 8/8] s390x: Disable storage key migration on old machine type, Cornelia Huck, 2015/07/20
[Qemu-devel] [PATCH for-2.5 2/8] s390x: Create QOM device for s390 storage keys, Cornelia Huck, 2015/07/20
[Qemu-devel] [PATCH for-2.5 4/8] s390x: Dump storage keys qmp command, Cornelia Huck, 2015/07/20