Re: [linus:master] [hugetlb] 7118fc2906: kernel_BUG_at_lib/list_debug.c

Feng Tang
2023-01-18T14:00:35Z

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

On Tue, Jan 17, 2023 at 10:25:17AM -0800, Linus Torvalds wrote:
> On Tue, Jan 17, 2023 at 4:22 AM Feng Tang <feng.tang@intel.com> wrote:
> >
> > With the following patch to use 'O1' instead 'O2' gcc optoin for
> > page_alloc.c, the list corruption issue can't be reproduced for
> > commit 7118fc2906 in 1000 runs.
>
> Ugh.
>
> It would be lovely if you could just narrow it down with
>
> #pragma GCC optimize ("O1")
> ...
> #pragma GCC optimize ("O2")
>
> around just that prep_compound_page(), but when I tried it myself I
> get some function attribute mismatch errors.

Yes, this works with both my local build and 0Day's build system,
and it also makes the issue gone.

> > As is can't be reproduced with X86_64 build, it could be i386
> > compiling related.
>
> Your particular config causes a huge amount of nasty 64-bit arithmetic
> according to the objdump code, with sequences like
>
> c13b3cbb: 83 05 d0 28 6c c5 01 addl $0x1,0xc56c28d0
> c13b3cc2: 83 15 d4 28 6c c5 00 adcl $0x0,0xc56c28d4
>
> which seems to be just from some coverage profiling being on
> (CONFIG_GCOV?), or something. It makes it very hard to read the code.
>
> You also have UBSAN enabled, which - again - makes for some really
> grotty asm that hides any actual logic.
>
> Finally, your objdump version also does some horrendous decoding, like
>
> c13b3e29: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi

I know little about these tools, and I tried objdump tool from
Cent OS 9 (objdump version 2.35.2) and Ubuntu 22.04 (objdump version
2.38), they both dumped similar assembly. Please let me know if you
want us to try other version of objdump.

> which is just a 7-byte 'nop' instruction, but again, it makes it
> rather hard to actually read the code.
>
> With the i386 defconfig, gcc generates a function that is just ~30
> instructions for me, so this makes a huge difference in the legibility
> of the code.
>
> I wonder if you can recreate the issue with a much more
> straightforward config. By all means, leave DEBUG_PAGEALLOC and SLUB
> debugging on, but without the things like UBSAN and GCOV.

We modify the kconfig to disable GCOV and UBSAN, and the issue can't
be reproudced in 1000 runs.

The objdump of prep_compound_page() for the 2 commits are also
attached for check.

Anothe info is, as you pointed out GCOV and UBSAN, we tried to
disable GCOV/UBSAN for page_alloc.c in mm/Makefile separtely
(thanks to Fengwei Yin's tip), by adding lines:

a) UBSAN_SANITIZE_page_alloc.o := n
b) GCOV_PROFILE_page_alloc.o := n

The issue also cannot be reproduced with either one (with
original kconfig)

> > I also objdumped 'prep_compound_page' for vmlinux of 7118fc2906 and
> > its parent commit 48b8d744ea84, which have big difference than the
> > simple 'set_page_count()' change, but I can't tell which part is
> > abnormal, so attach them for further check.
>
> Yeah, I can't make heads or tails of them either, see above on how
> illegible the objdump files are. And that's despite not even having
> all of prep_compound_page() in them (it's missing
> prep_compound_page.cold, which is probably just UBSAN fixup code, but
> who knows..)

Yes, from what I can tell that old 'prep_compound_page.cold' is mostly
calling UBSAN functions. And after disbling GCOV+UBSAN, there is no
more prep_compound_page.cold.

Thanks,
Feng

>
> That said, with the i386 defconfig, the only change from adding
> set_page_count() to the loop seems to be exactly that:
>
> .L589:
> - movl $1024, 12(%eax)
> + movl $0, 28(%eax)
> addl $32, %eax
> + movl $1024, -20(%eax)
> movl %esi, -28(%eax)
> movl $0, -12(%eax)
> cmpl %edx, %eax
>
> (don't ask me why gcc does *one* access using the pre-incremented
> pointer, and then the rest to the post-incremented ones, but whatever
> - it means that it's not just "add a mov $0", it's also changing how
> the
>
> p->mapping = TAIL_MAPPING;
>
> instruction is done, which is that
>
> - movl $1024, 12(%eax)
> + movl $1024, -20(%eax)
>
> part of the change)
>
> Linus

