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
>