Re: [PATCH v2 2/2] LoongArch: Skip address pairing for non-exec sections
Tiezhu Yang <[email protected]> Fri, 24 Jul 2026 14:07:36 +0800
| Newsgroups | dev.linux.lists.loongarch,org.kernel.vger.linux-kernel,org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
On 2026/7/21 下午5:06, Tiezhu Yang wrote: > The module loader currently runs expensive address pairing logic for all > sections blindly during relocation. For massive modules like amdgpu, this > causes the loader to waste lots of CPU cycles analyzing non-exec sections. > > 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/module.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 char *strtab, > Elf_Addr v; > Elf_Sym *sym; > Elf_Rela *rel = (void *) sechdrs[relsec].sh_addr; > + Elf_Shdr *dst_sec = sechdrs + sechdrs[relsec].sh_info; > > pr_debug("%s: Applying relocate section %u to %u\n", __func__, relsec, > sechdrs[relsec].sh_info); > @@ -522,6 +523,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, > > v = 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 == R_LARCH_PCADD_LO12 || type == R_LARCH_GOT_PCADD_LO12) { > bool found = false; > unsigned int j = idx; > @@ -562,6 +567,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, > idx = j; /* Record the previous j-loop end index */ > } > > +apply_normal: > switch (type) { > case R_LARCH_B26: > err = 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/module.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 = (void *) sechdrs[relsec].sh_addr; + Elf_Shdr *dst_sec = sechdrs + sechdrs[relsec].sh_info; + bool is_exec = !!(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 = sym->st_value + rel[i].r_addend; + /* Skip relocation types that exist exclusively in executable sections */ + if (!is_exec) { + err = handler(mod, location, v, rela_stack, &rela_stack_top, type); + if (err) + return err; + continue; + } + if (type == R_LARCH_PCADD_LO12 || type == R_LARCH_GOT_PCADD_LO12) { bool found = false; unsigned int j = 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. Thanks, Tiezhu