diff mbox series

How can a userspace program tell if the system supports the ACPI S4 state (Suspend-to-Disk)?

Message ID MWHPR21MB0863BA3D689DDEC3CA6BC262BFC91@MWHPR21MB0863.namprd21.prod.outlook.com
State New
Headers show
Series How can a userspace program tell if the system supports the ACPI S4 state (Suspend-to-Disk)? | expand

Commit Message

Dexuan Cui Dec. 12, 2020, 1:20 a.m. UTC
Hi all,
It looks like Linux can hibernate even if the system does not support the ACPI
S4 state, as long as the system can shut down, so "cat /sys/power/state"
always contains "disk", unless we specify the kernel parameter "nohibernate"
or we use LOCKDOWN_HIBERNATION.

In some scenarios IMO it can still be useful if the userspace is able to detect
if the ACPI S4 state is supported or not, e.g. when a Linux guest runs on 
Hyper-V, Hyper-V uses the virtual ACPI S4 state as an indicator of the proper
support of the tool stack on the host, i.e. the guest is discouraged from 
trying hibernation if the state is not supported.

I know we can check the S4 state by 'dmesg':

# dmesg |grep ACPI: | grep support
[    3.034134] ACPI: (supports S0 S4 S5)

But this method is unreliable because the kernel msg buffer can be filled
and overwritten. Is there any better method? If not, do you think if the
below patch is appropriate? Thanks!


Thanks,
-- Dexuan

Comments

Pavel Machek Dec. 21, 2020, 7:07 p.m. UTC | #1
On Sat 2020-12-12 01:20:30, Dexuan Cui wrote:
> Hi all,

> It looks like Linux can hibernate even if the system does not support the ACPI

> S4 state, as long as the system can shut down, so "cat /sys/power/state"

> always contains "disk", unless we specify the kernel parameter "nohibernate"

> or we use LOCKDOWN_HIBERNATION.

> 

> In some scenarios IMO it can still be useful if the userspace is able to detect

> if the ACPI S4 state is supported or not, e.g. when a Linux guest runs on 

> Hyper-V, Hyper-V uses the virtual ACPI S4 state as an indicator of the proper

> support of the tool stack on the host, i.e. the guest is discouraged from 

> trying hibernation if the state is not supported.


Umm. Does not sound like exactly strong reason to me.

If ACPI S4 is special to the hypervisor, perhaps that should be
reported to userspace...?

> I know we can check the S4 state by 'dmesg':

> 

> # dmesg |grep ACPI: | grep support

> [    3.034134] ACPI: (supports S0 S4 S5)

> 

> But this method is unreliable because the kernel msg buffer can be filled

> and overwritten. Is there any better method? If not, do you think if the

> below patch is appropriate? Thanks!



> @@ -600,8 +601,12 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,

>                         s += sprintf(s,"%s ", pm_states[i]);

> 

>  #endif

> -       if (hibernation_available())

> -               s += sprintf(s, "disk ");

> +       if (hibernation_available()) {

> +               if (acpi_sleep_state_supported(ACPI_STATE_S4))

> +                       s += sprintf(s, "disk+ ");

> +               else

> +                       s += sprintf(s, "disk ");

> +       }

>         if (s != buf)


Will this compile on all the systems?

Certainly needs documentation.

Plus if ACPI S4 is supported, kernel can support both normal
hibernation and ACPI S4... so perhaps it should list two entries? And
"disk+" sounds wrong, "acpidisk"?

...and that would bring next question. Usespace writes "disk" there
and uses different file to select between S4 and S5...

								Pavel
-- 
http://www.livejournal.com/~pavelmachek
Dexuan Cui Dec. 23, 2020, 9:04 p.m. UTC | #2
> From: Pavel Machek <pavel@ucw.cz>

> Sent: Monday, December 21, 2020 11:08 AM

> 

> On Sat 2020-12-12 01:20:30, Dexuan Cui wrote:

> > Hi all,

> > It looks like Linux can hibernate even if the system does not support the ACPI

> > S4 state, as long as the system can shut down, so "cat /sys/power/state"

> > always contains "disk", unless we specify the kernel parameter "nohibernate"

> > or we use LOCKDOWN_HIBERNATION.

> >

> > In some scenarios IMO it can still be useful if the userspace is able to detect

> > if the ACPI S4 state is supported or not, e.g. when a Linux guest runs on

