Re: git: e779891327b1 - main - sys/power: Sleep type reporting by PM backends
Date: Tue, 16 Sep 2025 05:02:39 UTC
In message <202509142159.58ELx5Rg054606@gitrepo.freebsd.org>, Aymeric Wibo writ
es:
> The branch main has been updated by obiwac:
>
> URL: https://cgit.FreeBSD.org/src/commit/?id=e779891327b1d9b9ab10ba482e59f498
> 790505a7
>
> commit e779891327b1d9b9ab10ba482e59f498790505a7
> Author: Aymeric Wibo <obiwac@FreeBSD.org>
> AuthorDate: 2025-09-14 21:58:13 +0000
> Commit: Aymeric Wibo <obiwac@FreeBSD.org>
> CommitDate: 2025-09-14 21:58:15 +0000
>
> sys/power: Sleep type reporting by PM backends
>
> Allow PM backends to report supported sleep types when registering
> through `power_pm_register`. Expose this information through
> `kern.power.supported_stype` sysctl, and set defaults for
> `power_standby/suspend/hibernate_stype` based on this.
>
> Implement this in ACPI PM backend.
>
> Reviewed by: mckusick (mentor), markj
> Approved by: mckusick (mentor), markj
> Sponsored by: The FreeBSD Foundation
> Differential Revision: https://reviews.freebsd.org/D52044
> ---
> sys/dev/acpica/acpi.c | 6 ++++--
> sys/kern/subr_power.c | 46 +++++++++++++++++++++++++++++++++++++++++-----
> sys/sys/power.h | 3 ++-
> 3 files changed, 47 insertions(+), 8 deletions(-)
>
> diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
> index 8dd879a573cc..702e1ecb5340 100644
> --- a/sys/dev/acpica/acpi.c
> +++ b/sys/dev/acpica/acpi.c
> @@ -734,7 +734,8 @@ acpi_attach(device_t dev)
> goto out;
>
> /* Register ACPI again to pass the correct argument of pm_func. */
> - power_pm_register(POWER_PM_TYPE_ACPI, acpi_pm_func, sc);
> + power_pm_register(POWER_PM_TYPE_ACPI, acpi_pm_func, sc,
> + acpi_supported_stypes);
>
> acpi_platform_osc(dev);
>
> @@ -4776,7 +4777,8 @@ acpi_pm_register(void *arg)
> if (!cold || resource_disabled("acpi", 0))
> return;
>
> - power_pm_register(POWER_PM_TYPE_ACPI, acpi_pm_func, NULL);
> + power_pm_register(POWER_PM_TYPE_ACPI, acpi_pm_func, NULL,
> + acpi_supported_stypes);
> }
>
> SYSINIT(power, SI_SUB_KLD, SI_ORDER_ANY, acpi_pm_register, NULL);
> diff --git a/sys/kern/subr_power.c b/sys/kern/subr_power.c
> index eb5bd03f5018..44ad82860649 100644
> --- a/sys/kern/subr_power.c
> +++ b/sys/kern/subr_power.c
> @@ -39,13 +39,14 @@
> #include <sys/systm.h>
> #include <sys/taskqueue.h>
>
> -enum power_stype power_standby_stype = POWER_STYPE_STANDBY;
> -enum power_stype power_suspend_stype = POWER_STYPE_SUSPEND_TO_IDLE;
> -enum power_stype power_hibernate_stype = POWER_STYPE_HIBERNATE;
> +enum power_stype power_standby_stype = POWER_STYPE_UNKNOWN;
> +enum power_stype power_suspend_stype = POWER_STYPE_UNKNOWN;
> +enum power_stype power_hibernate_stype = POWER_STYPE_UNKNOWN;
>
> static u_int power_pm_type = POWER_PM_TYPE_NONE;
> static power_pm_fn_t power_pm_fn = NULL;
> static void *power_pm_arg = NULL;
> +static bool power_pm_supported[POWER_STYPE_COUNT] = {0};
> static struct task power_pm_task;
>
> enum power_stype
> @@ -70,6 +71,26 @@ power_stype_to_name(enum power_stype stype)
> return (power_stype_names[stype]);
> }
>
> +static int
> +sysctl_supported_stypes(SYSCTL_HANDLER_ARGS)
> +{
> + int error;
> + struct sbuf sb;
> + enum power_stype stype;
> +
> + sbuf_new(&sb, NULL, 32, SBUF_AUTOEXTEND);
> + for (stype = 0; stype < POWER_STYPE_COUNT; stype++) {
> + if (power_pm_supported[stype])
> + sbuf_printf(&sb, "%s ", power_stype_to_name(stype));
> + }
> + sbuf_trim(&sb);
> + sbuf_finish(&sb);
> + error = sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req);
> + sbuf_delete(&sb);
> +
> + return (error);
> +}
> +
> static int
> power_sysctl_stype(SYSCTL_HANDLER_ARGS)
> {
> @@ -86,7 +107,8 @@ power_sysctl_stype(SYSCTL_HANDLER_ARGS)
> new_stype = power_name_to_stype(name);
> if (new_stype == POWER_STYPE_UNKNOWN)
> return (EINVAL);
> - /* TODO Check to see if the new stype is supported. */
> + if (!power_pm_supported[new_stype])
> + return (EOPNOTSUPP);
> if (new_stype != old_stype)
> *(enum power_stype *)oidp->oid_arg1 = new_stype;
> return (0);
> @@ -95,6 +117,9 @@ power_sysctl_stype(SYSCTL_HANDLER_ARGS)
> static SYSCTL_NODE(_kern, OID_AUTO, power, CTLFLAG_RW, 0,
> "Generic power management related sysctls");
>
> +SYSCTL_PROC(_kern_power, OID_AUTO, supported_stype,
> + CTLTYPE_STRING | CTLFLAG_RD, 0, 0, sysctl_supported_stypes, "A",
> + "List supported sleep types");
> SYSCTL_PROC(_kern_power, OID_AUTO, standby, CTLTYPE_STRING | CTLFLAG_RW,
> &power_standby_stype, 0, power_sysctl_stype, "A",
> "Sleep type to enter on standby");
> @@ -114,7 +139,8 @@ power_pm_deferred_fn(void *arg, int pending)
> }
>
> int
> -power_pm_register(u_int pm_type, power_pm_fn_t pm_fn, void *pm_arg)
> +power_pm_register(u_int pm_type, power_pm_fn_t pm_fn, void *pm_arg,
> + bool pm_supported[static POWER_STYPE_COUNT])
> {
> int error;
>
> @@ -123,6 +149,16 @@ power_pm_register(u_int pm_type, power_pm_fn_t pm_fn, vo
> id *pm_arg)
> power_pm_type = pm_type;
> power_pm_fn = pm_fn;
> power_pm_arg = pm_arg;
> + memcpy(power_pm_supported, pm_supported,
> + sizeof(power_pm_supported));
> + if (power_pm_supported[POWER_STYPE_STANDBY])
> + power_standby_stype = POWER_STYPE_STANDBY;
> + if (power_pm_supported[POWER_STYPE_SUSPEND_TO_IDLE])
> + power_suspend_stype = POWER_STYPE_SUSPEND_TO_IDLE;
> + else if (power_pm_supported[POWER_STYPE_SUSPEND_TO_MEM])
> + power_suspend_stype = POWER_STYPE_SUSPEND_TO_MEM;
> + if (power_pm_supported[POWER_STYPE_HIBERNATE])
> + power_hibernate_stype = POWER_STYPE_HIBERNATE;
> error = 0;
> TASK_INIT(&power_pm_task, 0, power_pm_deferred_fn, NULL);
> } else {
> diff --git a/sys/sys/power.h b/sys/sys/power.h
> index 44d7fc354423..33ace400bfd2 100644
> --- a/sys/sys/power.h
> +++ b/sys/sys/power.h
> @@ -91,7 +91,8 @@ extern const char *power_stype_to_name(enum power_stype _
> stype);
>
> typedef int (*power_pm_fn_t)(u_long _cmd, void* _arg, enum power_stype _styp
> e);
> extern int power_pm_register(u_int _pm_type, power_pm_fn_t _pm_fn,
> - void *_pm_arg);
> + void *_pm_arg,
> + bool _pm_supported[static POWER_STYPE_COUNT]);
> extern u_int power_pm_get_type(void);
> extern void power_pm_suspend(int);
>
>
One of this series of ACPI commits has broken power management on my machines.
One of which managed to capture a dump from a kernel panic after poweroff(8)
was issued.
__curthread () at /opt/src/git-src/sys/amd64/include/pcpu_aux.h:57
57 __asm("movq %%gs:%c1,%0" : "=r" (td)
(kgdb) #0 __curthread () at /opt/src/git-src/sys/amd64/include/pcpu_aux.h:57
td = <optimized out>
#1 doadump (textdump=textdump@entry=1)
at /opt/src/git-src/sys/kern/kern_shutdown.c:399
error = 0
coredump = <optimized out>
#2 0xffffffff8070d320 in kern_reboot (howto=260)
at /opt/src/git-src/sys/kern/kern_shutdown.c:519
once = 1
__pc = 0x0
#3 0xffffffff8070d857 in vpanic (fmt=0xffffffff80b8e00c "%s",
ap=ap@entry=0xfffffe008a636960)
at /opt/src/git-src/sys/kern/kern_shutdown.c:974
buf = "page fault", '\000' <repeats 245 times>
__pc = 0x0
__pc = 0x0
__pc = 0x0
other_cpus = {__bits = {14, 0 <repeats 15 times>}}
td = 0xfffff80006607000
bootopt = <unavailable>
newpanic = <optimized out>
#4 0xffffffff8070d683 in panic (fmt=<unavailable>)
at /opt/src/git-src/sys/kern/kern_shutdown.c:887
ap = {{gp_offset = 16, fp_offset = 48,
overflow_arg_area = 0xfffffe008a636990,
reg_save_area = 0xfffffe008a636930}}
#5 0xffffffff80aeb4bc in trap_fatal (frame=<optimized out>,
eva=<optimized out>) at /opt/src/git-src/sys/amd64/amd64/trap.c:969
type = <optimized out>
handled = <optimized out>
#6 0xffffffff80aeb4bc in trap_pfault (frame=0xfffffe008a636a00,
usermode=false, signo=<optimized out>, ucode=<optimized out>)
__pc = 0x0
__pc = 0x0
__pc = 0x0
td = <optimized out>
p = <optimized out>
eva = 136
map = <optimized out>
ftype = <optimized out>
rv = <optimized out>
#7 <signal handler called>
No locals.
#8 device_get_softc (dev=dev@entry=0x0)
at /opt/src/git-src/sys/kern/subr_bus.c:2141
No locals.
#9 0xffffffff80429385 in acpi_wake_sleep_prep (handle=0xfffff80007706e00,
stype=POWER_STYPE_POWEROFF) at /opt/src/git-src/sys/dev/acpica/acpi.c:3689
prw = {gpe_handle = 0x0, gpe_bit = 27, lowest_wake = 3, power_res = {{
Type = 0, Integer = {Type = 0, Value = 0}, String = {Type = 0,
Length = 0, Pointer = 0x0}, Buffer = {Type = 0, Length = 0,
Pointer = 0x0}, Package = {Type = 0, Count = 0,
Elements = 0x0}, Reference = {Type = 0, ActualType = 0,
Handle = 0x0}, Processor = {Type = 0, ProcId = 0,
PblkAddress = 0, PblkLength = 87678488}, PowerResource = {
Type = 0, SystemLevel = 0, ResourceOrder = 0}}, {Type = 369,
Integer = {Type = 369, Value = 8}, String = {Type = 369,
Length = 0,
Pointer = 0x8 <error: Cannot access memory at address 0x8>},
Buffer = {Type = 369, Length = 0,
Pointer = 0x8 <error: Cannot access memory at address 0x8>},
Buffer = {Type = 369, Length = 0,
Pointer = 0x8 <error: Cannot access memory at address 0x8>},
Package = {Type = 369, Count = 0, Elements = 0x8}, Reference = {
Type = 369, ActualType = 0, Handle = 0x8}, Processor = {
Type = 369, ProcId = 0, PblkAddress = 8, PblkLength = 0},
PowerResource = {Type = 369, SystemLevel = 0,
ResourceOrder = 8}}, {Type = 2159484735, Integer = {
Type = 2159484735, Value = 0}, String = {Type = 2159484735,
Length = 4294967295, Pointer = 0x0}, Buffer = {
Type = 2159484735, Length = 4294967295, Pointer = 0x0},
Package = {Type = 2159484735, Count = 4294967295,
Elements = 0x0}, Reference = {Type = 2159484735,
ActualType = 4294967295, Handle = 0x0}, Processor = {
Type = 2159484735, ProcId = 4294967295, PblkAddress = 0,
PblkLength = 87678488}, PowerResource = {Type = 2159484735,
SystemLevel = 4294967295, ResourceOrder = 0}}, {Type = 458,
Integer = {Type = 458, Value = 8}, String = {Type = 458,
Length = 0,
Pointer = 0x8 <error: Cannot access memory at address 0x8>},
Buffer = {Type = 458, Length = 0,
Pointer = 0x8 <error: Cannot access memory at address 0x8>},
Package = {Type = 458, Count = 0, Elements = 0x8}, Reference = {
Type = 458, ActualType = 0, Handle = 0x8}, Processor = {
Type = 458, ProcId = 0, PblkAddress = 8, PblkLength = 0},
PowerResource = {Type = 458, SystemLevel = 0,
ResourceOrder = 8}}, {Type = 2159484735, Integer = {
Type = 2159484735, Value = 18446741877008067488}, String = {
Type = 2159484735, Length = 4294967295,
Pointer = 0xfffffe008a636ba0 "\300kc\212"}, Buffer = {
Type = 2159484735, Length = 4294967295,
Pointer = 0xfffffe008a636ba0 "\300kc\212"}, Package = {
Type = 2159484735, Count = 4294967295,
Elements = 0xfffffe008a636ba0}, Reference = {
Type = 2159484735, ActualType = 4294967295,
Handle = 0xfffffe008a636ba0}, Processor = {Type = 2159484735,
ProcId = 4294967295, PblkAddress = 18446741877008067488,
PblkLength = 2154715683}, PowerResource = {Type = 2159484735,
SystemLevel = 4294967295, ResourceOrder = 2321771424}}, {
Type = 87678488, Integer = {Type = 87678488,
Value = 18446735277723512832}, String = {Type = 87678488,
Length = 4294965248,
Pointer = 0xfffff80006607000 "\300\321G\204\377\377\377\377\020 "}, Buffer = {Type = 87678488, Length =
4294965248,
Pointer = 0xfffff80006607000 "\300\321G\204\377\377\377\377\020 "}, Package = {Type = 87678488, Count =
4294965248,
Elements = 0xfffff80006607000}, Reference = {Type = 87678488,
ActualType = 4294965248, Handle = 0xfffff80006607000},
Processor = {Type = 87678488, ProcId = 4294965248,
PblkAddress = 18446735277723512832, PblkLength = 87678464},
PowerResource = {Type = 87678488, SystemLevel = 4294965248,
ResourceOrder = 106983424}}, {Type = 663, Integer = {
Type = 663, Value = 18446735277704207896}, String = {
Type = 663, Length = 0, Pointer = 0xfffff8000539de18 ""},
Buffer = {Type = 663, Length = 0,
Pointer = 0xfffff8000539de18 ""}, Package = {Type = 663,
Count = 0, Elements = 0xfffff8000539de18}, Reference = {
Type = 663, ActualType = 0, Handle = 0xfffff8000539de18},
Processor = {Type = 663, ProcId = 0,
PblkAddress = 18446735277704207896, PblkLength = 2165581152},
PowerResource = {Type = 663, SystemLevel = 0,
ResourceOrder = 87678488}}, {Type = 87678464, Integer = {
Type = 87678464, Value = 8}, String = {Type = 87678464,
Length = 4294965248,
Pointer = 0x8 <error: Cannot access memory at address 0x8>},
Buffer = {Type = 87678464, Length = 4294965248,
Pointer = 0x8 <error: Cannot access memory at address 0x8>},
Package = {Type = 87678464, Count = 4294965248, Elements = 0x8},
Reference = {Type = 87678464, ActualType = 4294965248,
Handle = 0x8}, Processor = {Type = 87678464,
ProcId = 4294965248, PblkAddress = 8,
PblkLength = 2321771456}, PowerResource = {Type = 87678464,
SystemLevel = 4294965248, ResourceOrder = 8}}},
power_res_count = 0}
dev = 0x0
sc = <optimized out>
sstate = <optimized out>
#10 acpi_wake_prep (handle=0xfffff80007706e00, level=<optimized out>,
context=<optimized out>, status=<optimized out>)
at /opt/src/git-src/sys/dev/acpica/acpi.c:3764
stype = POWER_STYPE_POWEROFF
#11 0xffffffff803756db in AcpiNsWalkNamespace (Type=Type@entry=6,
StartNode=<optimized out>, StartNode@entry=0xfffff800050b3880,
MaxDepth=MaxDepth@entry=100, Flags=Flags@entry=1,
DescendingCallback=DescendingCallback@entry=0xffffffff80429320 <acpi_wake_prep>, AscendingCallback=AscendingCallbac
k@entry=0x0,
Context=0xfffffe008a636ce4, ReturnValue=0x0)
at /opt/src/git-src/sys/contrib/dev/acpica/components/namespace/nswalk.c:484
NodePreviouslyVisited = 0 '\000'
ParentNode = 0xfffff800050b14c0
ChildNode = 0xfffff80007706e00
ChildType = 6
Level = 2
Status = 0
MutexStatus = <optimized out>
#12 0xffffffff80375c45 in AcpiWalkNamespace (Type=Type@entry=6,
StartObject=0xfffff800050b3880, MaxDepth=MaxDepth@entry=100,
DescendingCallback=0xffffffff80429320 <acpi_wake_prep>,
AscendingCallback=AscendingCallback@entry=0x0,
Context=Context@entry=0xfffffe008a636ce4, ReturnValue=<optimized out>)
at /opt/src/git-src/sys/contrib/dev/acpica/components/namespace/nsxfeval.c:809
Status = 0
#13 0xffffffff80426384 in acpi_wake_prep_walk (stype=POWER_STYPE_POWEROFF)
at /opt/src/git-src/sys/dev/acpica/acpi.c:3777
sb_handle = 0xfffff800050b3880
#14 acpi_shutdown (dev=0xfffff80007716e00)
at /opt/src/git-src/sys/dev/acpica/acpi.c:878
No locals.
#15 0xffffffff8074c706 in DEVICE_SHUTDOWN (dev=0xfffff80007716e00)
at ./device_if.h:262
rc = <optimized out>
_m = <optimized out>
_cep = <optimized out>
_ce = <optimized out>
_desc = <optimized out>
#16 device_shutdown (dev=0xfffff80007716e00)
at /opt/src/git-src/sys/kern/subr_bus.c:2753
No locals.
#17 bus_generic_shutdown (dev=<optimized out>)
at /opt/src/git-src/sys/kern/subr_bus.c:3563
child = <optimized out>
#18 0xffffffff8074c706 in DEVICE_SHUTDOWN (dev=0xfffff800051b8200)
at ./device_if.h:262
rc = <optimized out>
_m = <optimized out>
_cep = <optimized out>
_ce = <optimized out>
#16 device_shutdown (dev=0xfffff80007716e00)
at /opt/src/git-src/sys/kern/subr_bus.c:2753
No locals.
#17 bus_generic_shutdown (dev=<optimized out>)
at /opt/src/git-src/sys/kern/subr_bus.c:3563
child = <optimized out>
#18 0xffffffff8074c706 in DEVICE_SHUTDOWN (dev=0xfffff800051b8200)
at ./device_if.h:262
rc = <optimized out>
_m = <optimized out>
_cep = <optimized out>
_ce = <optimized out>
_desc = <optimized out>
#19 device_shutdown (dev=0xfffff800051b8200)
at /opt/src/git-src/sys/kern/subr_bus.c:2753
No locals.
#20 bus_generic_shutdown (dev=<optimized out>)
at /opt/src/git-src/sys/kern/subr_bus.c:3563
child = <optimized out>
#21 0xffffffff80750d06 in DEVICE_SHUTDOWN (dev=0xfffff800051b8500)
at ./device_if.h:262
rc = <optimized out>
_m = <optimized out>
_cep = <optimized out>
_ce = <optimized out>
_desc = <optimized out>
#22 device_shutdown (dev=0xfffff800051b8500)
at /opt/src/git-src/sys/kern/subr_bus.c:2753
No locals.
#23 root_bus_module_handler (mod=<optimized out>, what=<optimized out>,
arg=<optimized out>) at /opt/src/git-src/sys/kern/subr_bus.c:5211
No locals.
#24 0xffffffff806e534b in module_shutdown (arg1=<optimized out>,
arg2=<optimized out>) at /opt/src/git-src/sys/kern/kern_module.c:101
mod = 0xfffff800051d3b00
#25 0xffffffff8070d3d3 in kern_reboot (howto=16392)
at /opt/src/git-src/sys/kern/kern_shutdown.c:527
_ep = <optimized out>
_t = 0xfffff800050e9f40
_el = 0xfffff800050e4600
once = 1
__pc = 0x0
#26 0xffffffff8070cd9c in sys_reboot (td=0xfffff80006607000,
uap=0xfffff80006607428) at /opt/src/git-src/sys/kern/kern_shutdown.c:308
error = 5
#27 0xffffffff80aebe69 in syscallenter (td=0xfffff80006607000)
at /opt/src/git-src/sys/amd64/amd64/../../kern/subr_syscall.c:193
se = 0xffffffff81054310 <sysent+1760>
p = 0xfffffe0081002010
sa = 0xfffff80006607418
error = <optimized out>
sy_thr_static = true
traced = <optimized out>
_audit_entered = <optimized out>
#28 amd64_syscall (td=0xfffff80006607000, traced=0)
at /opt/src/git-src/sys/amd64/amd64/trap.c:1208
ksi = {ksi_link = {tqe_next = 0xfffffe008a636f30,
tqe_prev = 0xffffffff80aeae4d <trap+2173>}, ksi_info = {
si_signo = -1973195040, si_errno = -512, si_code = -2139594896,
si_pid = -1, si_uid = 25088, si_status = -2047,
si_addr = 0x800000000000, si_value = {sival_int = -860430388,
sival_ptr = 0x326493c1ccb6dfcc, sigval_int = -860430388,
sigval_ptr = 0x326493c1ccb6dfcc}, _reason = {_fault = {
_trapno = 3}, _timer = {_timerid = 3, _overrun = 0}, _mesgq = {
_mqd = 3}, _poll = {_band = 3}, _capsicum = {_syscall = 3},
__spare__ = {__spare1__ = 3, __spare2__ = {106984784, -2048,
-1973194752, -512, -2126868952, -1, 106983424}}}},
ksi_flags = -2130704888, ksi_sigq = 0x7}
#29 <signal handler called>
No locals.
#30 0x000000000028bb1a in ?? ()
--
Cheers,
Cy Schubert <Cy.Schubert@cschubert.com>
FreeBSD UNIX: <cy@FreeBSD.org> Web: https://FreeBSD.org
NTP: <cy@nwtime.org> Web: https://nwtime.org
e**(i*pi)+1=0