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;
> 
> 

Reply via email to