> > Hyper-V, Hyper-V uses the virtual ACPI S4 state as an indicator of the proper

> > support of the tool stack on the host, i.e. the guest is discouraged from

> > trying hibernation if the state is not supported.

> 

> Umm. Does not sound like exactly strong reason to me.


Hi Pavel,
Thanks for the reply. I realized that it may be better for me to add the code
to Hyper-V specific driver: https://lkml.org/lkml/2020/12/22/719

Let's see how it goes that way. :-)

Thanks,
Dexuan
Rafael J. Wysocki Feb. 5, 2021, 1:05 p.m. UTC | #3
On Sat, Dec 12, 2020 at 2:22 AM Dexuan Cui <decui@microsoft.com> wrote:
>

> Hi all,

> It looks like Linux can hibernate even if the system does not support the ACPI

> S4 state, as long as the system can shut down, so "cat /sys/power/state"

> always contains "disk", unless we specify the kernel parameter "nohibernate"

> or we use LOCKDOWN_HIBERNATION.

>

> In some scenarios IMO it can still be useful if the userspace is able to detect

> if the ACPI S4 state is supported or not, e.g. when a Linux guest runs on

> Hyper-V, Hyper-V uses the virtual ACPI S4 state as an indicator of the proper

> support of the tool stack on the host, i.e. the guest is discouraged from

> trying hibernation if the state is not supported.

>

> I know we can check the S4 state by 'dmesg':

>

> # dmesg |grep ACPI: | grep support

> [    3.034134] ACPI: (supports S0 S4 S5)

>

> But this method is unreliable because the kernel msg buffer can be filled

> and overwritten. Is there any better method? If not, do you think if the

> below patch is appropriate? Thanks!


Sorry for the delay.

If ACPI S4 is supported, /sys/power/disk will list "platform" as one
of the options (and it will be the default one then).  Otherwise,
"platform" is not present in /sys/power/disk, because ACPI is the only
user of hibernation_ops.

HTH
Dexuan Cui Feb. 5, 2021, 7:36 p.m. UTC | #4
> From: Rafael J. Wysocki <rafael@kernel.org>

> Sent: Friday, February 5, 2021 5:06 AM

> To: Dexuan Cui <decui@microsoft.com>

> Cc: linux-acpi@vger.kernel.org; linux-kernel@vger.kernel.org;

> linux-hyperv@vger.kernel.org; Michael Kelley <mikelley@microsoft.com>

> Subject: Re: How can a userspace program tell if the system supports the ACPI

> S4 state (Suspend-to-Disk)?

> 

> On Sat, Dec 12, 2020 at 2:22 AM Dexuan Cui <decui@microsoft.com> wrote:

> >

> > Hi all,

> > It looks like Linux can hibernate even if the system does not support the ACPI

> > S4 state, as long as the system can shut down, so "cat /sys/power/state"

> > always contains "disk", unless we specify the kernel parameter "nohibernate"

> > or we use LOCKDOWN_HIBERNATION.

> >

> > In some scenarios IMO it can still be useful if the userspace is able to detect

> > if the ACPI S4 state is supported or not, e.g. when a Linux guest runs on

> > Hyper-V, Hyper-V uses the virtual ACPI S4 state as an indicator of the proper

> > support of the tool stack on the host, i.e. the guest is discouraged from

> > trying hibernation if the state is not supported.

> >

> > I know we can check the S4 state by 'dmesg':

> >

> > # dmesg |grep ACPI: | grep support

> > [    3.034134] ACPI: (supports S0 S4 S5)

> >

> > But this method is unreliable because the kernel msg buffer can be filled

> > and overwritten. Is there any better method? If not, do you think if the

> > below patch is appropriate? Thanks!

> 

> Sorry for the delay.

> 

> If ACPI S4 is supported, /sys/power/disk will list "platform" as one

> of the options (and it will be the default one then).  Otherwise,

> "platform" is not present in /sys/power/disk, because ACPI is the only

> user of hibernation_ops.

> 

> HTH


This works on x86. Thanks a lot!

BTW, does this also work on ARM64?

Thanks,
-- Dexuan
James Morse Feb. 9, 2021, 6:15 p.m. UTC | #5
Hi Dexuan,

On 05/02/2021 19:36, Dexuan Cui wrote:
>> From: Rafael J. Wysocki <rafael@kernel.org>

