* [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
@ 2024-08-29 16:50 Andy Shevchenko
2024-09-03 15:00 ` Gergo Koteles
` (2 more replies)
0 siblings, 3 replies; 17+ messages in thread
From: Andy Shevchenko @ 2024-08-29 16:50 UTC (permalink / raw)
To: Ilpo Järvinen, Gergo Koteles, Hans de Goede,
platform-driver-x86, linux-kernel
Cc: Ike Panhc, Peter Zijlstra, Josh Poimboeuf, Nathan Chancellor,
Andy Shevchenko, kernel test robot
First of all, it's a bit counterintuitive to have something like
int err;
...
scoped_guard(...)
err = foo(...);
if (err)
return err;
Second, with a particular kernel configuration and compiler version in
one of such cases the objtool is not happy:
ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
I'm not an expert on all this, but the theory is that compiler and
linker in this case can't understand that 'result' variable will be
always initialized as long as no error has been returned. Assigning
'result' to a dummy value helps with this. Note, that fixing the
scoped_guard() scope (as per above) does not make issue gone.
That said, assign dummy value and make the scope_guard() clear of its scope.
For the sake of consistency do it in the entire file.
Fixes: 7cc06e729460 ("platform/x86: ideapad-laptop: add a mutex to synchronize VPC commands")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202408290219.BrPO8twi-lkp@intel.com/
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
This has been Cc'ed to objtool and clang maintainers to have a look and
tell if this can be addressed in a better way.
drivers/platform/x86/ideapad-laptop.c | 48 +++++++++++++++------------
1 file changed, 27 insertions(+), 21 deletions(-)
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 35c75bcff195..c64dfc56651d 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -554,13 +554,14 @@ static ssize_t camera_power_show(struct device *dev,
char *buf)
{
struct ideapad_private *priv = dev_get_drvdata(dev);
- unsigned long result;
+ unsigned long result = 0;
int err;
- scoped_guard(mutex, &priv->vpc_mutex)
+ scoped_guard(mutex, &priv->vpc_mutex) {
err = read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &result);
- if (err)
- return err;
+ if (err)
+ return err;
+ }
return sysfs_emit(buf, "%d\n", !!result);
}
@@ -577,10 +578,11 @@ static ssize_t camera_power_store(struct device *dev,
if (err)
return err;
- scoped_guard(mutex, &priv->vpc_mutex)
+ scoped_guard(mutex, &priv->vpc_mutex) {
err = write_ec_cmd(priv->adev->handle, VPCCMD_W_CAMERA, state);
- if (err)
- return err;
+ if (err)
+ return err;
+ }
return count;
}
@@ -628,13 +630,14 @@ static ssize_t fan_mode_show(struct device *dev,
char *buf)
{
struct ideapad_private *priv = dev_get_drvdata(dev);
- unsigned long result;
+ unsigned long result = 0;
int err;
- scoped_guard(mutex, &priv->vpc_mutex)
+ scoped_guard(mutex, &priv->vpc_mutex) {
err = read_ec_data(priv->adev->handle, VPCCMD_R_FAN, &result);
- if (err)
- return err;
+ if (err)
+ return err;
+ }
return sysfs_emit(buf, "%lu\n", result);
}
@@ -654,10 +657,11 @@ static ssize_t fan_mode_store(struct device *dev,
if (state > 4 || state == 3)
return -EINVAL;
- scoped_guard(mutex, &priv->vpc_mutex)
+ scoped_guard(mutex, &priv->vpc_mutex) {
err = write_ec_cmd(priv->adev->handle, VPCCMD_W_FAN, state);
- if (err)
- return err;
+ if (err)
+ return err;
+ }
return count;
}
@@ -737,13 +741,14 @@ static ssize_t touchpad_show(struct device *dev,
char *buf)
{
struct ideapad_private *priv = dev_get_drvdata(dev);
- unsigned long result;
+ unsigned long result = 0;
int err;
- scoped_guard(mutex, &priv->vpc_mutex)
+ scoped_guard(mutex, &priv->vpc_mutex) {
err = read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &result);
- if (err)
- return err;
+ if (err)
+ return err;
+ }
priv->r_touchpad_val = result;
@@ -762,10 +767,11 @@ static ssize_t touchpad_store(struct device *dev,
if (err)
return err;
- scoped_guard(mutex, &priv->vpc_mutex)
+ scoped_guard(mutex, &priv->vpc_mutex) {
err = write_ec_cmd(priv->adev->handle, VPCCMD_W_TOUCHPAD, state);
- if (err)
- return err;
+ if (err)
+ return err;
+ }
priv->r_touchpad_val = state;
--
2.43.0.rc1.1336.g36b5255a03ac
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-08-29 16:50 [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope Andy Shevchenko
@ 2024-09-03 15:00 ` Gergo Koteles
2024-09-03 15:14 ` Andy Shevchenko
2024-09-04 4:52 ` Josh Poimboeuf
2024-09-04 18:14 ` Hans de Goede
2 siblings, 1 reply; 17+ messages in thread
From: Gergo Koteles @ 2024-09-03 15:00 UTC (permalink / raw)
To: Andy Shevchenko, Ilpo Järvinen, Hans de Goede,
platform-driver-x86, linux-kernel
Cc: Ike Panhc, Peter Zijlstra, Josh Poimboeuf, Nathan Chancellor,
kernel test robot
Hi Andy,
Thank you for addressing this.
On Thu, 2024-08-29 at 19:50 +0300, Andy Shevchenko wrote:
> First of all, it's a bit counterintuitive to have something like
>
> int err;
> ...
> scoped_guard(...)
> err = foo(...);
> if (err)
> return err;
>
> Second, with a particular kernel configuration and compiler version in
> one of such cases the objtool is not happy:
>
> ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
>
> I'm not an expert on all this, but the theory is that compiler and
> linker in this case can't understand that 'result' variable will be
> always initialized as long as no error has been returned. Assigning
> 'result' to a dummy value helps with this. Note, that fixing the
> scoped_guard() scope (as per above) does not make issue gone.
>
> That said, assign dummy value and make the scope_guard() clear of its scope.
> For the sake of consistency do it in the entire file.
>
Interestingly, if I open a scope manually and use the plain guard, the
warning disappears.
...
unsigned long result;
int err;
{
guard(mutex)(&priv->vpc_mutex);
err = read_ec_data(priv->adev->handle, VPCCMD_R_FAN,
&result);
if (err)
return err;
}
...
This looks a bit strange, but is probably easier for the compiler than
the for loop of scoped_guard.
But I don't know how well this style fits into the kernel.
Best regards,
Gergo Koteles
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-09-03 15:00 ` Gergo Koteles
@ 2024-09-03 15:14 ` Andy Shevchenko
2024-09-03 15:29 ` Gergo Koteles
0 siblings, 1 reply; 17+ messages in thread
From: Andy Shevchenko @ 2024-09-03 15:14 UTC (permalink / raw)
To: Gergo Koteles
Cc: Ilpo Järvinen, Hans de Goede, platform-driver-x86,
linux-kernel, Ike Panhc, Peter Zijlstra, Josh Poimboeuf,
Nathan Chancellor, kernel test robot
On Tue, Sep 03, 2024 at 05:00:51PM +0200, Gergo Koteles wrote:
> On Thu, 2024-08-29 at 19:50 +0300, Andy Shevchenko wrote:
> > First of all, it's a bit counterintuitive to have something like
> >
> > int err;
> > ...
> > scoped_guard(...)
> > err = foo(...);
> > if (err)
> > return err;
> >
> > Second, with a particular kernel configuration and compiler version in
> > one of such cases the objtool is not happy:
> >
> > ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
> >
> > I'm not an expert on all this, but the theory is that compiler and
> > linker in this case can't understand that 'result' variable will be
> > always initialized as long as no error has been returned. Assigning
> > 'result' to a dummy value helps with this. Note, that fixing the
> > scoped_guard() scope (as per above) does not make issue gone.
> >
> > That said, assign dummy value and make the scope_guard() clear of its scope.
> > For the sake of consistency do it in the entire file.
> >
>
> Interestingly, if I open a scope manually and use the plain guard, the
> warning disappears.
Yes, that's what I also have, but I avoid that approach because in that case
the printing will be done inside the lock, widening the critical section for
no benefits.
> ...
> unsigned long result;
> int err;
>
> {
> guard(mutex)(&priv->vpc_mutex);
> err = read_ec_data(priv->adev->handle, VPCCMD_R_FAN,
> &result);
> if (err)
> return err;
> }
> ...
>
> This looks a bit strange, but is probably easier for the compiler than
> the for loop of scoped_guard.
>
> But I don't know how well this style fits into the kernel.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-09-03 15:14 ` Andy Shevchenko
@ 2024-09-03 15:29 ` Gergo Koteles
2024-09-03 15:40 ` Andy Shevchenko
2024-09-04 13:37 ` Ilpo Järvinen
0 siblings, 2 replies; 17+ messages in thread
From: Gergo Koteles @ 2024-09-03 15:29 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Ilpo Järvinen, Hans de Goede, platform-driver-x86,
linux-kernel, Ike Panhc, Peter Zijlstra, Josh Poimboeuf,
Nathan Chancellor, kernel test robot
On Tue, 2024-09-03 at 18:14 +0300, Andy Shevchenko wrote:
> On Tue, Sep 03, 2024 at 05:00:51PM +0200, Gergo Koteles wrote:
> > On Thu, 2024-08-29 at 19:50 +0300, Andy Shevchenko wrote:
> > > First of all, it's a bit counterintuitive to have something like
> > >
> > > int err;
> > > ...
> > > scoped_guard(...)
> > > err = foo(...);
> > > if (err)
> > > return err;
> > >
> > > Second, with a particular kernel configuration and compiler version in
> > > one of such cases the objtool is not happy:
> > >
> > > ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
> > >
> > > I'm not an expert on all this, but the theory is that compiler and
> > > linker in this case can't understand that 'result' variable will be
> > > always initialized as long as no error has been returned. Assigning
> > > 'result' to a dummy value helps with this. Note, that fixing the
> > > scoped_guard() scope (as per above) does not make issue gone.
> > >
> > > That said, assign dummy value and make the scope_guard() clear of its scope.
> > > For the sake of consistency do it in the entire file.
> > >
> >
> > Interestingly, if I open a scope manually and use the plain guard, the
> > warning disappears.
>
> Yes, that's what I also have, but I avoid that approach because in that case
> the printing will be done inside the lock, widening the critical section for
> no benefits.
>
This is intended to be an inner block scope within the function, it
does not expand the critical section.
> > ...
> > unsigned long result;
> > int err;
> >
> > {
> > guard(mutex)(&priv->vpc_mutex);
> > err = read_ec_data(priv->adev->handle, VPCCMD_R_FAN,
> > &result);
> > if (err)
> > return err;
> > }
> > ...
> >
> > This looks a bit strange, but is probably easier for the compiler than
> > the for loop of scoped_guard.
> >
> > But I don't know how well this style fits into the kernel.
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-09-03 15:29 ` Gergo Koteles
@ 2024-09-03 15:40 ` Andy Shevchenko
2024-09-04 1:22 ` Nathan Chancellor
2024-09-04 13:37 ` Ilpo Järvinen
1 sibling, 1 reply; 17+ messages in thread
From: Andy Shevchenko @ 2024-09-03 15:40 UTC (permalink / raw)
To: Gergo Koteles
Cc: Ilpo Järvinen, Hans de Goede, platform-driver-x86,
linux-kernel, Ike Panhc, Peter Zijlstra, Josh Poimboeuf,
Nathan Chancellor, kernel test robot
On Tue, Sep 03, 2024 at 05:29:02PM +0200, Gergo Koteles wrote:
> On Tue, 2024-09-03 at 18:14 +0300, Andy Shevchenko wrote:
> > On Tue, Sep 03, 2024 at 05:00:51PM +0200, Gergo Koteles wrote:
> > > On Thu, 2024-08-29 at 19:50 +0300, Andy Shevchenko wrote:
> > > > First of all, it's a bit counterintuitive to have something like
> > > >
> > > > int err;
> > > > ...
> > > > scoped_guard(...)
> > > > err = foo(...);
> > > > if (err)
> > > > return err;
> > > >
> > > > Second, with a particular kernel configuration and compiler version in
> > > > one of such cases the objtool is not happy:
> > > >
> > > > ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
> > > >
> > > > I'm not an expert on all this, but the theory is that compiler and
> > > > linker in this case can't understand that 'result' variable will be
> > > > always initialized as long as no error has been returned. Assigning
> > > > 'result' to a dummy value helps with this. Note, that fixing the
> > > > scoped_guard() scope (as per above) does not make issue gone.
> > > >
> > > > That said, assign dummy value and make the scope_guard() clear of its scope.
> > > > For the sake of consistency do it in the entire file.
> > > >
> > >
> > > Interestingly, if I open a scope manually and use the plain guard, the
> > > warning disappears.
> >
> > Yes, that's what I also have, but I avoid that approach because in that case
> > the printing will be done inside the lock, widening the critical section for
> > no benefits.
> >
>
> This is intended to be an inner block scope within the function, it
> does not expand the critical section.
I'm not sure I understand.
scoped_guard() has a marked scope (with {} or just a line coupled with it).
The guard() has a scope starting at it till the end of the function. In the
latter case the sysfs_emit() becomes part of the critical section.
> > > unsigned long result;
> > > int err;
> > >
> > > {
> > > guard(mutex)(&priv->vpc_mutex);
> > > err = read_ec_data(priv->adev->handle, VPCCMD_R_FAN,
> > > &result);
> > > if (err)
> > > return err;
> > > }
But looking again into the code above now I got what you meant.
You have added a nested scope inside the function, like
do {
...
} while (0);
Yes, this is strange and not what we want to have either. So I prefer to hear
what objtool / clang people may comment on this.
Sorry that I missed this.
> > > This looks a bit strange, but is probably easier for the compiler than
> > > the for loop of scoped_guard.
> > >
> > > But I don't know how well this style fits into the kernel.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-09-03 15:40 ` Andy Shevchenko
@ 2024-09-04 1:22 ` Nathan Chancellor
2024-09-04 10:28 ` Andy Shevchenko
0 siblings, 1 reply; 17+ messages in thread
From: Nathan Chancellor @ 2024-09-04 1:22 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Gergo Koteles, Ilpo Järvinen, Hans de Goede,
platform-driver-x86, linux-kernel, Ike Panhc, Peter Zijlstra,
Josh Poimboeuf, kernel test robot
Hi Andy,
On Tue, Sep 03, 2024 at 06:40:16PM +0300, Andy Shevchenko wrote:
> On Tue, Sep 03, 2024 at 05:29:02PM +0200, Gergo Koteles wrote:
> > On Tue, 2024-09-03 at 18:14 +0300, Andy Shevchenko wrote:
> > > On Tue, Sep 03, 2024 at 05:00:51PM +0200, Gergo Koteles wrote:
> > > > On Thu, 2024-08-29 at 19:50 +0300, Andy Shevchenko wrote:
> > > > > First of all, it's a bit counterintuitive to have something like
> > > > >
> > > > > int err;
> > > > > ...
> > > > > scoped_guard(...)
> > > > > err = foo(...);
> > > > > if (err)
> > > > > return err;
> > > > >
> > > > > Second, with a particular kernel configuration and compiler version in
> > > > > one of such cases the objtool is not happy:
> > > > >
> > > > > ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
> > > > >
> > > > > I'm not an expert on all this, but the theory is that compiler and
> > > > > linker in this case can't understand that 'result' variable will be
> > > > > always initialized as long as no error has been returned. Assigning
> > > > > 'result' to a dummy value helps with this. Note, that fixing the
> > > > > scoped_guard() scope (as per above) does not make issue gone.
> > > > >
> > > > > That said, assign dummy value and make the scope_guard() clear of its scope.
> > > > > For the sake of consistency do it in the entire file.
> > > > >
> > > >
> > > > Interestingly, if I open a scope manually and use the plain guard, the
> > > > warning disappears.
> > >
> > > Yes, that's what I also have, but I avoid that approach because in that case
> > > the printing will be done inside the lock, widening the critical section for
> > > no benefits.
> > >
> >
> > This is intended to be an inner block scope within the function, it
> > does not expand the critical section.
>
> I'm not sure I understand.
>
> scoped_guard() has a marked scope (with {} or just a line coupled with it).
> The guard() has a scope starting at it till the end of the function. In the
> latter case the sysfs_emit() becomes part of the critical section.
>
> > > > unsigned long result;
> > > > int err;
> > > >
> > > > {
> > > > guard(mutex)(&priv->vpc_mutex);
> > > > err = read_ec_data(priv->adev->handle, VPCCMD_R_FAN,
> > > > &result);
> > > > if (err)
> > > > return err;
> > > > }
>
> But looking again into the code above now I got what you meant.
> You have added a nested scope inside the function, like
>
> do {
> ...
> } while (0);
>
> Yes, this is strange and not what we want to have either. So I prefer to hear
> what objtool / clang people may comment on this.
So this does not appear to happen when CONFIG_KCOV is disabled with the
configuration from the original report. I have spent some time looking
at the disassembly but I am a little out of my element there. If I
remember correctly, the "unexpected end of section" warning from objtool
can appear when optimizations play fast and loose with the presence of
potential undefined behavior (or cannot prove that there is no undefined
behavior through inlining or analysis). In this case, I wonder if KCOV
prevents LLVM from realizing that the for loop that scoped_guard()
results in will run at least once, meaning that err and result would be
potentially used uninitialized? That could explain why this change
resolves the warning, as it ensures that no undefined behavior could
happen regardless of whether or not the loop runs?
Josh and Peter may have more insight.
Cheers,
Nathan
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-08-29 16:50 [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope Andy Shevchenko
2024-09-03 15:00 ` Gergo Koteles
@ 2024-09-04 4:52 ` Josh Poimboeuf
2024-09-04 10:26 ` Andy Shevchenko
2024-09-04 18:14 ` Hans de Goede
2 siblings, 1 reply; 17+ messages in thread
From: Josh Poimboeuf @ 2024-09-04 4:52 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Ilpo Järvinen, Gergo Koteles, Hans de Goede,
platform-driver-x86, linux-kernel, Ike Panhc, Peter Zijlstra,
Nathan Chancellor, kernel test robot
On Thu, Aug 29, 2024 at 07:50:32PM +0300, Andy Shevchenko wrote:
> First of all, it's a bit counterintuitive to have something like
>
> int err;
> ...
> scoped_guard(...)
> err = foo(...);
> if (err)
> return err;
>
> Second, with a particular kernel configuration and compiler version in
> one of such cases the objtool is not happy:
>
> ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
>
> I'm not an expert on all this, but the theory is that compiler and
> linker in this case can't understand that 'result' variable will be
> always initialized as long as no error has been returned. Assigning
> 'result' to a dummy value helps with this. Note, that fixing the
> scoped_guard() scope (as per above) does not make issue gone.
I'm not sure I buy that, we should look closer to understand what the
issue is. Can you share the config and/or toolchain version(s) need to
trigger the warning?
--
Josh
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-09-04 4:52 ` Josh Poimboeuf
@ 2024-09-04 10:26 ` Andy Shevchenko
2024-09-06 3:16 ` Josh Poimboeuf
0 siblings, 1 reply; 17+ messages in thread
From: Andy Shevchenko @ 2024-09-04 10:26 UTC (permalink / raw)
To: Josh Poimboeuf
Cc: Ilpo Järvinen, Gergo Koteles, Hans de Goede,
platform-driver-x86, linux-kernel, Ike Panhc, Peter Zijlstra,
Nathan Chancellor, kernel test robot
On Tue, Sep 03, 2024 at 09:52:01PM -0700, Josh Poimboeuf wrote:
> On Thu, Aug 29, 2024 at 07:50:32PM +0300, Andy Shevchenko wrote:
> > First of all, it's a bit counterintuitive to have something like
> >
> > int err;
> > ...
> > scoped_guard(...)
> > err = foo(...);
> > if (err)
> > return err;
> >
> > Second, with a particular kernel configuration and compiler version in
> > one of such cases the objtool is not happy:
> >
> > ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
> >
> > I'm not an expert on all this, but the theory is that compiler and
> > linker in this case can't understand that 'result' variable will be
> > always initialized as long as no error has been returned. Assigning
> > 'result' to a dummy value helps with this. Note, that fixing the
> > scoped_guard() scope (as per above) does not make issue gone.
>
> I'm not sure I buy that, we should look closer to understand what the
> issue is. Can you share the config and/or toolchain version(s) need to
> trigger the warning?
.config is from the original report [1], toolchain is
Debian clang version 18.1.8 (9)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
(Just whatever Debian unstable provides)
[1]: https://lore.kernel.org/oe-kbuild-all/202408290219.BrPO8twi-lkp@intel.com/
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-09-04 1:22 ` Nathan Chancellor
@ 2024-09-04 10:28 ` Andy Shevchenko
0 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2024-09-04 10:28 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Gergo Koteles, Ilpo Järvinen, Hans de Goede,
platform-driver-x86, linux-kernel, Ike Panhc, Peter Zijlstra,
Josh Poimboeuf, kernel test robot
On Tue, Sep 03, 2024 at 06:22:42PM -0700, Nathan Chancellor wrote:
> On Tue, Sep 03, 2024 at 06:40:16PM +0300, Andy Shevchenko wrote:
> > On Tue, Sep 03, 2024 at 05:29:02PM +0200, Gergo Koteles wrote:
> > > On Tue, 2024-09-03 at 18:14 +0300, Andy Shevchenko wrote:
> > > > On Tue, Sep 03, 2024 at 05:00:51PM +0200, Gergo Koteles wrote:
> > > > > On Thu, 2024-08-29 at 19:50 +0300, Andy Shevchenko wrote:
> > > > > > First of all, it's a bit counterintuitive to have something like
> > > > > >
> > > > > > int err;
> > > > > > ...
> > > > > > scoped_guard(...)
> > > > > > err = foo(...);
> > > > > > if (err)
> > > > > > return err;
> > > > > >
> > > > > > Second, with a particular kernel configuration and compiler version in
> > > > > > one of such cases the objtool is not happy:
> > > > > >
> > > > > > ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
> > > > > >
> > > > > > I'm not an expert on all this, but the theory is that compiler and
> > > > > > linker in this case can't understand that 'result' variable will be
> > > > > > always initialized as long as no error has been returned. Assigning
> > > > > > 'result' to a dummy value helps with this. Note, that fixing the
> > > > > > scoped_guard() scope (as per above) does not make issue gone.
> > > > > >
> > > > > > That said, assign dummy value and make the scope_guard() clear of its scope.
> > > > > > For the sake of consistency do it in the entire file.
> > > > > >
> > > > >
> > > > > Interestingly, if I open a scope manually and use the plain guard, the
> > > > > warning disappears.
> > > >
> > > > Yes, that's what I also have, but I avoid that approach because in that case
> > > > the printing will be done inside the lock, widening the critical section for
> > > > no benefits.
> > > >
> > >
> > > This is intended to be an inner block scope within the function, it
> > > does not expand the critical section.
> >
> > I'm not sure I understand.
> >
> > scoped_guard() has a marked scope (with {} or just a line coupled with it).
> > The guard() has a scope starting at it till the end of the function. In the
> > latter case the sysfs_emit() becomes part of the critical section.
> >
> > > > > unsigned long result;
> > > > > int err;
> > > > >
> > > > > {
> > > > > guard(mutex)(&priv->vpc_mutex);
> > > > > err = read_ec_data(priv->adev->handle, VPCCMD_R_FAN,
> > > > > &result);
> > > > > if (err)
> > > > > return err;
> > > > > }
> >
> > But looking again into the code above now I got what you meant.
> > You have added a nested scope inside the function, like
> >
> > do {
> > ...
> > } while (0);
> >
> > Yes, this is strange and not what we want to have either. So I prefer to hear
> > what objtool / clang people may comment on this.
>
> So this does not appear to happen when CONFIG_KCOV is disabled with the
> configuration from the original report. I have spent some time looking
> at the disassembly but I am a little out of my element there. If I
> remember correctly, the "unexpected end of section" warning from objtool
> can appear when optimizations play fast and loose with the presence of
> potential undefined behavior (or cannot prove that there is no undefined
> behavior through inlining or analysis). In this case, I wonder if KCOV
> prevents LLVM from realizing that the for loop that scoped_guard()
> results in will run at least once, meaning that err and result would be
> potentially used uninitialized? That could explain why this change
> resolves the warning, as it ensures that no undefined behavior could
> happen regardless of whether or not the loop runs?
>
> Josh and Peter may have more insight.
Thanks for looking into this. Josh already keeps an eye on this.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-09-03 15:29 ` Gergo Koteles
2024-09-03 15:40 ` Andy Shevchenko
@ 2024-09-04 13:37 ` Ilpo Järvinen
1 sibling, 0 replies; 17+ messages in thread
From: Ilpo Järvinen @ 2024-09-04 13:37 UTC (permalink / raw)
To: Gergo Koteles
Cc: Andy Shevchenko, Hans de Goede, platform-driver-x86, LKML,
Ike Panhc, Peter Zijlstra, Josh Poimboeuf, Nathan Chancellor,
kernel test robot
On Tue, 3 Sep 2024, Gergo Koteles wrote:
> On Tue, 2024-09-03 at 18:14 +0300, Andy Shevchenko wrote:
> > On Tue, Sep 03, 2024 at 05:00:51PM +0200, Gergo Koteles wrote:
> > > On Thu, 2024-08-29 at 19:50 +0300, Andy Shevchenko wrote:
> > > > First of all, it's a bit counterintuitive to have something like
> > > >
> > > > int err;
> > > > ...
> > > > scoped_guard(...)
> > > > err = foo(...);
> > > > if (err)
> > > > return err;
> > > >
> > > > Second, with a particular kernel configuration and compiler version in
> > > > one of such cases the objtool is not happy:
> > > >
> > > > ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
> > > >
> > > > I'm not an expert on all this, but the theory is that compiler and
> > > > linker in this case can't understand that 'result' variable will be
> > > > always initialized as long as no error has been returned. Assigning
> > > > 'result' to a dummy value helps with this. Note, that fixing the
> > > > scoped_guard() scope (as per above) does not make issue gone.
> > > >
> > > > That said, assign dummy value and make the scope_guard() clear of its scope.
> > > > For the sake of consistency do it in the entire file.
> > > >
> > >
> > > Interestingly, if I open a scope manually and use the plain guard, the
> > > warning disappears.
> >
> > Yes, that's what I also have, but I avoid that approach because in that case
> > the printing will be done inside the lock, widening the critical section for
> > no benefits.
> >
>
> This is intended to be an inner block scope within the function, it
> does not expand the critical section.
>
>
> > > ...
> > > unsigned long result;
> > > int err;
> > >
> > > {
> > > guard(mutex)(&priv->vpc_mutex);
> > > err = read_ec_data(priv->adev->handle, VPCCMD_R_FAN,
> > > &result);
> > > if (err)
> > > return err;
> > > }
> > > ...
> > >
> > > This looks a bit strange, but is probably easier for the compiler than
> > > the for loop of scoped_guard.
> > >
> > > But I don't know how well this style fits into the kernel.
It's ugly enough that I'd prefer the initialization of results variable as
done in Andy's patch.
--
i.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-08-29 16:50 [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope Andy Shevchenko
2024-09-03 15:00 ` Gergo Koteles
2024-09-04 4:52 ` Josh Poimboeuf
@ 2024-09-04 18:14 ` Hans de Goede
2024-09-04 20:18 ` Andy Shevchenko
2 siblings, 1 reply; 17+ messages in thread
From: Hans de Goede @ 2024-09-04 18:14 UTC (permalink / raw)
To: Andy Shevchenko, Ilpo Järvinen, Gergo Koteles,
platform-driver-x86, linux-kernel
Cc: Ike Panhc, Peter Zijlstra, Josh Poimboeuf, Nathan Chancellor,
kernel test robot
Hi,
On 8/29/24 6:50 PM, Andy Shevchenko wrote:
> First of all, it's a bit counterintuitive to have something like
>
> int err;
> ...
> scoped_guard(...)
> err = foo(...);
> if (err)
> return err;
>
> Second, with a particular kernel configuration and compiler version in
> one of such cases the objtool is not happy:
>
> ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
>
> I'm not an expert on all this, but the theory is that compiler and
> linker in this case can't understand that 'result' variable will be
> always initialized as long as no error has been returned. Assigning
> 'result' to a dummy value helps with this. Note, that fixing the
> scoped_guard() scope (as per above) does not make issue gone.
>
> That said, assign dummy value and make the scope_guard() clear of its scope.
> For the sake of consistency do it in the entire file.
>
> Fixes: 7cc06e729460 ("platform/x86: ideapad-laptop: add a mutex to synchronize VPC commands")
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202408290219.BrPO8twi-lkp@intel.com/
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Thank you for your patch, I've applied this patch to my review-hans
branch:
https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/log/?h=review-hans
Note it will show up in my review-hans branch once I've pushed my
local branch there, which might take a while.
Once I've run some tests on this branch the patches there will be
added to the platform-drivers-x86/for-next branch and eventually
will be included in the pdx86 pull-request to Linus for the next
merge-window.
Regards,
Hans
> ---
>
> This has been Cc'ed to objtool and clang maintainers to have a look and
> tell if this can be addressed in a better way.
>
> drivers/platform/x86/ideapad-laptop.c | 48 +++++++++++++++------------
> 1 file changed, 27 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
> index 35c75bcff195..c64dfc56651d 100644
> --- a/drivers/platform/x86/ideapad-laptop.c
> +++ b/drivers/platform/x86/ideapad-laptop.c
> @@ -554,13 +554,14 @@ static ssize_t camera_power_show(struct device *dev,
> char *buf)
> {
> struct ideapad_private *priv = dev_get_drvdata(dev);
> - unsigned long result;
> + unsigned long result = 0;
> int err;
>
> - scoped_guard(mutex, &priv->vpc_mutex)
> + scoped_guard(mutex, &priv->vpc_mutex) {
> err = read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &result);
> - if (err)
> - return err;
> + if (err)
> + return err;
> + }
>
> return sysfs_emit(buf, "%d\n", !!result);
> }
> @@ -577,10 +578,11 @@ static ssize_t camera_power_store(struct device *dev,
> if (err)
> return err;
>
> - scoped_guard(mutex, &priv->vpc_mutex)
> + scoped_guard(mutex, &priv->vpc_mutex) {
> err = write_ec_cmd(priv->adev->handle, VPCCMD_W_CAMERA, state);
> - if (err)
> - return err;
> + if (err)
> + return err;
> + }
>
> return count;
> }
> @@ -628,13 +630,14 @@ static ssize_t fan_mode_show(struct device *dev,
> char *buf)
> {
> struct ideapad_private *priv = dev_get_drvdata(dev);
> - unsigned long result;
> + unsigned long result = 0;
> int err;
>
> - scoped_guard(mutex, &priv->vpc_mutex)
> + scoped_guard(mutex, &priv->vpc_mutex) {
> err = read_ec_data(priv->adev->handle, VPCCMD_R_FAN, &result);
> - if (err)
> - return err;
> + if (err)
> + return err;
> + }
>
> return sysfs_emit(buf, "%lu\n", result);
> }
> @@ -654,10 +657,11 @@ static ssize_t fan_mode_store(struct device *dev,
> if (state > 4 || state == 3)
> return -EINVAL;
>
> - scoped_guard(mutex, &priv->vpc_mutex)
> + scoped_guard(mutex, &priv->vpc_mutex) {
> err = write_ec_cmd(priv->adev->handle, VPCCMD_W_FAN, state);
> - if (err)
> - return err;
> + if (err)
> + return err;
> + }
>
> return count;
> }
> @@ -737,13 +741,14 @@ static ssize_t touchpad_show(struct device *dev,
> char *buf)
> {
> struct ideapad_private *priv = dev_get_drvdata(dev);
> - unsigned long result;
> + unsigned long result = 0;
> int err;
>
> - scoped_guard(mutex, &priv->vpc_mutex)
> + scoped_guard(mutex, &priv->vpc_mutex) {
> err = read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &result);
> - if (err)
> - return err;
> + if (err)
> + return err;
> + }
>
> priv->r_touchpad_val = result;
>
> @@ -762,10 +767,11 @@ static ssize_t touchpad_store(struct device *dev,
> if (err)
> return err;
>
> - scoped_guard(mutex, &priv->vpc_mutex)
> + scoped_guard(mutex, &priv->vpc_mutex) {
> err = write_ec_cmd(priv->adev->handle, VPCCMD_W_TOUCHPAD, state);
> - if (err)
> - return err;
> + if (err)
> + return err;
> + }
>
> priv->r_touchpad_val = state;
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-09-04 18:14 ` Hans de Goede
@ 2024-09-04 20:18 ` Andy Shevchenko
2024-09-05 8:33 ` Hans de Goede
0 siblings, 1 reply; 17+ messages in thread
From: Andy Shevchenko @ 2024-09-04 20:18 UTC (permalink / raw)
To: Hans de Goede
Cc: Andy Shevchenko, Ilpo Järvinen, Gergo Koteles,
platform-driver-x86, linux-kernel, Ike Panhc, Peter Zijlstra,
Josh Poimboeuf, Nathan Chancellor, kernel test robot
Wed, Sep 04, 2024 at 08:14:53PM +0200, Hans de Goede kirjoitti:
> Hi,
>
> On 8/29/24 6:50 PM, Andy Shevchenko wrote:
> > First of all, it's a bit counterintuitive to have something like
> >
> > int err;
> > ...
> > scoped_guard(...)
> > err = foo(...);
> > if (err)
> > return err;
> >
> > Second, with a particular kernel configuration and compiler version in
> > one of such cases the objtool is not happy:
> >
> > ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
> >
> > I'm not an expert on all this, but the theory is that compiler and
> > linker in this case can't understand that 'result' variable will be
> > always initialized as long as no error has been returned. Assigning
> > 'result' to a dummy value helps with this. Note, that fixing the
> > scoped_guard() scope (as per above) does not make issue gone.
> >
> > That said, assign dummy value and make the scope_guard() clear of its scope.
> > For the sake of consistency do it in the entire file.
> >
> > Fixes: 7cc06e729460 ("platform/x86: ideapad-laptop: add a mutex to synchronize VPC commands")
> > Reported-by: kernel test robot <lkp@intel.com>
> > Closes: https://lore.kernel.org/oe-kbuild-all/202408290219.BrPO8twi-lkp@intel.com/
> > Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Thank you for your patch, I've applied this patch to my review-hans
> branch:
> https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/log/?h=review-hans
Have you had a chance to go through the discussion?
TL;DR: please defer this. There is still no clear understanding of the root
cause and the culprit.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-09-04 20:18 ` Andy Shevchenko
@ 2024-09-05 8:33 ` Hans de Goede
2024-09-05 8:36 ` Andy Shevchenko
0 siblings, 1 reply; 17+ messages in thread
From: Hans de Goede @ 2024-09-05 8:33 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Andy Shevchenko, Ilpo Järvinen, Gergo Koteles,
platform-driver-x86, linux-kernel, Ike Panhc, Peter Zijlstra,
Josh Poimboeuf, Nathan Chancellor, kernel test robot
Hi Andy,
On 9/4/24 10:18 PM, Andy Shevchenko wrote:
> Wed, Sep 04, 2024 at 08:14:53PM +0200, Hans de Goede kirjoitti:
>> Hi,
>>
>> On 8/29/24 6:50 PM, Andy Shevchenko wrote:
>>> First of all, it's a bit counterintuitive to have something like
>>>
>>> int err;
>>> ...
>>> scoped_guard(...)
>>> err = foo(...);
>>> if (err)
>>> return err;
>>>
>>> Second, with a particular kernel configuration and compiler version in
>>> one of such cases the objtool is not happy:
>>>
>>> ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
>>>
>>> I'm not an expert on all this, but the theory is that compiler and
>>> linker in this case can't understand that 'result' variable will be
>>> always initialized as long as no error has been returned. Assigning
>>> 'result' to a dummy value helps with this. Note, that fixing the
>>> scoped_guard() scope (as per above) does not make issue gone.
>>>
>>> That said, assign dummy value and make the scope_guard() clear of its scope.
>>> For the sake of consistency do it in the entire file.
>>>
>>> Fixes: 7cc06e729460 ("platform/x86: ideapad-laptop: add a mutex to synchronize VPC commands")
>>> Reported-by: kernel test robot <lkp@intel.com>
>>> Closes: https://lore.kernel.org/oe-kbuild-all/202408290219.BrPO8twi-lkp@intel.com/
>>> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
>
>> Thank you for your patch, I've applied this patch to my review-hans
>> branch:
>> https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/log/?h=review-hans
>
> Have you had a chance to go through the discussion?
Yes I did read the entire discussion.
> TL;DR: please defer this. There is still no clear understanding of the root
> cause and the culprit.
My gist from the discussion was that this was good to have regardless of
the root cause.
IMHO the old construction where the scoped-guard only guards the function-call
and not the "if (ret)" on the return value of the guarded call was quite ugly /
convoluted / hard to read and this patch is an improvement regardless.
Regards,
Hans
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-09-05 8:33 ` Hans de Goede
@ 2024-09-05 8:36 ` Andy Shevchenko
0 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2024-09-05 8:36 UTC (permalink / raw)
To: Hans de Goede
Cc: Ilpo Järvinen, Gergo Koteles, platform-driver-x86,
linux-kernel, Ike Panhc, Peter Zijlstra, Josh Poimboeuf,
Nathan Chancellor, kernel test robot
On Thu, Sep 05, 2024 at 10:33:22AM +0200, Hans de Goede wrote:
> On 9/4/24 10:18 PM, Andy Shevchenko wrote:
> > Wed, Sep 04, 2024 at 08:14:53PM +0200, Hans de Goede kirjoitti:
> >> On 8/29/24 6:50 PM, Andy Shevchenko wrote:
> >>> First of all, it's a bit counterintuitive to have something like
> >>>
> >>> int err;
> >>> ...
> >>> scoped_guard(...)
> >>> err = foo(...);
> >>> if (err)
> >>> return err;
> >>>
> >>> Second, with a particular kernel configuration and compiler version in
> >>> one of such cases the objtool is not happy:
> >>>
> >>> ideapad-laptop.o: warning: objtool: .text.fan_mode_show: unexpected end of section
> >>>
> >>> I'm not an expert on all this, but the theory is that compiler and
> >>> linker in this case can't understand that 'result' variable will be
> >>> always initialized as long as no error has been returned. Assigning
> >>> 'result' to a dummy value helps with this. Note, that fixing the
> >>> scoped_guard() scope (as per above) does not make issue gone.
> >>>
> >>> That said, assign dummy value and make the scope_guard() clear of its scope.
> >>> For the sake of consistency do it in the entire file.
> >>>
> >>> Fixes: 7cc06e729460 ("platform/x86: ideapad-laptop: add a mutex to synchronize VPC commands")
> >>> Reported-by: kernel test robot <lkp@intel.com>
> >>> Closes: https://lore.kernel.org/oe-kbuild-all/202408290219.BrPO8twi-lkp@intel.com/
> >>> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> >
> >> Thank you for your patch, I've applied this patch to my review-hans
> >> branch:
> >> https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/log/?h=review-hans
> >
> > Have you had a chance to go through the discussion?
>
> Yes I did read the entire discussion.
>
> > TL;DR: please defer this. There is still no clear understanding of the root
> > cause and the culprit.
>
> My gist from the discussion was that this was good to have regardless of
> the root cause.
>
> IMHO the old construction where the scoped-guard only guards the function-call
> and not the "if (ret)" on the return value of the guarded call was quite ugly /
> convoluted / hard to read and this patch is an improvement regardless.
Okay, if you think it's good to go, you are welcome!
Thanks!
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-09-04 10:26 ` Andy Shevchenko
@ 2024-09-06 3:16 ` Josh Poimboeuf
2024-09-13 23:33 ` Nathan Chancellor
0 siblings, 1 reply; 17+ messages in thread
From: Josh Poimboeuf @ 2024-09-06 3:16 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Ilpo Järvinen, Gergo Koteles, Hans de Goede,
platform-driver-x86, linux-kernel, Ike Panhc, Peter Zijlstra,
Nathan Chancellor, kernel test robot
On Wed, Sep 04, 2024 at 01:26:11PM +0300, Andy Shevchenko wrote:
> On Tue, Sep 03, 2024 at 09:52:01PM -0700, Josh Poimboeuf wrote:
> > I'm not sure I buy that, we should look closer to understand what the
> > issue is. Can you share the config and/or toolchain version(s) need to
> > trigger the warning?
>
> .config is from the original report [1], toolchain is
> Debian clang version 18.1.8 (9)
> Target: x86_64-pc-linux-gnu
> Thread model: posix
> InstalledDir: /usr/bin
>
> (Just whatever Debian unstable provides)
>
> [1]: https://lore.kernel.org/oe-kbuild-all/202408290219.BrPO8twi-lkp@intel.com/
The warning is due to a (minor?) Clang bug, almost like it tried to
optimize but didn't quite finish.
Here's the disassembly:
0000000000000010 <fan_mode_show>:
10: e8 00 00 00 00 call 15 <fan_mode_show+0x5> 11: R_X86_64_PLT32 __fentry__-0x4
15: 55 push %rbp
16: 48 89 e5 mov %rsp,%rbp
19: 41 57 push %r15
1b: 41 56 push %r14
1d: 53 push %rbx
1e: 50 push %rax
1f: 48 89 d3 mov %rdx,%rbx
22: 49 89 fe mov %rdi,%r14
25: e8 00 00 00 00 call 2a <fan_mode_show+0x1a> 26: R_X86_64_PLT32 __sanitizer_cov_trace_pc-0x4
2a: 4d 8b 76 78 mov 0x78(%r14),%r14
2e: 31 f6 xor %esi,%esi
30: 49 8d 7e 08 lea 0x8(%r14),%rdi
34: e8 00 00 00 00 call 39 <fan_mode_show+0x29> 35: R_X86_64_PLT32 mutex_lock_nested-0x4
39: 4d 89 f7 mov %r14,%r15
3c: 49 83 c7 08 add $0x8,%r15
40: 74 5b je 9d <fan_mode_show+0x8d>
42: 49 8b 06 mov (%r14),%rax
45: 48 8d 55 e0 lea -0x20(%rbp),%rdx
49: be 2b 00 00 00 mov $0x2b,%esi
4e: 48 8b 78 08 mov 0x8(%rax),%rdi
52: e8 00 00 00 00 call 57 <fan_mode_show+0x47> 53: R_X86_64_PLT32 .text.read_ec_data-0x4
57: 4c 89 ff mov %r15,%rdi
5a: 41 89 c6 mov %eax,%r14d
5d: e8 00 00 00 00 call 62 <fan_mode_show+0x52> 5e: R_X86_64_PLT32 mutex_unlock-0x4
62: 45 85 f6 test %r14d,%r14d
65: 74 07 je 6e <fan_mode_show+0x5e>
67: e8 00 00 00 00 call 6c <fan_mode_show+0x5c> 68: R_X86_64_PLT32 __sanitizer_cov_trace_pc-0x4
6c: eb 1b jmp 89 <fan_mode_show+0x79>
6e: e8 00 00 00 00 call 73 <fan_mode_show+0x63> 6f: R_X86_64_PLT32 __sanitizer_cov_trace_pc-0x4
73: 48 8b 55 e0 mov -0x20(%rbp),%rdx
77: 48 89 df mov %rbx,%rdi
7a: 48 c7 c6 00 00 00 00 mov $0x0,%rsi 7d: R_X86_64_32S .rodata.str1.1+0x508
81: e8 00 00 00 00 call 86 <fan_mode_show+0x76> 82: R_X86_64_PLT32 sysfs_emit-0x4
86: 41 89 c6 mov %eax,%r14d
89: 49 63 c6 movslq %r14d,%rax
8c: 48 83 c4 08 add $0x8,%rsp
90: 5b pop %rbx
91: 41 5e pop %r14
93: 41 5f pop %r15
95: 5d pop %rbp
96: 31 ff xor %edi,%edi
98: 31 d2 xor %edx,%edx
9a: 31 f6 xor %esi,%esi
9c: c3 ret
9d: e8 00 00 00 00 call a2 <__param_ctrl_ps2_aux_port+0x2> 9e: R_X86_64_PLT32 __sanitizer_cov_trace_pc-0x4
<end of function>
And the interesting bit:
30: 49 8d 7e 08 lea 0x8(%r14),%rdi # rdi = &priv->vpc_mutex
34: e8 00 00 00 00 call mutex_lock_nested
39: 4d 89 f7 mov %r14,%r15 # r15 = r14 = priv
3c: 49 83 c7 08 add $0x8,%r15 # r15 = &priv->vpc_mutex
40: 74 5b je 9d <fan_mode_show+0x8d> # if &priv->vpc_mutex == NULL, goto 9d
...
9d: e8 00 00 00 00 call a2 <__param_ctrl_ps2_aux_port+0x2> 9e: R_X86_64_PLT32 __sanitizer_cov_trace_pc-0x4
<oof>
If '&priv->vpc_mutex' is NULL, it jumps to 9d, where it calls
__sanitizer_cov_trace_pc(). After that returns, it runs off the rails.
Apparently Clang decided somehow (LTO?) that '&priv->vpc_mutex' can
never be NULL, but it didn't quite finish the optimization. Maybe some
bad interaction between LTO and KCOV?
Here's the triggering code:
> static ssize_t fan_mode_show(struct device *dev,
> struct device_attribute *attr,
> char *buf)
> {
> struct ideapad_private *priv = dev_get_drvdata(dev);
> unsigned long result;
> int err;
>
> scoped_guard(mutex, &priv->vpc_mutex)
> err = read_ec_data(priv->adev->handle, VPCCMD_R_FAN, &result);
Here's the pre-processed code for the scoped_guard() invocation and its
DEFINE_GUARD() dependency, edited for readability:
> typedef struct mutex * class_mutex_t;
>
> static inline void class_mutex_destructor(struct mutex **p)
> {
> struct mutex *_T = *p;
> if (_T)
> mutex_unlock(_T);
> }
>
> static inline struct mutex *class_mutex_constructor(struct mutex *_T)
> {
> struct mutex *t = ({ mutex_lock_nested(_T, 0); _T; });
> return t;
> }
>
> static inline void *class_mutex_lock_ptr(struct mutex **_T)
> {
> return *_T;
> }
>
> for (struct mutex *scope = class_mutex_constructor(&priv->vpc_mutex), *done = ((void *)0);
> class_mutex_lock_ptr(&scope) && !done;
> done = (void *)1) {
>
> err = read_ec_data(priv->adev->handle, VPCCMD_R_FAN, &result);
> }
The fake "for loop" is needed to be able to initialize the scope
variable inline. But basically it's doing this:
> if (class_mutex_constructor(&priv->vpc_mutex))
> err = read_ec_data(priv->adev->handle, VPCCMD_R_FAN, &result);
In this case, mutex is an unconditional guard, so the constructor just
returns the original value of '&priv->vpc_mutex'. So if the original
'&priv->vpc_mutex' is never NULL, the condition would always be true.
--
Josh
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-09-06 3:16 ` Josh Poimboeuf
@ 2024-09-13 23:33 ` Nathan Chancellor
2024-09-16 10:40 ` Andy Shevchenko
0 siblings, 1 reply; 17+ messages in thread
From: Nathan Chancellor @ 2024-09-13 23:33 UTC (permalink / raw)
To: Josh Poimboeuf
Cc: Andy Shevchenko, Ilpo Järvinen, Gergo Koteles, Hans de Goede,
platform-driver-x86, linux-kernel, Ike Panhc, Peter Zijlstra,
kernel test robot
On Thu, Sep 05, 2024 at 08:16:01PM -0700, Josh Poimboeuf wrote:
> On Wed, Sep 04, 2024 at 01:26:11PM +0300, Andy Shevchenko wrote:
> > On Tue, Sep 03, 2024 at 09:52:01PM -0700, Josh Poimboeuf wrote:
> > > I'm not sure I buy that, we should look closer to understand what the
> > > issue is. Can you share the config and/or toolchain version(s) need to
> > > trigger the warning?
> >
> > .config is from the original report [1], toolchain is
> > Debian clang version 18.1.8 (9)
> > Target: x86_64-pc-linux-gnu
> > Thread model: posix
> > InstalledDir: /usr/bin
> >
> > (Just whatever Debian unstable provides)
> >
> > [1]: https://lore.kernel.org/oe-kbuild-all/202408290219.BrPO8twi-lkp@intel.com/
>
> The warning is due to a (minor?) Clang bug, almost like it tried to
> optimize but didn't quite finish.
...
> In this case, mutex is an unconditional guard, so the constructor just
> returns the original value of '&priv->vpc_mutex'. So if the original
> '&priv->vpc_mutex' is never NULL, the condition would always be true.
Thanks a lot for that Josh. I have a somewhat trivial reproducer for the
clang folks to take a look at. I should have some time on Monday to get
that reported upstream and I will see if I can find anyone to take a
look at it.
For what it is worth, I don't think the workaround for this is too bad
and it seems like it only shows up with KCOV.
Cheers,
Nathan
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
2024-09-13 23:33 ` Nathan Chancellor
@ 2024-09-16 10:40 ` Andy Shevchenko
0 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2024-09-16 10:40 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Josh Poimboeuf, Ilpo Järvinen, Gergo Koteles, Hans de Goede,
platform-driver-x86, linux-kernel, Ike Panhc, Peter Zijlstra,
kernel test robot
On Fri, Sep 13, 2024 at 04:33:24PM -0700, Nathan Chancellor wrote:
> On Thu, Sep 05, 2024 at 08:16:01PM -0700, Josh Poimboeuf wrote:
> > On Wed, Sep 04, 2024 at 01:26:11PM +0300, Andy Shevchenko wrote:
> > > On Tue, Sep 03, 2024 at 09:52:01PM -0700, Josh Poimboeuf wrote:
> > > > I'm not sure I buy that, we should look closer to understand what the
> > > > issue is. Can you share the config and/or toolchain version(s) need to
> > > > trigger the warning?
> > >
> > > .config is from the original report [1], toolchain is
> > > Debian clang version 18.1.8 (9)
> > > Target: x86_64-pc-linux-gnu
> > > Thread model: posix
> > > InstalledDir: /usr/bin
> > >
> > > (Just whatever Debian unstable provides)
> > >
> > > [1]: https://lore.kernel.org/oe-kbuild-all/202408290219.BrPO8twi-lkp@intel.com/
> >
> > The warning is due to a (minor?) Clang bug, almost like it tried to
> > optimize but didn't quite finish.
> ...
> > In this case, mutex is an unconditional guard, so the constructor just
> > returns the original value of '&priv->vpc_mutex'. So if the original
> > '&priv->vpc_mutex' is never NULL, the condition would always be true.
>
> Thanks a lot for that Josh. I have a somewhat trivial reproducer for the
> clang folks to take a look at. I should have some time on Monday to get
> that reported upstream and I will see if I can find anyone to take a
> look at it.
>
> For what it is worth, I don't think the workaround for this is too bad
> and it seems like it only shows up with KCOV.
FWIW, Hans queued the workaround.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2024-09-16 10:41 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-29 16:50 [PATCH v1 1/1] platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope Andy Shevchenko
2024-09-03 15:00 ` Gergo Koteles
2024-09-03 15:14 ` Andy Shevchenko
2024-09-03 15:29 ` Gergo Koteles
2024-09-03 15:40 ` Andy Shevchenko
2024-09-04 1:22 ` Nathan Chancellor
2024-09-04 10:28 ` Andy Shevchenko
2024-09-04 13:37 ` Ilpo Järvinen
2024-09-04 4:52 ` Josh Poimboeuf
2024-09-04 10:26 ` Andy Shevchenko
2024-09-06 3:16 ` Josh Poimboeuf
2024-09-13 23:33 ` Nathan Chancellor
2024-09-16 10:40 ` Andy Shevchenko
2024-09-04 18:14 ` Hans de Goede
2024-09-04 20:18 ` Andy Shevchenko
2024-09-05 8:33 ` Hans de Goede
2024-09-05 8:36 ` Andy Shevchenko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox