Date: Sun, 22 May 2022 21:20:40 +0000 From: John F Carr <jfc@mit.edu> To: "tuexen@freebsd.org" <tuexen@freebsd.org> Cc: "freebsd-arm@freebsd.org" <freebsd-arm@freebsd.org> Subject: Re: clang14 issue triggering PR264094? Message-ID: <A82D46B2-72D6-437A-96F4-1FBDCF0C74A1@exchange.mit.edu> In-Reply-To: <41AF8299-1B05-487A-AE34-11BCA460C3B1@freebsd.org> References: <41AF8299-1B05-487A-AE34-11BCA460C3B1@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On May 22, 2022, at 16:41 , tuexen@freebsd.org wrote: >=20 > Dear all, >=20 > I'm trying to analyze https://bugs.freebsd.org/bugzilla/show_bug.cgi?id= =3D264094 >=20 > The relevant file is: > https://cgit.freebsd.org/src/tree/sys/netinet/cc/cc_htcp.c >=20 > It is interesting that the panic happens on arm64, but not amd64. It does > happen when using clang14 (most recent version in the main tree), it does > not happen when using clang13. > I also does not happen using clang14 when forcing htcp_recalc_beta() not > to be inlined. >=20 > The panic happens when accessing V_htcp_adaptive_backoff in > https://cgit.freebsd.org/src/tree/sys/netinet/cc/cc_htcp.c#n471 >=20 > Since this looks strange to me, I disassembled htcp_recalc_beta() when > using clang14 and the function not being inlined. This is the relevant > code: >=20 > (kgdb) disassemble htcp_recalc_beta > Dump of assembler code for function htcp_recalc_beta: > 0x00000000000113cc <+0>: stp x29, x30, [sp, #-16]! > 0x00000000000113d0 <+4>: mov x29, sp > 0x00000000000113d4 <+8>: ldr x8, [x0] ; x8 =3D ccv > 0x00000000000113d8 <+12>: ldr x9, [x18] ; x9 =3D curthread > 0x00000000000113dc <+16>: adrp x10, 0x21000 ; x10 =3D ??? > 0x00000000000113e0 <+20>: ldr x9, [x9, #1368] ; x9 =3D curthread->td_= vnet > 0x00000000000113e4 <+24>: ldr x10, [x10, #2168] ; x10 =3D ??? > 0x00000000000113e8 <+28>: ldr x9, [x9, #40] ; x9 =3D curthread->td_= vnet->vnet_data_base > 0x00000000000113ec <+32>: ldr w9, [x9, x10] ; w9 =3D V_htcp_adaptiv= e_backoff ??? > 0x00000000000113f0 <+36>: cbz w9, 0x11428 <htcp_recalc_beta+92> >=20 > I don't understand the computations in relation to x10, which is the offs= et used to get the relevant variable. >=20 > However, this code works. >=20 > Looking at the code generated by clang13 when htcp_recalc_beta() is inlin= ed, one gets: >=20 > 0xffff000150610f28 <+212>: ldr x10, [x0] ; x10 =3D ccv > 0xffff000150610f2c <+216>: ldr x11, [x18] ; x11 =3D curth= read > 0xffff000150610f30 <+220>: ldr x11, [x11, #1368] ; x11 =3D curth= read->td_vnet > 0xffff000150610f34 <+224>: ldr x12, [x11, #40] ; x12 =3D curth= read->td_vnet->vnet_data_base > 0xffff000150610f38 <+228>: adrp x11, 0xffff000150621000 ; ??? > 0xffff000150610f3c <+232>: ldr x11, [x11, #2256] ; ??? > 0xffff000150610f40 <+236>: ldr w12, [x12, x11] > 0xffff000150610f44 <+240>: cbz w12, 0xffff000150610f7c <htcp_ack_receiv= ed+296> >=20 > It looks similar and it does work. >=20 > Now comes the inlined code from clang14: >=20 > 0xffff0001016acf28 <+212>: ldr x10, [x0] ; x10 =3D ccv > 0xffff0001016acf2c <+216>: ldr x11, [x18] ; x11 =3D curthread > 0xffff0001016acf30 <+220>: ldr x12, [x11, #1368] ; x12 =3D curthread->t= d_vnet > 0xffff0001016acf34 <+224>: nop > 0xffff0001016acf38 <+228>: adr x11, 0xffff0001016bd520 <vnet_entry_htcp= _adaptive_backoff> > 0xffff0001016acf3c <+232>: ldr x12, [x12, #40] ; x12 =3D curthread->t= d_vnet->vnet_data_base > =3D=3D>0xffff0001016acf40 <+236>: ldr w12, [x12, x11] > 0xffff0001016acf44 <+240>: cbz w12, 0xffff0001016acf7c <htcp_ack_receiv= ed+296> >=20 > The line marked with =3D=3D> is the line where the panic happens. It look= s that the offset computation is different. >=20 > Is this an issue with clang14? Any idea what is going wrong? >=20 > Thanks for any help! >=20 > Best regards > Michael >=20 >=20 That nop next to the adr instruction makes me think a 32 bit relocation wen= t wrong. These relocations normally consume two instructions but the linke= r can patch one into a nop if it is not needed. Usually you have a pair of= instructions adrp+adr or, as in the clang13 example, adrp+ld or adrp+st. = The adrp computes a page-aligned address within a 32 bit offset of the PC = and the next instruction has low 12 bits of the address. The problem could= be in the compiler or the linker. What does the assembly or disassembled = .o look like before it gets linked?
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?A82D46B2-72D6-437A-96F4-1FBDCF0C74A1>