From nobody Sat Jul 12 15:22:07 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 14860197710431016.9722876514754; Wed, 1 Feb 2017 23:16:11 -0800 (PST) Received: from localhost ([::1]:54913 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cZBcm-0001Gy-Oc for importer@patchew.org; Thu, 02 Feb 2017 02:16:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53016) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cZ9kO-00086a-EV for qemu-devel@nongnu.org; Thu, 02 Feb 2017 00:15:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cZ9kF-0004PD-MI for qemu-devel@nongnu.org; Thu, 02 Feb 2017 00:15:52 -0500 Received: from ozlabs.org ([2401:3900:2:1::2]:56341) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cZ9kE-0004LI-VJ; Thu, 02 Feb 2017 00:15:43 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vDSqb4RDwz9sN7; Thu, 2 Feb 2017 16:15:02 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1486012507; bh=xEp4KJmw53GNHX/zwPZnxlqE7RoRoejrrrh0JvklfMc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YfCzjk84u6MuY7FjIElF0zvYGAhB10HuvaudbY5gjPOdFxecjGjC+LSIJ5gbWqRyf M+puodBK3XS07xcpANXteq3m5yHfl1xvu6MnwkEosr4BgR/1lf2uduTUFtPcLUMB10 xUkl8zqek3IWXHki9Q8pCvuIDwnILZeiLyeQ5Du0= From: David Gibson To: peter.maydell@linaro.org Date: Thu, 2 Feb 2017 16:14:33 +1100 Message-Id: <20170202051445.5735-96-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170202051445.5735-1-david@gibson.dropbear.id.au> References: <20170202051445.5735-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PULL 095/107] spapr: clock should count only if vm is running X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, thuth@redhat.com, qemu-devel@nongnu.org, mdroth@linux.vnet.ibm.com, agraf@suse.de, aik@ozlabs.ru, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Laurent Vivier This is a port to ppc of the i386 commit: 00f4d64 kvmclock: clock should count only if vm is running We remove timebase_post_load function, and use the VM state change handler to save and restore the guest_timebase (on stop and continue). We keep timebase_pre_save to reduce the clock difference on migration like in: 6053a86 kvmclock: reduce kvmclock difference on migration Time base offset has originally been introduced by commit 98a8b52 spapr: Add support for time base offset migration So while VM is paused, the time is stopped. This allows to have the same result with date (based on Time Base Register) and hwclock (based on "get-time-of-day" RTAS call). Moreover in TCG mode, the Time Base is always paused, so this patch also adjust the behavior between TCG and KVM. VM state field "time_of_the_day_ns" is now useless but we keep it to be able to migrate to older version of the machine. As vmstate_ppc_timebase structure (with timebase_pre_save() and timebase_post_load() functions) was only used by vmstate_spapr, we register the VM state change handler only in ppc_spapr_init(). Signed-off-by: Laurent Vivier Signed-off-by: David Gibson --- hw/ppc/ppc.c | 66 ++++++++++++++++++++++++++++++++++--------------= ---- hw/ppc/spapr.c | 6 +++++ target/ppc/cpu-qom.h | 3 +++ 3 files changed, 52 insertions(+), 23 deletions(-) diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index f9a4b51..d171e60 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -847,9 +847,8 @@ static void cpu_ppc_set_tb_clk (void *opaque, uint32_t = freq) cpu_ppc_store_purr(cpu, 0x0000000000000000ULL); } =20 -static void timebase_pre_save(void *opaque) +static void timebase_save(PPCTimebase *tb) { - PPCTimebase *tb =3D opaque; uint64_t ticks =3D cpu_get_host_ticks(); PowerPCCPU *first_ppc_cpu =3D POWERPC_CPU(first_cpu); =20 @@ -858,43 +857,30 @@ static void timebase_pre_save(void *opaque) return; } =20 + /* not used anymore, we keep it for compatibility */ tb->time_of_the_day_ns =3D qemu_clock_get_ns(QEMU_CLOCK_HOST); /* - * tb_offset is only expected to be changed by migration so + * tb_offset is only expected to be changed by QEMU so * there is no need to update it from KVM here */ tb->guest_timebase =3D ticks + first_ppc_cpu->env.tb_env->tb_offset; } =20 -static int timebase_post_load(void *opaque, int version_id) +static void timebase_load(PPCTimebase *tb) { - PPCTimebase *tb_remote =3D opaque; CPUState *cpu; PowerPCCPU *first_ppc_cpu =3D POWERPC_CPU(first_cpu); - int64_t tb_off_adj, tb_off, ns_diff; - int64_t migration_duration_ns, migration_duration_tb, guest_tb, host_n= s; + int64_t tb_off_adj, tb_off; unsigned long freq; =20 if (!first_ppc_cpu->env.tb_env) { error_report("No timebase object"); - return -1; + return; } =20 freq =3D first_ppc_cpu->env.tb_env->tb_freq; - /* - * Calculate timebase on the destination side of migration. - * The destination timebase must be not less than the source timebase. - * We try to adjust timebase by downtime if host clocks are not - * too much out of sync (1 second for now). - */ - host_ns =3D qemu_clock_get_ns(QEMU_CLOCK_HOST); - ns_diff =3D MAX(0, host_ns - tb_remote->time_of_the_day_ns); - migration_duration_ns =3D MIN(NANOSECONDS_PER_SECOND, ns_diff); - migration_duration_tb =3D muldiv64(freq, migration_duration_ns, - NANOSECONDS_PER_SECOND); - guest_tb =3D tb_remote->guest_timebase + MIN(0, migration_duration_tb); =20 - tb_off_adj =3D guest_tb - cpu_get_host_ticks(); + tb_off_adj =3D tb->guest_timebase - cpu_get_host_ticks(); =20 tb_off =3D first_ppc_cpu->env.tb_env->tb_offset; trace_ppc_tb_adjust(tb_off, tb_off_adj, tb_off_adj - tb_off, @@ -904,9 +890,44 @@ static int timebase_post_load(void *opaque, int versio= n_id) CPU_FOREACH(cpu) { PowerPCCPU *pcpu =3D POWERPC_CPU(cpu); pcpu->env.tb_env->tb_offset =3D tb_off_adj; +#if defined(CONFIG_KVM) + kvm_set_one_reg(cpu, KVM_REG_PPC_TB_OFFSET, + &pcpu->env.tb_env->tb_offset); +#endif } +} =20 - return 0; +void cpu_ppc_clock_vm_state_change(void *opaque, int running, + RunState state) +{ + PPCTimebase *tb =3D opaque; + + if (running) { + timebase_load(tb); + } else { + timebase_save(tb); + } +} + +/* + * When migrating, read the clock just before migration, + * so that the guest clock counts during the events + * between: + * + * * vm_stop() + * * + * * pre_save() + * + * This reduces clock difference on migration from 5s + * to 0.1s (when max_downtime =3D=3D 5s), because sending the + * final pages of memory (which happens between vm_stop() + * and pre_save()) takes max_downtime. + */ +static void timebase_pre_save(void *opaque) +{ + PPCTimebase *tb =3D opaque; + + timebase_save(tb); } =20 const VMStateDescription vmstate_ppc_timebase =3D { @@ -915,7 +936,6 @@ const VMStateDescription vmstate_ppc_timebase =3D { .minimum_version_id =3D 1, .minimum_version_id_old =3D 1, .pre_save =3D timebase_pre_save, - .post_load =3D timebase_post_load, .fields =3D (VMStateField []) { VMSTATE_UINT64(guest_timebase, PPCTimebase), VMSTATE_INT64(time_of_the_day_ns, PPCTimebase), diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index b71cd7a..9fc3fb9 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2129,6 +2129,12 @@ static void ppc_spapr_init(MachineState *machine) qemu_register_reset(spapr_ccs_reset_hook, spapr); =20 qemu_register_boot_set(spapr_boot_set, spapr); + + /* to stop and start vmclock */ + if (kvm_enabled()) { + qemu_add_vm_change_state_handler(cpu_ppc_clock_vm_state_change, + &spapr->tb); + } } =20 static int spapr_kvm_type(const char *vm_type) diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h index d46c31a..b7977ba 100644 --- a/target/ppc/cpu-qom.h +++ b/target/ppc/cpu-qom.h @@ -214,6 +214,9 @@ extern const struct VMStateDescription vmstate_ppc_time= base; .flags =3D VMS_STRUCT, \ .offset =3D vmstate_offset_value(_state, _field, PPCTimebase), \ } + +void cpu_ppc_clock_vm_state_change(void *opaque, int running, + RunState state); #endif =20 #endif --=20 2.9.3