Re: [PATCH v1 2/2] LoongArch: mm: Expand modules virtual address space to 2GB

Tiezhu Yang <[email protected]> Mon, 20 Jul 2026 15:16:25 +0800
Newsgroups dev.linux.lists.loongarch,org.kernel.vger.linux-kernel,org.kvack.linux-mm
Message-ID <[email protected]>
On 2026/7/19 下午11:28, Xi Ruoyao wrote:
> On Sun, 2026-07-19 at 12:01 +0300, Mike Rapoport wrote:
>> On Fri, Jul 17, 2026 at 03:57:15PM +0800, Tiezhu Yang wrote:
>>> Frequent "execmem: unable to allocate memory" warnings are observed
>>> during kernel module loading when updating the latest kernel.
>>>
>>> This is because the modules virtual address region on LoongArch is
>>> tightly constrained to 256MB, while ARM64 and RISC-V are natively
>>> configured with a spacious 2GB region.
>>
>> The constraint follows architecture ability to address kernel instructions
>> and data from modules code.
>>
>> I don't know what are loongarch requirements, but I remember that arm64
>> added a layer of relocation support to allow 2G module address space.
> 
> IIUC on LoongArch the size of one module is limited to 256MB, but the
> total size of modules can be up to 2GB, as the module loader creates PLT
> entries for calls across the module boundary.
> 
> I'd seen the "execmem: unable to allocate memory" error loading the
> large amdgpu module.  But after I stripped the amdgpu module those
> warnings gone away.  To me this is very strange: shouldn't the module
> loader just ignore the debug info even if it's not stripped instead of
> requesting execmem for it???

Yes, after "strip --strip-debug drivers/gpu/drm/amd/amdgpu/amdgpu.ko",
there are no "execmem: unable to allocate memory" warnings anymore.

But we usually need the debuginfo, here are the details:

$ readelf -S drivers/gpu/drm/amd/amdgpu/amdgpu.ko
There are 78 section headers, starting at offset 0x3acdf0a0:

Section Headers:
   [Nr] Name              Type             Address           Offset
        Size              EntSize          Flags  Link  Info  Align
   ...
   [23] .debug_info       PROGBITS         0000000000000000  00b73fa9
        000000000bfde1bc  0000000000000000           0     0     1
   [24] .rela.debug_info  RELA             0000000000000000  280f2e40
        0000000011f754a8  0000000000000018   I      75    23     8
   ...


$ objdump -h drivers/gpu/drm/amd/amdgpu/amdgpu.ko

drivers/gpu/drm/amd/amdgpu/amdgpu.ko:     file format elf64-loongarch

Sections:
Idx Name          Size      VMA               LMA               File off 
  Algn
  ...
  14 .debug_info   0bfde1bc  0000000000000000  0000000000000000 
00b73fa9  2**0
                   CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
  ...

The size of .debug_info is 0x0bfde1bc (191.87 MB),
the flag of .debug_info is not SHF_EXECINSTR or SHF_ALLOC.
The size of .rela.debug_info is 0x11f754a8 (287.46 MB),
the flag of .rela.debug_info is I (SHF_INFO_LINK).

Furthermore, I think the following changes are also necessary:

```
diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/module.c
index 7d4d571ee55e..5a4cbd27f97d 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 advanced 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,
```

Thanks,
Tiezhu