[-- Attachment #2: 7118fc29.log --]
[-- Type: text/plain, Size: 3713 bytes --]

c11e56e0 <prep_compound_page>:
c11e56e0: 55 push %ebp
c11e56e1: 89 d1 mov %edx,%ecx
c11e56e3: 89 e5 mov %esp,%ebp
c11e56e5: 56 push %esi
c11e56e6: 53 push %ebx
c11e56e7: 89 c3 mov %eax,%ebx
c11e56e9: b8 01 00 00 00 mov $0x1,%eax
c11e56ee: d3 e0 shl %cl,%eax
c11e56f0: 83 3b ff cmpl $0xffffffff,(%ebx)
c11e56f3: 0f 84 87 00 00 00 je c11e5780 <prep_compound_page+0xa0>
c11e56f9: 0f ba 2b 10 btsl $0x10,(%ebx)
c11e56fd: 48 dec %eax
c11e56fe: 7e 21 jle c11e5721 <prep_compound_page+0x41>
c11e5700: 8d 73 01 lea 0x1(%ebx),%esi
c11e5703: ba 28 00 00 00 mov $0x28,%edx
c11e5708: d3 e2 shl %cl,%edx
c11e570a: 8d 43 28 lea 0x28(%ebx),%eax
c11e570d: 01 da add %ebx,%edx
c11e570f: 90 nop
c11e5710: c7 40 0c 00 04 00 00 movl $0x400,0xc(%eax)
c11e5717: 83 c0 28 add $0x28,%eax
c11e571a: 89 70 dc mov %esi,-0x24(%eax)
c11e571d: 39 d0 cmp %edx,%eax
c11e571f: 75 ef jne c11e5710 <prep_compound_page+0x30>
c11e5721: c7 43 34 ff ff ff ff movl $0xffffffff,0x34(%ebx)
c11e5728: b8 01 00 00 00 mov $0x1,%eax
c11e572d: c6 43 30 01 movb $0x1,0x30(%ebx)
c11e5731: d3 e0 shl %cl,%eax
c11e5733: 89 43 38 mov %eax,0x38(%ebx)
c11e5736: 8b 43 04 mov 0x4(%ebx),%eax
c11e5739: 88 4b 31 mov %cl,0x31(%ebx)
c11e573c: a8 01 test $0x1,%al
c11e573e: 75 50 jne c11e5790 <prep_compound_page+0xb0>
c11e5740: 89 d8 mov %ebx,%eax
c11e5742: 8b 10 mov (%eax),%edx
c11e5744: 81 e2 00 00 01 00 and $0x10000,%edx
c11e574a: 74 24 je c11e5770 <prep_compound_page+0x90>
c11e574c: 83 38 ff cmpl $0xffffffff,(%eax)
c11e574f: 74 42 je c11e5793 <prep_compound_page+0xb3>
c11e5751: 8b 10 mov (%eax),%edx
c11e5753: 81 e2 00 00 01 00 and $0x10000,%edx
c11e5759: 74 0d je c11e5768 <prep_compound_page+0x88>
c11e575b: 80 78 31 01 cmpb $0x1,0x31(%eax)
c11e575f: 76 07 jbe c11e5768 <prep_compound_page+0x88>
c11e5761: c7 43 58 00 00 00 00 movl $0x0,0x58(%ebx)
c11e5768: 5b pop %ebx
c11e5769: 5e pop %esi
c11e576a: 5d pop %ebp
c11e576b: c3 ret
c11e576c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi
c11e5770: 8b 50 04 mov 0x4(%eax),%edx
c11e5773: f6 c2 01 test $0x1,%dl
c11e5776: 75 d4 jne c11e574c <prep_compound_page+0x6c>
c11e5778: 5b pop %ebx
c11e5779: 5e pop %esi
c11e577a: 5d pop %ebp
c11e577b: c3 ret
c11e577c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi
c11e5780: ba 10 5c 97 c2 mov $0xc2975c10,%edx
c11e5785: 89 d8 mov %ebx,%eax
c11e5787: e8 e4 ae fd ff call c11c0670 <dump_page>
c11e578c: 0f 0b ud2
c11e578e: 66 90 xchg %ax,%ax
c11e5790: 48 dec %eax
c11e5791: eb af jmp c11e5742 <prep_compound_page+0x62>
c11e5793: ba 10 5c 97 c2 mov $0xc2975c10,%edx
c11e5798: e8 d3 ae fd ff call c11c0670 <dump_page>
c11e579d: 0f 0b ud2
c11e579f: 90 nop

[-- Attachment #3: 48b8d744.log --]
[-- Type: text/plain, Size: 4706 bytes --]

c11e56c0 <prep_compound_page>:
c11e56c0: 55 push %ebp
c11e56c1: 88 d1 mov %dl,%cl
c11e56c3: 89 e5 mov %esp,%ebp
c11e56c5: 57 push %edi
c11e56c6: bf 01 00 00 00 mov $0x1,%edi
c11e56cb: 56 push %esi
c11e56cc: 89 c6 mov %eax,%esi
c11e56ce: 53 push %ebx
c11e56cf: d3 e7 shl %cl,%edi
c11e56d1: 83 ec 0c sub $0xc,%esp
c11e56d4: 83 38 ff cmpl $0xffffffff,(%eax)
c11e56d7: 89 55 ec mov %edx,-0x14(%ebp)
c11e56da: 0f 84 c0 00 00 00 je c11e57a0 <prep_compound_page+0xe0>
c11e56e0: 0f ba 28 10 btsl $0x10,(%eax)
c11e56e4: 83 ff 01 cmp $0x1,%edi
c11e56e7: 7e 38 jle c11e5721 <prep_compound_page+0x61>
c11e56e9: 89 75 e8 mov %esi,-0x18(%ebp)
c11e56ec: 8d 48 01 lea 0x1(%eax),%ecx
c11e56ef: bb 01 00 00 00 mov $0x1,%ebx
c11e56f4: 8d 40 28 lea 0x28(%eax),%eax
c11e56f7: 89 ce mov %ecx,%esi
c11e56f9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
c11e5700: c7 40 1c 00 00 00 00 movl $0x0,0x1c(%eax)
c11e5707: 3e 8d 74 26 00 lea %ds:0x0(%esi,%eiz,1),%esi
c11e570c: c7 40 0c 00 04 00 00 movl $0x400,0xc(%eax)
c11e5713: 43 inc %ebx
c11e5714: 83 c0 28 add $0x28,%eax
c11e5717: 89 70 dc mov %esi,-0x24(%eax)
c11e571a: 39 df cmp %ebx,%edi
c11e571c: 75 e2 jne c11e5700 <prep_compound_page+0x40>
c11e571e: 8b 75 e8 mov -0x18(%ebp),%esi
c11e5721: c7 46 34 ff ff ff ff movl $0xffffffff,0x34(%esi)
c11e5728: 8b 4d ec mov -0x14(%ebp),%ecx
c11e572b: b8 01 00 00 00 mov $0x1,%eax
c11e5730: c6 46 30 01 movb $0x1,0x30(%esi)
c11e5734: 88 4e 31 mov %cl,0x31(%esi)
c11e5737: d3 e0 shl %cl,%eax
c11e5739: 89 46 38 mov %eax,0x38(%esi)
c11e573c: 8b 46 04 mov 0x4(%esi),%eax
c11e573f: a8 01 test $0x1,%al
c11e5741: 75 6d jne c11e57b0 <prep_compound_page+0xf0>
c11e5743: 89 f0 mov %esi,%eax
c11e5745: 8b 10 mov (%eax),%edx
c11e5747: 81 e2 00 00 01 00 and $0x10000,%edx
c11e574d: 74 41 je c11e5790 <prep_compound_page+0xd0>
c11e574f: 83 38 ff cmpl $0xffffffff,(%eax)
c11e5752: 74 5f je c11e57b3 <prep_compound_page+0xf3>
c11e5754: 8b 10 mov (%eax),%edx
c11e5756: 81 e2 00 00 01 00 and $0x10000,%edx
c11e575c: 74 0d je c11e576b <prep_compound_page+0xab>
c11e575e: 80 78 31 01 cmpb $0x1,0x31(%eax)
c11e5762: 76 07 jbe c11e576b <prep_compound_page+0xab>
c11e5764: c7 46 58 00 00 00 00 movl $0x0,0x58(%esi)
c11e576b: 83 c4 0c add $0xc,%esp
c11e576e: 5b pop %ebx
c11e576f: 5e pop %esi
c11e5770: 5f pop %edi
c11e5771: 5d pop %ebp
c11e5772: c3 ret
c11e5773: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi
c11e5777: 90 nop
c11e5778: 89 45 f0 mov %eax,-0x10(%ebp)
c11e577b: 31 d2 xor %edx,%edx
c11e577d: e8 5e 06 04 00 call c1225de0 <__page_ref_set>
c11e5782: 8b 45 f0 mov -0x10(%ebp),%eax
c11e5785: eb 85 jmp c11e570c <prep_compound_page+0x4c>
c11e5787: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
c11e578e: 66 90 xchg %ax,%ax
c11e5790: 8b 50 04 mov 0x4(%eax),%edx
c11e5793: f6 c2 01 test $0x1,%dl
c11e5796: 75 b7 jne c11e574f <prep_compound_page+0x8f>
c11e5798: 83 c4 0c add $0xc,%esp
c11e579b: 5b pop %ebx
c11e579c: 5e pop %esi
c11e579d: 5f pop %edi
c11e579e: 5d pop %ebp
c11e579f: c3 ret
c11e57a0: ba a8 5b 97 c2 mov $0xc2975ba8,%edx
c11e57a5: e8 f6 ae fd ff call c11c06a0 <dump_page>
c11e57aa: 0f 0b ud2
c11e57ac: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi
c11e57b0: 48 dec %eax
c11e57b1: eb 92 jmp c11e5745 <prep_compound_page+0x85>
c11e57b3: ba a8 5b 97 c2 mov $0xc2975ba8,%edx
c11e57b8: e8 e3 ae fd ff call c11c06a0 <dump_page>
c11e57bd: 0f 0b ud2
c11e57bf: 90 nop