public inbox for linux-hwmon@vger.kernel.org
 help / color / mirror / Atom feed
From: Andreas Kemnade <andreas@kemnade.info>
To: Guenter Roeck <linux@roeck-us.net>
Cc: Arnd Bergmann <arnd@arndb.de>,
	rydberg@bitmath.org, Jean Delvare <jdelvare@suse.com>,
	linux-hwmon@vger.kernel.org,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	hns@goldelico.com
Subject: Re: [REGRESSION] hwmon: (applesmc) avoid overlong udelay()
Date: Tue, 6 Oct 2020 09:02:26 +0200	[thread overview]
Message-ID: <20201006090226.4275c824@kemnade.info> (raw)
In-Reply-To: <7543ef85-727d-96c3-947e-5b18e9e6c44d@roeck-us.net>

[-- Attachment #1: Type: text/plain, Size: 6459 bytes --]

On Thu, 1 Oct 2020 21:07:51 -0700
Guenter Roeck <linux@roeck-us.net> wrote:

> On 10/1/20 3:22 PM, Andreas Kemnade wrote:
> > On Wed, 30 Sep 2020 22:00:09 +0200
> > Arnd Bergmann <arnd@arndb.de> wrote:
> >   
> >> On Wed, Sep 30, 2020 at 6:44 PM Guenter Roeck <linux@roeck-us.net> wrote:  
> >>>
> >>> On Wed, Sep 30, 2020 at 10:54:42AM +0200, Andreas Kemnade wrote:    
> >>>> Hi,
> >>>>
> >>>> after the $subject patch I get lots of errors like this:    
> >>>
> >>> For reference, this refers to commit fff2d0f701e6 ("hwmon: (applesmc)
> >>> avoid overlong udelay()").
> >>>    
> >>>> [  120.378614] applesmc: send_byte(0x00, 0x0300) fail: 0x40
> >>>> [  120.378621] applesmc: LKSB: write data fail
> >>>> [  120.512782] applesmc: send_byte(0x00, 0x0300) fail: 0x40
> >>>> [  120.512787] applesmc: LKSB: write data fail
> >>>>
> >>>> CPU sticks at low speed and no fan is turning on.
> >>>> Reverting this patch on top of 5.9-rc6 solves this problem.
> >>>>
> >>>> Some information from dmidecode:
> >>>>
> >>>> Base Board Information
> >>>>         Manufacturer: Apple Inc.
> >>>>         Product Name: Mac-7DF21CB3ED6977E5
> >>>>         Version: MacBookAir6,2
> >>>>
> >>>> Handle 0x0020, DMI type 11, 5 bytes OEM Strings         String 1: Apple ROM Version.  Model:       …,
> >>>> Handle 0x0020, DMI type 11, 5 bytes
> >>>> OEM Strings
> >>>>         String 1: Apple ROM Version.  Model:        MBA61.  EFI Version:  122.0.0
> >>>>         String 2: .0.0.  Built by:     root@saumon.  Date:         Wed Jun 10 18:
> >>>>         String 3: 10:36 PDT 2020.  Revision:     122 (B&I).  ROM Version:  F000_B
> >>>>         String 4: 00.  Build Type:   Official Build, Release.  Compiler:     Appl
> >>>>         String 5: e clang version 3.0 (tags/Apple/clang-211.10.1) (based on LLVM
> >>>>         String 6: 3.0svn).
> >>>>
> >>>> Writing to things in /sys/devices/platform/applesmc.768 gives also the
> >>>> said errors.
> >>>> But writing 1 to fan1_maunal and 5000 to fan1_output turns the fan on
> >>>> despite error messages.
> >>>>    
> >>> Not really sure what to do here. I could revert the patch, but then we'd gain
> >>> clang compile failures. Arnd, any idea ?    
> >>
> >> It seems that either I made a mistake in the conversion and it sleeps for
> >> less time than before, or my assumption was wrong that converting a delay to
> >> a sleep is safe here.
> >>
> >> The error message indicates that the write fails, not the read, so that
> >> is what I'd look at first. Right away I can see that the maximum time to
> >> retry is only half of what it used to be, as we used to wait for
> >> 0x10, 0x20, 0x40, 0x80, ..., 0x20000 microseconds for a total of
> >> 0x3fff0 microseconds (262ms), while my patch went with the 131ms
> >> total delay based on the comment saying "/* wait up to 128 ms for a
> >> status change. */".
> >>  
> > Yes, that is also what I read from the code. I just thought there must
> > be something simple, which just needs a short look from another pair of
> > eyes.
> >   
> >> Since there is sleeping wait, I see no reason the timeout couldn't
> >> be extended a lot, e.g. to a second, as in
> >>
> >> #define APPLESMC_MAX_WAIT 0x100000
> >>
> >> If that doesn't work, I'd try using mdelay() in place of
> >> usleep_range(), such as
> >>
> >>            mdelay(DIV_ROUND_UP(us, USEC_PER_MSEC)));
> >>
> >> This adds back a really nasty latency, but it should avoid the
> >> compile-time problem.
> >>
> >> Andreas, can you try those two things? (one at a time,
> >> not both)  
> > 
> > Ok, I tried. None of them works. I rechecked my work and created real
> > git commits out of them and CONFIG_LOCALVERSION_AUTO is also set so
> > the usual stupid things are rules out.
> > In detail:
> > On top of 5.9-rc6 + *reverted* patch:
> > diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
> > index fd99c9df8a00..2a9bd7f2b71b 100644
> > --- a/drivers/hwmon/applesmc.c
> > +++ b/drivers/hwmon/applesmc.c
> > @@ -45,7 +45,7 @@
> >  /* wait up to 128 ms for a status change. */
> >  #define APPLESMC_MIN_WAIT	0x0010
> >  #define APPLESMC_RETRY_WAIT	0x0100
> > -#define APPLESMC_MAX_WAIT	0x20000
> > +#define APPLESMC_MAX_WAIT	0x8000
> >  
> >  #define APPLESMC_READ_CMD	0x10
> >  #define APPLESMC_WRITE_CMD	0x11
> >   
> 
> Oh man, that code is so badlys broken.
> 
> send_byte() repeats sending the data if it was not immediately successful.
> That is done for both data and commands. Effectively that happens if
> the command is not immediately accepted. However, send_argument()
> clearly assumes that each data byte is sent exactly once. Sending
> it more than once will mess up the key that is supposed to be sent.
> The Apple SMC emulation code in qemu confirms that data bytes can not
> be written more than once.
> 
> Of course, theoretically it may be that the first data byte was not
> accepted (after all, the ACK bit is not set), but the ACK bit is
> not checked again after udelay(APPLESMC_RETRY_WAIT), so it may
> well have been set in the 256 uS between its check and re-writing
> the data.
> 
> In other words, this entire code only works accidentally to start with.
> 
> If you like, you could play around with the code and find out if and
> when exactly bit 1 (busy) is set, if and when bit 2 (ack) is set, and
> if and when any other bit is set. We could also try to read port 0x31e
> (the error port). Maybe the we can figure out what the error actually
> is. But then I don't really know what we could do with that information.
> 
Smoe research results: the second data byte seems to cause problems, not the
command byte.

> Other than that, the only useful idea I have is something crazy like
> 	if (us < 10000)
> 		udelay(us);
> 	else
> 		mdelay(DIV_ROUND_CLOSEST(udelay, 1000));
> in the hope that clang doesn't convert that back into a
> compile-time constant and udelay().
> 
> Overall it seems like the apple protocol may expect to receive data
> bytes faster than 1ms apart, because that is the only real difference
> between the original code and the new code using mdelay().

Yes, that explanation makes sense. If I am trying something like that, only
the last byte requires more than APPLESMC_MIN_WAIT. I have seen max. 256us.
So we could probably even use msleep for us > 1000 and udelay for anything below.

Regards,
Andreas

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2020-10-06  7:02 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-30  8:54 [REGRESSION] hwmon: (applesmc) avoid overlong udelay() Andreas Kemnade
2020-09-30 16:44 ` Guenter Roeck
2020-09-30 20:00   ` Arnd Bergmann
2020-10-01 22:22     ` Andreas Kemnade
2020-10-02  4:07       ` Guenter Roeck
2020-10-06  7:02         ` Andreas Kemnade [this message]
2020-11-02 23:56           ` Brad Campbell
2020-11-03  5:56             ` Brad Campbell
2020-11-04 13:20               ` Andreas Kemnade
2020-11-05  2:18                 ` Brad Campbell
2020-11-05  4:22                   ` Brad Campbell
2020-11-05  4:43                   ` Guenter Roeck
2020-11-05  5:05                     ` Brad Campbell
2020-11-05  5:26                       ` Guenter Roeck
2020-11-05  5:47                         ` [PATCH] applesmc: Re-work SMC comms v1 Brad Campbell
2020-11-05  7:26                           ` [PATCH] applesmc: Re-work SMC comms v2 Brad Campbell
2020-11-05  7:56                             ` Henrik Rydberg
2020-11-05  8:15                               ` Andreas Kemnade
2020-11-05  8:30                               ` Brad Campbell
2020-11-05 10:31                                 ` Henrik Rydberg
2020-11-06 16:26                                   ` Henrik Rydberg
2020-11-06 20:02                                     ` Henrik Rydberg
2020-11-07 18:31                                       ` Henrik Rydberg
2020-11-08  0:09                                         ` Brad Campbell
2020-11-08  8:22                                           ` Henrik Rydberg
2020-11-08  1:00                                         ` [PATCH v3] applesmc: Re-work SMC comms Brad Campbell
2020-11-08  8:35                                           ` Henrik Rydberg
2020-11-08 10:14                                             ` Henrik Rydberg
2020-11-08 11:57                                               ` Brad Campbell
2020-11-08 12:04                                                 ` Henrik Rydberg
2020-11-09 13:06                                                   ` Brad Campbell
2020-11-09 17:08                                                     ` Henrik Rydberg
2020-11-09 22:52                                                       ` Brad Campbell
2020-11-08 16:06                                               ` Guenter Roeck
2020-11-09  0:25                                                 ` Brad Campbell
2020-11-10  2:04                                                 ` Brad Campbell
2020-11-10  4:55                                                   ` Guenter Roeck
2020-11-10  5:40                                                     ` Brad Campbell
2020-11-10 16:02                                                       ` Guenter Roeck
2020-11-09  8:44                                               ` Andreas Kemnade
2020-11-09  9:51                                                 ` Brad Campbell
2020-11-11  3:37                                           ` [PATCH v4 0/1] " Brad Campbell
2020-11-11  4:55                                             ` [PATCH v1] applesmc: Cleanups on top of re-work comms Brad Campbell
2020-11-11  3:38                                           ` [PATCH v4 1/1] applesmc: Re-work SMC comms Brad Campbell
2020-11-11  5:56                                             ` Guenter Roeck
2020-11-11  7:05                                               ` Brad Campbell
2020-11-11 13:06                                               ` [PATCH v5 " Brad Campbell
2020-11-11 20:05                                                 ` Henrik Rydberg
2020-11-11 23:28                                                   ` Brad Campbell
2020-11-12  3:08                                                 ` [PATCH v6 " Brad Campbell
2020-11-12 17:20                                                   ` Guenter Roeck
2020-11-06 23:11                                     ` [PATCH] applesmc: Re-work SMC comms v2 Brad Campbell
2020-11-05  8:12                             ` Andreas Kemnade
2020-11-05 16:12                             ` Guenter Roeck
2020-11-06  0:02                               ` Brad Campbell
2020-11-06  3:08                                 ` Guenter Roeck
2020-11-09  9:27                           ` [PATCH] applesmc: Re-work SMC comms v1 kernel test robot
2020-11-05  9:48                       ` [REGRESSION] hwmon: (applesmc) avoid overlong udelay() Arnd Bergmann

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=20201006090226.4275c824@kemnade.info \
    --to=andreas@kemnade.info \
    --cc=arnd@arndb.de \
    --cc=hns@goldelico.com \
    --cc=jdelvare@suse.com \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=rydberg@bitmath.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox