Re: [PATCH v2 2/2] LoongArch: Skip address pairing for non-exec sections
Huacai Chen <[email protected]> Fri, 31 Jul 2026 15:38:05 +0800
| Newsgroups | dev.linux.lists.loongarch,org.kernel.vger.linux-kernel,org.kvack.linux-mm |
|---|---|
| Message-ID | <CAAhV-H47kc-=A2syzJNLWOD1=TWumvyYWObL+xutrbSRy=WpWA@mail.gmail.com> |
Hi, Tiezhu, On Fri, Jul 24, 2026 at 2:07=E2=80=AFPM Tiezhu Yang <[email protected]= > wrote: > > On 2026/7/21 =E4=B8=8B=E5=8D=885:06, Tiezhu Yang wrote: > > The module loader currently runs expensive address pairing logic for al= l > > sections blindly during relocation. For massive modules like amdgpu, th= is > > causes the loader to waste lots of CPU cycles analyzing non-exec sectio= ns. > > > > Furthermore, there is an inconsistency since module_frob_arch_sections(= ) > > already ignores non-exec sections during the counting phase. > > > > Check the SHF_EXECINSTR flag in apply_relocate_add(). If the section is > > non-exec, skip address pairing and then jump to normal relocation. This > > eliminates redundant search loops to improve module loading efficiency. > > > > Signed-off-by: Tiezhu Yang <[email protected]> > > --- > > arch/loongarch/kernel/module.c | 6 ++++++ > > 1 file changed, 6 insertions(+) > > > > diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/mod= ule.c > > index 7d4d571ee55e..c84ac1546dc6 100644 > > --- a/arch/loongarch/kernel/module.c > > +++ b/arch/loongarch/kernel/module.c > > @@ -484,6 +484,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const cha= r *strtab, > > Elf_Addr v; > > Elf_Sym *sym; > > Elf_Rela *rel =3D (void *) sechdrs[relsec].sh_addr; > > + Elf_Shdr *dst_sec =3D sechdrs + sechdrs[relsec].sh_info; > > > > pr_debug("%s: Applying relocate section %u to %u\n", __func__, re= lsec, > > sechdrs[relsec].sh_info); > > @@ -522,6 +523,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const ch= ar *strtab, > > > > v =3D sym->st_value + rel[i].r_addend; > > > > + /* Skip address pairing for non-exec sections */ > > + if (!(dst_sec->sh_flags & SHF_EXECINSTR)) > > + goto apply_normal; > > + > > if (type =3D=3D R_LARCH_PCADD_LO12 || type =3D=3D R_LARCH= _GOT_PCADD_LO12) { > > bool found =3D false; > > unsigned int j =3D idx; > > @@ -562,6 +567,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const cha= r *strtab, > > idx =3D j; /* Record the previous j-loop end inde= x */ > > } > > > > +apply_normal: > > switch (type) { > > case R_LARCH_B26: > > err =3D apply_r_larch_b26(mod, sechdrs, location, > > > > According to the LoongArch ABI specification, the following relocation > types exist exclusively in executable code sections: > > R_LARCH_PCADD_LO12 > R_LARCH_GOT_PCADD_LO12 > R_LARCH_B26 > R_LARCH_GOT_PC_HI20...R_LARCH_GOT_PC_LO12 > R_LARCH_GOT_PCADD_HI20...R_LARCH_GOT_PCADD_LO12 > R_LARCH_SOP_PUSH_PLT_PCREL > > https://github.com/loongson/la-abi-specs/blob/release/laelf.adoc > > Thus, here is a better way: > > ``` > diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/modul= e.c > index 7d4d571ee55e..b1452b8adc63 100644 > --- a/arch/loongarch/kernel/module.c > +++ b/arch/loongarch/kernel/module.c > @@ -484,6 +484,8 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char > *strtab, > Elf_Addr v; > Elf_Sym *sym; > Elf_Rela *rel =3D (void *) sechdrs[relsec].sh_addr; > + Elf_Shdr *dst_sec =3D sechdrs + sechdrs[relsec].sh_info; > + bool is_exec =3D !!(dst_sec->sh_flags & SHF_EXECINSTR); > > pr_debug("%s: Applying relocate section %u to %u\n", __func__, > relsec, > sechdrs[relsec].sh_info); > @@ -522,6 +524,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const > char *strtab, > > v =3D sym->st_value + rel[i].r_addend; > > + /* Skip relocation types that exist exclusively in > executable sections */ > + if (!is_exec) { > + err =3D handler(mod, location, v, rela_stack, > &rela_stack_top, type); > + if (err) > + return err; > + continue; > + } > + > if (type =3D=3D R_LARCH_PCADD_LO12 || type =3D=3D > R_LARCH_GOT_PCADD_LO12) { > bool found =3D false; > unsigned int j =3D idx; > ``` > > For the non-exec sections such as .orc_unwind_ip: > > fedora@linux:~/7.2-rc3.git$ objdump -h > drivers/gpu/drm/amd/amdgpu/amdgpu.ko | grep -A 1 .orc_unwind_ip > 32 .orc_unwind_ip 000ac104 0000000000000000 0000000000000000 > 18592470 2**0 > CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA > > there are 176193 relocation entries: > > fedora@linux:~/7.2-rc3.git$ readelf -rW > drivers/gpu/drm/amd/amdgpu/amdgpu.o | grep .rela.orc_unwind_ip > Relocation section '.rela.orc_unwind_ip' at offset 0x3a5321e8 contains > 176193 entries: > > Using the section flag check reduces the operation to a single check for > massive data sections; otherwise, the loader would have to perform six > redundant type comparisons across the if-statement and switch-case for > every single relocation entry. Please just drop this patch and make the first one better. Now the first patch has a risk that the distance between .init.text and .text of the same module exceeds 128MB. I solved it and you can verify: https://github.com/chenhuacai/linux/commit/f87f9d82869ebc71dca4c02bdff1cd20= 3913a98f Huacai > > Thanks, > Tiezhu >