>> Sent: Friday, February 5, 2021 5:06 AM

>> To: Dexuan Cui <decui@microsoft.com>

>> Cc: linux-acpi@vger.kernel.org; linux-kernel@vger.kernel.org;

>> linux-hyperv@vger.kernel.org; Michael Kelley <mikelley@microsoft.com>

>> Subject: Re: How can a userspace program tell if the system supports the ACPI

>> S4 state (Suspend-to-Disk)?

>>

>> On Sat, Dec 12, 2020 at 2:22 AM Dexuan Cui <decui@microsoft.com> wrote:

>>>

>>> Hi all,

>>> It looks like Linux can hibernate even if the system does not support the ACPI

>>> S4 state, as long as the system can shut down, so "cat /sys/power/state"

>>> always contains "disk", unless we specify the kernel parameter "nohibernate"

>>> or we use LOCKDOWN_HIBERNATION.


>>> In some scenarios IMO it can still be useful if the userspace is able to detect

>>> if the ACPI S4 state is supported or not, e.g. when a Linux guest runs on

>>> Hyper-V, Hyper-V uses the virtual ACPI S4 state as an indicator of the proper

>>> support of the tool stack on the host, i.e. the guest is discouraged from

>>> trying hibernation if the state is not supported.


What goes wrong? This sounds like a funny way of signalling hypervisor policy.


>>> I know we can check the S4 state by 'dmesg':

>>>

>>> # dmesg |grep ACPI: | grep support

>>> [    3.034134] ACPI: (supports S0 S4 S5)

>>>

>>> But this method is unreliable because the kernel msg buffer can be filled

>>> and overwritten. Is there any better method? If not, do you think if the

>>> below patch is appropriate? Thanks!

>>

>> Sorry for the delay.

>>

>> If ACPI S4 is supported, /sys/power/disk will list "platform" as one

>> of the options (and it will be the default one then).  Otherwise,

>> "platform" is not present in /sys/power/disk, because ACPI is the only

>> user of hibernation_ops.


> This works on x86. Thanks a lot!

> 

> BTW, does this also work on ARM64?


Not today. The S4/S5 stuff is part of 'ACPI_SYSTEM_POWER_STATES_SUPPORT', which arm64
doesn't enable as it has a firmware mechanism that covers this on both DT and ACPI
systems. That code is what calls hibernation_set_ops() to enable ACPI's platform mode.

