All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eugene Shalygin <eugene.shalygin@gmail.com>
To: Denis Pauk <pauk.denis@gmail.com>
Cc: andy.shevchenko@gmail.com, Jean Delvare <jdelvare@suse.com>,
	Guenter Roeck <linux@roeck-us.net>,
	linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org
Subject: Re: [PATCH v2 2/3] hwmon: (asus_wmi_ec_sensors) Support B550 Asus WMI.
Date: Thu, 7 Oct 2021 20:11:33 +0200	[thread overview]
Message-ID: <CAB95QAQ+u4DmF0e9Zvy5hDV0mFQDEULtr-newtz5_6y=Bzp+ww@mail.gmail.com> (raw)
In-Reply-To: <CAB95QASYPRZSFnpE5u=SYJ49Hd+=BAZY==Ky8dzjL8h7YZj-CQ@mail.gmail.com>

Denis and All,

regarding the asus-wmi-ec-sensors driver: it uses a WMI method to read
EC registers, and this method is slow (requires almost a full second
for a single call). Maybe I'm doing something wrong, but my impression
is that the WMI calls themselves are that slow. I will try to
reimplement this driver using direct EC operations and the global ACPI
lock with a hope to make it read sensors quicker. If that works out,
perhaps the nct6775 may go the same way, as it suffers too from the
slow WMI calls. I know next to nothing about the ACPI system and learn
from the beginning, so I'm not sure about the result. I know the naive
reading from the ACPI EC registers leads to problems (fans get stuck,
etc.), and if someone with knowledge can assure me that the idea with
the ACPI global lock (as far as I understand it is even implemented in
the ec kernel driver already) is correct, I would even request to stop
accepting the EC WMI sensors driver, as it is so slow (albeit dead
simple and small).

Best regards,
Eugen

