[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <0cbe7ab8-bd87-b5f7-0513-07c82a7e76c9@loongson.cn>
Date: Mon, 7 Apr 2025 18:52:10 +0800
From: Tiezhu Yang <yangtiezhu@...ngson.cn>
To: Josh Poimboeuf <jpoimboe@...nel.org>
Cc: Philip Li <philip.li@...el.com>, kernel test robot <lkp@...el.com>,
Guenter Roeck <linux@...ck-us.net>, oe-kbuild-all@...ts.linux.dev,
Andrew Morton <akpm@...ux-foundation.org>,
Linux Memory Management List <linux-mm@...ck.org>,
Alessandro Carminati <acarmina@...hat.com>,
Peter Zijlstra <peterz@...radead.org>, linux-kernel@...r.kernel.org,
loongarch@...ts.linux.dev
Subject: Re: [linux-next:master 12681/13861] drivers/i2c/i2c-core-base.o:
warning: objtool: __i2c_transfer+0x120: stack state mismatch: reg1[24]=-1+0
reg2[24]=-2-24
On 04/03/2025 10:37 PM, Josh Poimboeuf wrote:
> On Thu, Apr 03, 2025 at 05:35:51PM +0800, Tiezhu Yang wrote:
>> On 04/02/2025 03:45 AM, Josh Poimboeuf wrote:
>>> On Tue, Apr 01, 2025 at 12:38:37PM +0800, Philip Li wrote:
>>>> On Tue, Apr 01, 2025 at 10:44:57AM +0800, kernel test robot wrote:
>>>>> tree: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
>>>>> head: 405e2241def89c88f008dcb899eb5b6d4be8b43c
>>>>> commit: 9016dad4dca4bbe61c48ffd5a273cad980caa0d1 [12681/13861] loongarch: add support for suppressing warning backtraces
>>>>> config: loongarch-randconfig-001-20250401 (https://download.01.org/0day-ci/archive/20250401/202504011011.jyZ6NtXx-lkp@intel.com/config)
>>>>> compiler: loongarch64-linux-gcc (GCC) 14.2.0
>>>>> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250401/202504011011.jyZ6NtXx-lkp@intel.com/reproduce)
>>>>>
>>>>> If you fix the issue in a separate patch/commit (i.e. not just a new version of
>>>>> the same patch/commit), kindly add following tags
>>>>> | Reported-by: kernel test robot <lkp@...el.com>
>>>>> | Closes: https://lore.kernel.org/oe-kbuild-all/202504011011.jyZ6NtXx-lkp@intel.com/
>>>>>
>>>>> All warnings (new ones prefixed by >>):
>>>>>
>>>>>>> drivers/i2c/i2c-core-base.o: warning: objtool: __i2c_transfer+0x120: stack state mismatch: reg1[24]=-1+0 reg2[24]=-2-24
>>>
>>> Tiezhu, this looks like a loongarch GCC bug with asm goto, or am I
>>> confused? See analysis below.
>>
>> This is related with GCC optimization "-fshrink-wrap" which is default y
>> on LoongArch, use "-fno-shrink-wrap" can avoid such issues, like this:
>
> As I showed, it looks like an actual runtime bug, not an objtool false
> positive. Disabling it only for CONFIG_OBJTOOLonly wouldn't fix that.
Here are my thoughts:
(1) -fshrink-wrap
The prologue may perform a variety of target dependent tasks such
as saving callee-saved registers, saving the return address, etc.
On some targets some of these tasks may be independent of others
and thus may be shrink-wrapped separately. These independent tasks
are referred to as components and are handled generically by the
target independent parts of GCC.
The initialization is not done as frequently on execution paths
where this would unnecessary.
"-fshrink-wrap" is enabled by default at -O and higher, will emit
function prologues only before parts of the function that need it,
rather than at the top of the function.
https://gcc.gnu.org/onlinedocs/gccint/Shrink-wrapping-separate-components.html
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fshrink-wrap
There is a potential execution path with only using s0 and ra
(without using s1, s2, s3, etc): 2d58-->2d70-->2f88-->2e78-->2e84
0000000000002d58 <__i2c_transfer>:
2d58: 02fe8063 addi.d $sp, $sp, -96
2d5c: 29c14077 st.d $s0, $sp, 80
2d60: 29c16061 st.d $ra, $sp, 88
2d64: 28c0408c ld.d $t0, $a0, 16
2d68: 00150097 or $s0, $a0, $zero
2d6c: 2600018c ldptr.d $t0, $t0, 0
2d70: 40021980 beqz $t0, 536 # 2f88
<.LVL1023>
...
0000000000002f88 <.LVL1023>:
2f88: 1a000006 pcalau12i $a2, 0
0000000000002f8c <.LVL1024>:
2f8c: 1a000004 pcalau12i $a0, 0
0000000000002f90 <.LVL1025>:
2f90: 02c00084 addi.d $a0, $a0, 0
2f94: 02c1c2e5 addi.d $a1, $s0, 112
0000000000002f98 <.LVL1026>:
2f98: 02c000c6 addi.d $a2, $a2, 0
2f9c: 54000000 bl 0 # 2f9c
<.LVL1026+0x4>
>
0000000000002fa0 <.LVL1027>:
2fa0: 02be8404 addi.w $a0, $zero, -95
2fa4: 53fed7ff b -300 # 2e78 <.L845>
...
0000000000002e78 <.L845>:
2e78: 28c16061 ld.d $ra, $sp, 88
2e7c: 28c14077 ld.d $s0, $sp, 80
0000000000002e80 <.LVL994>:
2e80: 02c18063 addi.d $sp, $sp, 96
2e84: 4c000020 jirl $zero, $ra, 0
From this point of view, it seems that there is no problem for the
generated instructions of the current code, it is not a runtime bug,
just a GCC optimization.
(2) Analysis
In fact, the generated objtool warning is because the break instruction
(2ee8) which is before the restoring s1 instruction (2eec) is annotated
as dead end.
0000000000002d58 <__i2c_transfer>:
2d58: 02fe8063 addi.d $sp, $sp, -96
2d5c: 29c14077 st.d $s0, $sp, 80
2d60: 29c16061 st.d $ra, $sp, 88
2d64: 28c0408c ld.d $t0, $a0, 16
2d68: 00150097 or $s0, $a0, $zero
2d6c: 2600018c ldptr.d $t0, $t0, 0
2d70: 40021980 beqz $t0, 536 # 2f88
<.LVL1023>
2d74: 29c12078 st.d $s1, $sp, 72
2d78: 001500b8 or $s1, $a1, $zero
0000000000002d7c <.LBB2114>:
2d7c: 400150a0 beqz $a1, 336 # 2ecc
<.LVL999+0x4>
...
2ecc: 1a000004 pcalau12i $a0, 0
0000000000002ed0 <.LVL1000>:
2ed0: 02c00084 addi.d $a0, $a0, 0
2ed4: 02c5a084 addi.d $a0, $a0, 360
2ed8: 54000000 bl 0 # 2ed8
<.LVL1000+0x8>
0000000000002edc <.LVL1001>:
2edc: 0015008c or $t0, $a0, $zero
2ee0: 02bfa804 addi.w $a0, $zero, -22
2ee4: 44003d80 bnez $t0, 60 # 2f20
<.LVL1008+0x8>
0000000000002ee8 <.L10001^B7>:
2ee8: 002a0001 break 0x1
2eec: 28c12078 ld.d $s1, $sp, 72
0000000000002ef0 <.LVL1002>:
2ef0: 53ff8bff b -120 # 2e78 <.L845>
This issue is introduced by the following changes:
#define __WARN_FLAGS(flags) \
do { \
instrumentation_begin(); \
- __BUG_FLAGS(BUGFLAG_WARNING|(flags), ANNOTATE_REACHABLE(10001b));\
+ if (!KUNIT_IS_SUPPRESSED_WARNING(__func__)) \
+ __BUG_FLAGS(BUGFLAG_WARNING|(flags), ANNOTATE_REACHABLE(10001b));\
instrumentation_end(); \
} while (0)
of commit e61a8b4b0d83 ("loongarch: add support for suppressing warning
backtraces") in the linux-next.git.
(3) -fno-shrink-wrap
"-fno-shrink-wrap" will save callee-saved registers and the return
address together as a whole block in the prologue at the top of the
function, and also restores them together as a whole block in the
epilogue.
0000000000002b38 <__i2c_transfer>:
2b38: 02fe8063 addi.d $sp, $sp, -96
2b3c: 29c14077 st.d $s0, $sp, 80
2b40: 29c12078 st.d $s1, $sp, 72
2b44: 29c10079 st.d $s2, $sp, 64
2b48: 29c16061 st.d $ra, $sp, 88
2b4c: 29c0e07a st.d $s3, $sp, 56
2b50: 29c0c07b st.d $s4, $sp, 48
2b54: 29c0a07c st.d $s5, $sp, 40
2b58: 29c0807d st.d $s6, $sp, 32
2b5c: 29c0607e st.d $s7, $sp, 24
2b60: 29c0407f st.d $s8, $sp, 16
...
0000000000002c38 <.L747>:
2c38: 28c16061 ld.d $ra, $sp, 88
2c3c: 28c14077 ld.d $s0, $sp, 80
0000000000002c40 <.LVL937>:
2c40: 28c12078 ld.d $s1, $sp, 72
2c44: 28c10079 ld.d $s2, $sp, 64
0000000000002c48 <.LVL938>:
2c48: 28c0e07a ld.d $s3, $sp, 56
2c4c: 28c0c07b ld.d $s4, $sp, 48
2c50: 28c0a07c ld.d $s5, $sp, 40
2c54: 28c0807d ld.d $s6, $sp, 32
2c58: 28c0607e ld.d $s7, $sp, 24
2c5c: 28c0407f ld.d $s8, $sp, 16
2c60: 02c18063 addi.d $sp, $sp, 96
2c64: 4c000020 jirl $zero, $ra, 0
(4) Solution 1
One way is to annotate __BUG_ENTRY() as reachable whether
KUNIT_IS_SUPPRESSED_WARNING() is true or false, like this:
---8<---
diff --git a/arch/loongarch/include/asm/bug.h
b/arch/loongarch/include/asm/bug.h
index b79ff6696ce6..e41ebeaba204 100644
--- a/arch/loongarch/include/asm/bug.h
+++ b/arch/loongarch/include/asm/bug.h
@@ -60,8 +60,9 @@
#define __WARN_FLAGS(flags) \
do { \
instrumentation_begin(); \
- if (!KUNIT_IS_SUPPRESSED_WARNING(__func__)) \
- __BUG_FLAGS(BUGFLAG_WARNING|(flags),
ANNOTATE_REACHABLE(10001b));\
+ if (!KUNIT_IS_SUPPRESSED_WARNING(__func__)) \
+ __BUG_FLAGS(BUGFLAG_WARNING|(flags), ""); \
+ __BUG_FLAGS(0, ANNOTATE_REACHABLE(10001b)); \
instrumentation_end(); \
} while (0)
(5) Solution 2
The other way is to use "-fno-shrink-wrap" to aovid such issue under
CONFIG_OBJTOOL at compile-time, like this:
---8<---
diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile
index 0304eabbe606..2d5529322357 100644
--- a/arch/loongarch/Makefile
+++ b/arch/loongarch/Makefile
@@ -106,6 +106,7 @@ KBUILD_CFLAGS +=
-mannotate-tablejump
else
KBUILD_CFLAGS += -fno-jump-tables # keep
compatibility with older compilers
endif
+KBUILD_CFLAGS += -fno-shrink-wrap
endif
KBUILD_RUSTFLAGS +=
--target=loongarch64-unknown-none-softfloat -Ccode-model=small
If you have more suggestion, please let me know.
Thanks,
Tiezhu
Powered by blists - more mailing lists