Regardless: hibernate works fine. What does your hypervisor do that causes problems?
(I think all we expect from firmware is it doesn't randomise the placement of the ACPI
tables as they aren't necessarily part of the hibernate image)


Thanks,

James
Dexuan Cui Feb. 10, 2021, 7 a.m. UTC | #6
> From: James Morse <james.morse@arm.com>

> Sent: Tuesday, February 9, 2021 10:15 AM

> To: Dexuan Cui <decui@microsoft.com>

> Cc: Rafael J. Wysocki <rafael@kernel.org>; linux-acpi@vger.kernel.org;

> linux-kernel@vger.kernel.org; linux-hyperv@vger.kernel.org; Michael Kelley

> <mikelley@microsoft.com>; Leandro Pereira <Leandro.Pereira@microsoft.com>

> Subject: Re: How can a userspace program tell if the system supports the ACPI

> S4 state (Suspend-to-Disk)?

> 

> Hi Dexuan,

> 

> On 05/02/2021 19:36, Dexuan Cui wrote:

> >> From: Rafael J. Wysocki <rafael@kernel.org>

> >> Sent: Friday, February 5, 2021 5:06 AM

> >> To: Dexuan Cui <decui@microsoft.com>

> >> Cc: linux-acpi@vger.kernel.org; linux-kernel@vger.kernel.org;

> >> linux-hyperv@vger.kernel.org; Michael Kelley <mikelley@microsoft.com>

> >> Subject: Re: How can a userspace program tell if the system supports the

> ACPI

> >> S4 state (Suspend-to-Disk)?

> >>

> >> On Sat, Dec 12, 2020 at 2:22 AM Dexuan Cui <decui@microsoft.com> wrote:

> >>>

> >>> Hi all,

> >>> It looks like Linux can hibernate even if the system does not support the

> ACPI

> >>> S4 state, as long as the system can shut down, so "cat /sys/power/state"

> >>> always contains "disk", unless we specify the kernel parameter

> "nohibernate"

> >>> or we use LOCKDOWN_HIBERNATION.

> 

> >>> In some scenarios IMO it can still be useful if the userspace is able to

> >>> detect if the ACPI S4 state is supported or not, e.g. when a Linux guest

> >>> runs on Hyper-V, Hyper-V uses the virtual ACPI S4 state as an indicator

> >>> of the proper support of the tool stack on the host, i.e. the guest is

> >>> discouraged from trying hibernation if the state is not supported.

> 

> What goes wrong? This sounds like a funny way of signalling hypervisor policy.


Hi James,
Sorry if I have caused any confusion. My above description only applies to
x86 Linux VM on Hyper-V.

For ARM64 Hyper-V, I suspect the mainline Linux kernel still can't work in a
Linux VM running on ARM64 Hyper-V, so AFAIK the VM hibernation hasn't
been tested: it may work or may not work. This is in our To-Do list.

Linux VM on Hyper-V needs to know if hibernation is supported/enabled
for the VM, mainly due to 2 reasons:

1. In the VM, the hv_balloon driver should disable the balloon up/down
operations if hibernation is enabled for the VM, otherwise bad things can
happen, e.g. the hv_balloon driver allocates some pages and gives the
pages to the hyperpvisor; now if the VM is allowed to hibernate, later
when the VM resumes back, the VM loses the pages for ever, because
Hyper-V doesn't save the info of the pages that were from the VM, so
Hyper-V thinks no pages need to be returned to the VM.

2. If hibernation is enabled for a VM, the VM has a Linux agent program
that automatically creates and sets up the swap file for hibernation. If
hibernation is not enabled for the VM, the agent should not try to create
and set up the swap file for hibernation.
 
> >>> I know we can check the S4 state by 'dmesg':

> >>>

> >>> # dmesg |grep ACPI: | grep support

> >>> [    3.034134] ACPI: (supports S0 S4 S5)

> >>>

> >>> But this method is unreliable because the kernel msg buffer can be filled

> >>> and overwritten. Is there any better method? If not, do you think if the

> >>> below patch is appropriate? Thanks!

> >>

> >> Sorry for the delay.

> >>

> >> If ACPI S4 is supported, /sys/power/disk will list "platform" as one

> >> of the options (and it will be the default one then).  Otherwise,

> >> "platform" is not present in /sys/power/disk, because ACPI is the only

> >> user of hibernation_ops.

> 

> > This works on x86. Thanks a lot!

> >

> > BTW, does this also work on ARM64?

> 

> Not today. The S4/S5 stuff is part of 'ACPI_SYSTEM_POWER_STATES_SUPPORT',

> which arm64

> doesn't enable as it has a firmware mechanism that covers this on both DT and

> ACPI

> systems. That code is what calls hibernation_set_ops() to enable ACPI's

> platform mode.


Thanks for the explanation!

> Regardless: hibernate works fine. What does your hypervisor do that causes

> problems?

> (I think all we expect from firmware is it doesn't randomise the placement of

> the ACPI

> tables as they aren't necessarily part of the hibernate image)

> 

> Thanks, 

> James


I have explained the problems above for Linux VM on ARM64 Hyper-V.

I suppose you mean hibernation works fine for ARM64 bare metal. 
For Linux VM on ARM64 Hyper-V, I suspect some Hyper-V specific states may
have to be saved and restored for hibernation. This is in our To-Do lsit.

Thanks,
Dexuan
diff mbox series

Patch

diff --git a/kernel/power/main.c b/kernel/power/main.c
index 0aefd6f57e0a..931a1526ea69 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -9,6 +9,7 @@ 
 #include <linux/export.h>
 #include <linux/kobject.h>
 #include <linux/string.h>
+#include <linux/acpi.h>
 #include <linux/pm-trace.h>
 #include <linux/workqueue.h>
 #include <linux/debugfs.h>
@@ -600,8 +601,12 @@  static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
                        s += sprintf(s,"%s ", pm_states[i]);

 #endif
-       if (hibernation_available())
-               s += sprintf(s, "disk ");
+       if (hibernation_available()) {
+               if (acpi_sleep_state_supported(ACPI_STATE_S4))
+                       s += sprintf(s, "disk+ ");
+               else
+                       s += sprintf(s, "disk ");
+       }
        if (s != buf)
                /* convert the last space to a newline */
                *(s-1) = '\n';