Re: [PATCH v2 2/2] LoongArch: Skip address pairing for non-exec sections

From: Tiezhu Yang

Date: Fri Jul 24 2026 - 02:08:04 EST


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 <yangtiezhu@xxxxxxxxxxx>
---
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