On May 27 19:39:18, guent...@gmail.com wrote: > On Fri, 27 May 2022, Jan Stary wrote: > > ... and with the latest snapshot, they are back. > ... > > acpicpu0 at acpi0: C3(350@96 mwait.1@0x20), C2(500@64 mwait.1@0x10), > > C1(1000@1 mwait.1), PSS > > acpicpu1 at acpi0: C3(350@96 mwait.1@0x20), C2(500@64 mwait.1@0x10), > > C1(1000@1 mwait.1), PSS > > acpicpu2 at acpi0: C3(350@96 mwait.1@0x20), C2(500@64 mwait.1@0x10), > > C1(1000@1 mwait.1), PSS > > acpicpu3 at acpi0: C3(350@96 mwait.1@0x20), C2(500@64 mwait.1@0x10), > > C1(1000@1 mwait.1), PSS > > > > On May 26 14:34:43, h...@stare.cz wrote: > > > This is current/adm64, dmesgs below. > > > With the current snapshot, the C states are gone: > > > > > > -acpicpu0 at acpi0: C3(350@96 mwait.1@0x20), C2(500@64 mwait.1@0x10), > > > C1(1000@1 mwait.1), PSS > > > -acpicpu1 at acpi0: C3(350@96 mwait.1@0x20), C2(500@64 mwait.1@0x10), > > > C1(1000@1 mwait.1), PSS > > > -acpicpu2 at acpi0: C3(350@96 mwait.1@0x20), C2(500@64 mwait.1@0x10), > > > C1(1000@1 mwait.1), PSS > > > -acpicpu3 at acpi0: C3(350@96 mwait.1@0x20), C2(500@64 mwait.1@0x10), > > > C1(1000@1 mwait.1), PSS > > > +acpicpu0 at acpi0: C1(@1 halt!), PSS > > > +acpicpu1 at acpi0: C1(@1 halt!), PSS > > > +acpicpu2 at acpi0: C1(@1 halt!), PSS > > > +acpicpu3 at acpi0: C1(@1 halt!), PSS > > > > > > Is this expected? > > > Is it related to the recent apmd -A change? > > Not really. Well, unless your box is one where the states change > depending on, say, whether the box is plugged in.
This is a PC workstation that is always plugged in. > You could give this diff a shot. It enables processing of CST change > notifications. No committers have a (working) box that does that, so I > couldn't get any interest and I have no idea when--or even if--it might go > in. Thanks. The current snapshots seem to work fine (like they have been), this was the only snapshot that didn't show the C-states. Is anyone please aware of a change that could have temporarily coused that around May 25th? Jan > > > Index: sys/dev/acpi/acpicpu.c > =================================================================== > RCS file: /data/src/openbsd/src/sys/dev/acpi/acpicpu.c,v > retrieving revision 1.92 > diff -u -p -r1.92 acpicpu.c > --- sys/dev/acpi/acpicpu.c 6 Apr 2022 18:59:27 -0000 1.92 > +++ sys/dev/acpi/acpicpu.c 12 Apr 2022 06:13:55 -0000 > @@ -25,6 +25,7 @@ > #include <sys/malloc.h> > #include <sys/queue.h> > #include <sys/atomic.h> > +#include <sys/mutex.h> > > #include <machine/bus.h> > #include <machine/cpu.h> > @@ -80,6 +81,7 @@ void acpicpu_setperf_ppc_change(struct a > #define CST_FLAG_FALLBACK 0x4000 /* fallback for broken _CST */ > #define CST_FLAG_SKIP 0x8000 /* state is worse > choice */ > > +#define FLAGS_NOCST 0x01 > #define FLAGS_MWAIT_ONLY 0x02 > #define FLAGS_BMCHECK 0x04 > #define FLAGS_NOTHROTTLE 0x08 > @@ -113,8 +115,10 @@ struct acpi_cstate > uint64_t address; /* or mwait hint */ > }; > > -unsigned long cst_stats[4] = { 0 }; > - > +/* > + * Locking: > + * m sc_mtx > + */ > struct acpicpu_softc { > struct device sc_dev; > int sc_cpu; > @@ -130,6 +134,10 @@ struct acpicpu_softc { > struct cpu_info *sc_ci; > SLIST_HEAD(,acpi_cstate) sc_cstates; > > + struct mutex sc_mtx; > + struct acpi_cstate *sc_cstates_active; /* [m] */ > + int sc_mwait_only; /* [m] */ > + > bus_space_tag_t sc_iot; > bus_space_handle_t sc_ioh; > > @@ -161,10 +169,13 @@ struct acpicpu_softc { > > void acpicpu_add_cstatepkg(struct aml_value *, void *); > void acpicpu_add_cdeppkg(struct aml_value *, void *); > +void acpicpu_cst_activate(struct acpicpu_softc *); > int acpicpu_getppc(struct acpicpu_softc *); > int acpicpu_getpct(struct acpicpu_softc *); > int acpicpu_getpss(struct acpicpu_softc *); > int acpicpu_getcst(struct acpicpu_softc *); > +int acpicpu_cst_changed(struct acpicpu_softc *); > +void acpicpu_free_states(struct acpi_cstate *); > void acpicpu_getcst_from_fadt(struct acpicpu_softc *); > void acpicpu_print_one_cst(struct acpi_cstate *_cx); > void acpicpu_print_cst(struct acpicpu_softc *_sc); > @@ -510,11 +521,11 @@ acpicpu_getcst(struct acpicpu_softc *sc) > struct acpi_cstate *cx, *next_cx; > int use_nonmwait; > > - /* delete the existing list */ > - while ((cx = SLIST_FIRST(&sc->sc_cstates)) != NULL) { > - SLIST_REMOVE_HEAD(&sc->sc_cstates, link); > - free(cx, M_DEVBUF, sizeof(*cx)); > - } > + /* set aside the existing list and free it if not active */ > + cx = SLIST_FIRST(&sc->sc_cstates); > + SLIST_INIT(&sc->sc_cstates); > + if (cx != sc->sc_cstates_active) > + acpicpu_free_states(cx); > > /* provide a fallback C1-via-halt in case _CST's C1 is bogus */ > acpicpu_add_cstate(sc, ACPI_STATE_C1, CST_METH_HALT, > @@ -528,8 +539,10 @@ acpicpu_getcst(struct acpicpu_softc *sc) > > /* only have fallback state? then no _CST objects were understood */ > cx = SLIST_FIRST(&sc->sc_cstates); > - if (cx->flags & CST_FLAG_FALLBACK) > + if (cx->flags & CST_FLAG_FALLBACK) { > + sc->sc_flags &= ~FLAGS_MWAIT_ONLY; > return (1); > + } > > /* > * Skip states >= C2 if the CPU's LAPIC timer stops in deep > @@ -558,6 +571,38 @@ acpicpu_getcst(struct acpicpu_softc *sc) > return (0); > } > > +int > +acpicpu_cst_changed(struct acpicpu_softc *sc) > +{ > + struct acpi_cstate *active, *new; > + > + active = sc->sc_cstates_active; > + new = SLIST_FIRST(&sc->sc_cstates); > + > + while (active != NULL && new != NULL) { > + if (active->state != new->state || > + active->method != new->method || > + active->flags != new->flags || > + active->latency != new->latency || > + active->address != new->address) > + return 1; > + active = SLIST_NEXT(active, link); > + new = SLIST_NEXT(new, link); > + } > + > + return active != NULL || new != NULL; > +} > + > +void > +acpicpu_free_states(struct acpi_cstate *cx) > +{ > + while (cx != NULL) { > + struct acpi_cstate *next_cx = SLIST_NEXT(cx, link); > + free(cx, M_DEVBUF, sizeof(*cx)); > + cx = next_cx; > + } > +} > + > /* > * old-style fixed C-state info in the FADT. > * Note that this has extra restrictions on values and flags. > @@ -689,7 +734,9 @@ acpicpu_attach(struct device *parent, st > sc->sc_acpi = (struct acpi_softc *)parent; > sc->sc_devnode = aa->aaa_node; > > + mtx_init(&sc->sc_mtx, IPL_NONE); > SLIST_INIT(&sc->sc_cstates); > + sc->sc_cstates_active = NULL; > > if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, > "_UID", 0, NULL, &uid) == 0) > @@ -734,9 +781,10 @@ acpicpu_attach(struct device *parent, st > #endif > > /* Get C-States from _CST or FADT */ > - if (acpicpu_getcst(sc) || SLIST_EMPTY(&sc->sc_cstates)) > + if (acpicpu_getcst(sc) || SLIST_EMPTY(&sc->sc_cstates)) { > acpicpu_getcst_from_fadt(sc); > - else { > + sc->sc_flags |= FLAGS_NOCST; > + } else { > /* Notify BIOS we use _CST objects */ > if (sc->sc_acpi->sc_fadt->cst_cnt) { > acpi_write_pmreg(sc->sc_acpi, ACPIREG_SMICMD, 0, > @@ -794,9 +842,6 @@ acpicpu_attach(struct device *parent, st > 0, sc->sc_acpi->sc_fadt->pstate_cnt); > } > > - aml_register_notify(sc->sc_devnode, NULL, > - acpicpu_notify, sc, ACPIDEV_NOPOLL); > - > acpi_gasio(sc->sc_acpi, ACPI_IOREAD, > sc->sc_pct.pct_status.grd_gas.address_space_id, > sc->sc_pct.pct_status.grd_gas.address, > @@ -838,6 +883,39 @@ acpicpu_attach(struct device *parent, st > } > > printf("\n"); > + acpicpu_cst_activate(sc); > + > + /* > + * If we understood either the provided _CST or _PPC > + * resources, register for notification of changes. > + */ > + if ((sc->sc_flags & FLAGS_NOCST) == 0 || > + (sc->sc_flags & (FLAGS_NOPSS | FLAGS_NOPCT)) == 0) > + { > +#ifdef ACPI_DEBUG > + printf(": %s: enabling notification\n", sc->sc_devnode->name); > +#endif > + aml_register_notify(sc->sc_devnode, NULL, > + acpicpu_notify, sc, ACPIDEV_NOPOLL); > + } > +} > + > +void > +acpicpu_cst_activate(struct acpicpu_softc *sc) > +{ > + struct acpi_cstate *cx, *old_states; > + > + mtx_enter(&sc->sc_mtx); > + cx = SLIST_FIRST(&sc->sc_cstates); > + old_states = sc->sc_cstates_active; > + if (cx != old_states) > + sc->sc_cstates_active = cx; > + else > + old_states = NULL; > + sc->sc_mwait_only = (sc->sc_flags & FLAGS_MWAIT_ONLY) != 0; > + mtx_leave(&sc->sc_mtx); > + > + acpicpu_free_states(old_states); > } > > int > @@ -1016,6 +1094,8 @@ acpicpu_notify(struct aml_node *node, in > > switch (notify_type) { > case 0x80: /* _PPC changed, retrieve new values */ > + if (sc->sc_flags & (FLAGS_NOPSS | FLAGS_NOPCT)) > + break; > acpicpu_getppc(sc); > acpicpu_getpss(sc); > if (sc->sc_notify) > @@ -1023,10 +1103,15 @@ acpicpu_notify(struct aml_node *node, in > break; > > case 0x81: /* _CST changed, retrieve new values */ > + if (sc->sc_flags & FLAGS_NOCST) > + break; > acpicpu_getcst(sc); > - printf("%s: notify", DEVNAME(sc)); > - acpicpu_print_cst(sc); > - printf("\n"); > + if (acpicpu_cst_changed(sc)) { > + printf("%s: notify", DEVNAME(sc)); > + acpicpu_print_cst(sc); > + printf("\n"); > + acpicpu_cst_activate(sc); > + } > break; > > default: > @@ -1151,18 +1236,22 @@ acpicpu_setperf(int level) > void > acpicpu_idle(void) > { > - struct cpu_info *ci = curcpu(); > - struct acpicpu_softc *sc = (struct acpicpu_softc *)ci->ci_acpicpudev; > - struct acpi_cstate *best, *cx; > - unsigned long itime; > + struct cpu_info *ci = curcpu(); > + struct acpicpu_softc *sc = (struct acpicpu_softc *)ci->ci_acpicpudev; > + struct acpi_cstate *best, *cx; > + unsigned long itime; > + short method; > + u_int address; > > if (sc == NULL) { > __asm volatile("sti"); > panic("null acpicpu"); > } > > + mtx_enter(&sc->sc_mtx); > + > /* possibly update the MWAIT_ONLY flag in cpu_info */ > - if (sc->sc_flags & FLAGS_MWAIT_ONLY) { > + if (sc->sc_mwait_only) { > if ((ci->ci_mwait & MWAIT_ONLY) == 0) > atomic_setbits_int(&ci->ci_mwait, MWAIT_ONLY); > } else if (ci->ci_mwait & MWAIT_ONLY) > @@ -1172,7 +1261,7 @@ acpicpu_idle(void) > * Find the first state with a latency we'll accept, ignoring > * states marked skippable > */ > - best = cx = SLIST_FIRST(&sc->sc_cstates); > + best = cx = sc->sc_cstates_active; > while ((cx->flags & CST_FLAG_SKIP) || > cx->latency * 3 > sc->sc_prev_sleep) { > if ((cx = SLIST_NEXT(cx, link)) == NULL) > @@ -1196,18 +1285,20 @@ acpicpu_idle(void) > best = cx; > } > > - > - atomic_inc_long(&cst_stats[best->state]); > + /* made our choice; save the values we need and unlock */ > + method = best->method; > + address = best->address; > + mtx_leave(&sc->sc_mtx); > > itime = tick / 2; > - switch (best->method) { > + switch (method) { > default: > case CST_METH_HALT: > __asm volatile("sti; hlt"); > break; > > case CST_METH_IO_HALT: > - inb((u_short)best->address); > + inb((u_short)address); > __asm volatile("sti; hlt"); > break; > > @@ -1238,7 +1329,7 @@ acpicpu_idle(void) > * something to the queue and called cpu_unidle() between > * the check in sched_idle() and here. > */ > - hints = (unsigned)best->address; > + hints = (unsigned)address; > microuptime(&start); > atomic_setbits_int(&ci->ci_mwait, MWAIT_IDLING); > if (cpu_is_idle(ci)) { > @@ -1265,7 +1356,7 @@ acpicpu_idle(void) > } > > case CST_METH_GAS_IO: > - inb((u_short)best->address); > + inb((u_short)address); > /* something harmless to give system time to change state */ > acpi_read_pmreg(acpi_softc, ACPIREG_PM1_STS, 0); > break; > >