On Thu, 7 Oct 2021 at 19:55, Eugene Shalygin <eugene.shalygin@gmail.com> wrote:
>
> Hi Denis,
>
> yes, the GH repo contains the fix and a few code cleanups, which I
> would like to propose for mainlining too. Also, please find below a
> draft of the documentation:
>
> Kernel driver asus-wmi-ec-sensors
> =================================
>
> Authors:
>         <eugene.shalygin@gmail.com>
>
> Description:
> ------------
> ASUS mainboards publish hardware monitoring information via Super I/O
> chip and the ACPI embedded controller (EC) registers. Some of the sensors
> are only available via the EC.
>
> ASUS WMI interface provides a method (BREC) to read data from EC registers,
> which is utilized by this driver to publish those sensor readings to the
> HWMON system. The driver is aware of and reads the following sensors:
>
> 1. Chipset (PCH) temperature
> 2. CPU package temperature
> 3. Motherboard temperature
> 4. Readings from the T_Sensor header
> 5. VRM temperature
> 6. CPU_Opt fan RPM
> 7. Chipset fan RPM
> 8. Readings from the "Water flow meter" header (RPM)
> 9. Readings from the "Water In" and "Water Out" temperature headers
> 10. CPU current
>
> Best regards,
> Eugene
>
> On Thu, 7 Oct 2021 at 17:46, Denis Pauk <pauk.denis@gmail.com> wrote:
> >
> > Hi Eugene,
> >
> > On Thu, 7 Oct 2021 01:32:14 +0200
> > Eugene Shalygin <eugene.shalygin@gmail.com> wrote:
> >
> > > On Thu, 7 Oct 2021 at 00:25, Denis Pauk <pauk.denis@gmail.com> wrote:
> > > >
> > >
> > > > Supported motherboards:
> > > > * ROG CROSSHAIR VIII HERO
> > > > * ROG CROSSHAIR VIII DARK HERO
> > > > * ROG CROSSHAIR VIII FORMULA
> > > > * ROG STRIX X570-E GAMING
> > > > * ROG STRIX B550-E GAMING
> > >
> > > Pro WS X570-ACE is missing from this list.
> > Thanks, I will check.
> > >
> > > > + * EC provided:
> > > provides
> > Thanks, I will check.
> > >
> > > > + * Chipset temperature,
> > > > + * CPU temperature,
> > > > + * Motherboard temperature,
> > > > + * T_Sensor temperature,
> > > > + * VRM  temperature,
> > > > + * Water In temperature,
> > > > + * Water Out temperature,
> > > > + * CPU Optional Fan,
> > > Hereinafter "CPU Optional Fan RPM"?
> > >
> > Thanks, I will check.
> > > > +static const enum known_ec_sensor
> > > > known_board_sensors[BOARD_MAX][SENSOR_MAX + 1] = {
> > > > +       [BOARD_PW_X570_A] = {
> > > > +               SENSOR_TEMP_CHIPSET, SENSOR_TEMP_CPU,
> > > > SENSOR_TEMP_MB, SENSOR_TEMP_VRM,
> > > > +               SENSOR_FAN_CHIPSET,
> > >
> > > I missed SENSOR_CURR_CPU for a few boards, and unfortunately the
> > > mistake made it here too. Sorry for that.
> > >
> > Do you have such fix in your repository?
> > > > +/**
> > > > + * struct asus_wmi_ec_info - sensor info.
> > > > + * @sensors: list of sensors.
> > > > + * @read_arg: UTF-16 string to pass to BRxx() WMI function.
> > > > + * @read_buffer: WMI function output.
> > >
> > > This seems to be a bit misleading to me in a sense that the variable
> > > holds decoded output (array of numbers as opposed to array of
> > > characters in the WMI output buffer.
> > >
> > > > +struct asus_wmi_data {
> > > > +       int ec_board;
> > > > +};
> > >
> > > A leftover?
> > >
> > Its platform data and used to share board_id with probe.
> >
> > > > +static void asus_wmi_ec_decode_reply_buffer(const u8 *inp, u8 *out)
> > > > +{
> > > > +       unsigned int len = ACPI_MIN(ASUS_WMI_MAX_BUF_LEN, inp[0] /
> > > > 4);
> > > > +       char buffer[ASUS_WMI_MAX_BUF_LEN * 2];
> > > > +       const char *pos = buffer;
> > > > +       const u8 *data = inp + 2;
> > > > +       unsigned int i;
> > > > +
> > > > +       utf16s_to_utf8s((wchar_t *)data, len * 2,
> > > > UTF16_LITTLE_ENDIAN, buffer, len * 2);
> > > Errr... Why is it here? You need the same loop afterwards, just with a
> > > smaller stride.
> > I have tried to apply Andy's idea. And it looks it does not
> > provide benefits. Andy, what do you think? Maybe I understand it in
> > wrong way.
> > > > +
> > > > +       for (i = 0; i < len; i++, pos += 2)
> > > > +               out[i] = (hex_to_bin(pos[0]) << 4) +
> > > > hex_to_bin(pos[1]); +}
> > > > +
> > > > +static void asus_wmi_ec_encode_registers(u16 *registers, u8 len,
> > > > char *out) +{
> > > > +       char buffer[ASUS_WMI_MAX_BUF_LEN * 2];
> > > > +       char *pos = buffer;
> > > > +       unsigned int i;
> > > > +       u8 byte;
> > > > +
> > > > +       *out++ = len * 8;
> > > > +       *out++ = 0;
> > > > +
> > > > +       for (i = 0; i < len; i++) {
> > > > +               byte = registers[i] >> 8;
> > > > +               *pos = hex_asc_hi(byte);
> > > > +               pos++;
> > > > +               *pos = hex_asc_lo(byte);
> > > > +               pos++;
> > > > +               byte = registers[i];
> > > > +               *pos = hex_asc_hi(byte);
> > > > +               pos++;
> > > > +               *pos = hex_asc_lo(byte);
> > > > +               pos++;
> > > > +       }
> > > > +
> > > > +       utf8s_to_utf16s(buffer, len * 4, UTF16_LITTLE_ENDIAN,
> > > > (wchar_t *)out, len * 4);
> > > Same here. Just for the sake of calling utf8s_to_utf16s() you need the
> > > same loop plus an additional buffer. I don't get it.
> > >
> > I have tried to apply Andy's idea. And it looks it does not
> > provide benefits. Andy, what do you think? Maybe I understand it in
> > wrong way.
> > > > +}
> > > > +
> > > > +static void asus_wmi_ec_make_block_read_query(struct
> > > > asus_wmi_ec_info *ec) +{
> > > > +       u16 registers[ASUS_WMI_BLOCK_READ_REGISTERS_MAX];
> > > > +       const struct ec_sensor_info *si;
> > > > +       long i, j, register_idx = 0;
> > > long? maybe a simple unsigned or int?
> > >
> > Looks as it was in original patch, I will look.
> > > > +
> > > > +static int asus_wmi_ec_update_ec_sensors(struct asus_wmi_ec_info
> > > > *ec) +{
> > > > +       const struct ec_sensor_info *si;
> > > > +       struct ec_sensor *s;
> > > > +
> > > > +       u32 value;
> > > This variable is now redundant.
> > >
> > Thank you, I will look.
> >
> > > > +               if (si->addr.size == 1)
> > > Maybe switch(si->addr.size)?
> > >
> > Thank you, I will check.
> > > > +                       value = ec->read_buffer[read_reg_ct];
> > > > +               else if (si->addr.size == 2)
> > > > +                       value =
> > > > get_unaligned_le16(&ec->read_buffer[read_reg_ct]);
> > > > +               else if (si->addr.size == 4)
> > > > +                       value =
> > > > get_unaligned_le32(&ec->read_buffer[read_reg_ct]); +
> > > > +               read_reg_ct += si->addr.size;
> > > > +               s->cached_value = value;
> > > > +       }
> > > > +       return 0;
> > > > +}
> > >
> > >
> > > > +       mutex_lock(&sensor_data->lock);
> > > The mutex locking/unlocking should be moved inside the
> > > update_ec_sensors(), I guess.
> > >
> > > I re-read your answer to my question as to why don't you add module
> > > aliases to the driver, and I have to admit I don't really understand
> > > it. Could you, please, elaborate?
> > >
> > It looked complicated to support two kind of WMI interfaces with UUID.
> > As we split big support module to two separate - I will look to such
> > change also.
> >
> > > Thank you,
> > > Eugene
> >
> > Best regards,
> >      Denis.

  reply	other threads:[~2021-10-07 18:11 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-06 22:24 [PATCH v2 0/3] [PATCH v2 0/3] Update ASUS WMI supported boards Denis Pauk
2021-10-06 22:24 ` [PATCH v2 1/3] hwmon: (nct6775) Add additional ASUS motherboards Denis Pauk
2021-10-07 10:35   ` Oleksandr Natalenko
2021-10-06 22:25 ` [PATCH v2 2/3] hwmon: (asus_wmi_ec_sensors) Support B550 Asus WMI Denis Pauk
2021-10-06 23:32   ` Eugene Shalygin
2021-10-07 15:46     ` Denis Pauk
2021-10-07 17:55       ` Eugene Shalygin
2021-10-07 18:11         ` Eugene Shalygin [this message]
2021-10-09 15:44           ` Eugene Shalygin
2021-10-10 10:39           ` Denis Pauk
2021-10-10 13:46             ` Eugene Shalygin
2021-10-10 14:33               ` Guenter Roeck
2021-10-10 18:45                 ` Eugene Shalygin
2021-10-25 13:10                   ` Eugene Shalygin
2021-10-07 16:41   ` Guenter Roeck
2021-10-07 17:17     ` Denis Pauk
2021-10-07 16:47   ` Guenter Roeck
2021-10-07 17:14     ` Denis Pauk
2021-10-08 14:42   ` Eugene Shalygin
2021-10-06 22:25 ` [PATCH v2 3/3] hwmon: (asus_wmi_sensors) Support X370 " Denis Pauk
2021-10-07 10:56   ` Eugene Shalygin
2021-10-07 15:36     ` Denis Pauk
2021-10-07 16:45   ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAB95QAQ+u4DmF0e9Zvy5hDV0mFQDEULtr-newtz5_6y=Bzp+ww@mail.gmail.com' \
    --to=eugene.shalygin@gmail.com \
    --cc=andy.shevchenko@gmail.com \
    --cc=jdelvare@suse.com \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=pauk.denis@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.