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@xxxxxxxxx> 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
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
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