[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] x86/suspend: unconditionally raise a timer softirq on resume



On Mon, Aug 25, 2025 at 05:15:15PM +0200, Roger Pau Monne wrote:
> The current code to restore the timer state on resume is incomplete.  While
> the local APIC Initial Count Register is saved and restored across
> suspension (even if possibly no longer accurate since it's not adjusted to
> account for the time spent in suspension), the TSC deadline MSR is not
> saved and restored, hence hosts using the TSC deadline timer will likely
> get stuck when resuming from suspension.
> 
> The lack of restoring of the TSC deadline MSR was mitigated by the raising
> of a timer softirq in mwait_idle_with_hints() if the timer had expired,
> previous to commit 3faf0866a33070b926ab78e6298290403f85e76c, which removed
> that logic.
> 
> This patch fixes the usage of the TSC deadline timer with suspension, by
> unconditionally raising a timer softirq on resume, that will take care of
> rearming the hardware timer.  Given that a timer softirq will be
> unconditionally risen, there's no need to save and restore the APIC Initial
> Count Register anymore either.
> 
> Note that secondary processors don't need this special treatment when
> resuming, since they are offlined before suspension and brought back up
> during resume, the first timer that gets setup will trigger a timer softirq
> unconditionally, for example from sched_migrate_timers() that gets called
> for each secondary processor.
> 
> Reported-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
> Fixes: fd1291a826e1 ('X86: Prefer TSC-deadline timer in Xen')
> Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>

Tested-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>

> ---
>  xen/arch/x86/acpi/power.c | 2 ++
>  xen/arch/x86/apic.c       | 3 ---
>  2 files changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c
> index 2ac162c997fe..27d672ad5dbb 100644
> --- a/xen/arch/x86/acpi/power.c
> +++ b/xen/arch/x86/acpi/power.c
> @@ -19,6 +19,7 @@
>  #include <xen/iommu.h>
>  #include <xen/param.h>
>  #include <xen/sched.h>
> +#include <xen/softirq.h>
>  #include <xen/spinlock.h>
>  #include <xen/watchdog.h>
>  
> @@ -310,6 +311,7 @@ static int enter_state(u32 state)
>      thaw_domains();
>      system_state = SYS_STATE_active;
>      spin_unlock(&pm_lock);
> +    raise_softirq(TIMER_SOFTIRQ);
>      return error;
>  }
>  
> diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c
> index cac5ba39e615..e3a2b84f1aae 100644
> --- a/xen/arch/x86/apic.c
> +++ b/xen/arch/x86/apic.c
> @@ -65,7 +65,6 @@ static struct {
>      unsigned int apic_lvt0;
>      unsigned int apic_lvt1;
>      unsigned int apic_lvterr;
> -    unsigned int apic_tmict;
>      unsigned int apic_tdcr;
>      unsigned int apic_thmr;
>  } apic_pm_state;
> @@ -658,7 +657,6 @@ int lapic_suspend(void)
>      apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0);
>      apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1);
>      apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);
> -    apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
>      apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
>      if (maxlvt >= 5)
>          apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
> @@ -718,7 +716,6 @@ int lapic_resume(void)
>          apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
>      apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
>      apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);
> -    apic_write(APIC_TMICT, apic_pm_state.apic_tmict);
>      apic_write(APIC_ESR, 0);
>      apic_read(APIC_ESR);
>      apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr);
> -- 
> 2.49.0
> 

-- 
Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab

Attachment: signature.asc
Description: PGP signature


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.