Skip to content

Commit 080c432

Browse files
fidomaxpalmer-dabbelt
authored andcommitted
riscv: optimize ELF relocation function in riscv
The patch can optimize the running times of insmod command by modify ELF relocation function. In the 5.10 and latest kernel, when install the riscv ELF drivers which contains multiple symbol table items to be relocated, kernel takes a lot of time to execute the relocation. For example, we install a 3+MB driver need 180+s. We focus on the riscv architecture handle R_RISCV_HI20 and R_RISCV_LO20 type items relocation function in the arch\riscv\kernel\module.c and find that there are two-loops in the function. If we modify the begin number in the second for-loops iteration, we could save significant time for installation. We install the same 3+MB driver could just need 2s. Signed-off-by: Amma Lee <lixiaoyun@binary-semi.com> Signed-off-by: Maxim Kochetkov <fido_max@inbox.ru> Reviewed-by: Charlie Jenkins <charlie@rivosinc.com> Link: https://lore.kernel.org/r/20231214063906.13612-1-fido_max@inbox.ru Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
1 parent 1024340 commit 080c432

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

arch/riscv/kernel/module.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
783783
Elf_Sym *sym;
784784
void *location;
785785
unsigned int i, type;
786+
unsigned int j_idx = 0;
786787
Elf_Addr v;
787788
int res;
788789
unsigned int num_relocations = sechdrs[relsec].sh_size / sizeof(*rel);
@@ -833,9 +834,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
833834
v = sym->st_value + rel[i].r_addend;
834835

835836
if (type == R_RISCV_PCREL_LO12_I || type == R_RISCV_PCREL_LO12_S) {
836-
unsigned int j;
837+
unsigned int j = j_idx;
838+
bool found = false;
837839

838-
for (j = 0; j < sechdrs[relsec].sh_size / sizeof(*rel); j++) {
840+
do {
839841
unsigned long hi20_loc =
840842
sechdrs[sechdrs[relsec].sh_info].sh_addr
841843
+ rel[j].r_offset;
@@ -864,16 +866,26 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
864866
hi20 = (offset + 0x800) & 0xfffff000;
865867
lo12 = offset - hi20;
866868
v = lo12;
869+
found = true;
867870

868871
break;
869872
}
870-
}
871-
if (j == sechdrs[relsec].sh_size / sizeof(*rel)) {
873+
874+
j++;
875+
if (j > sechdrs[relsec].sh_size / sizeof(*rel))
876+
j = 0;
877+
878+
} while (j_idx != j);
879+
880+
if (!found) {
872881
pr_err(
873882
"%s: Can not find HI20 relocation information\n",
874883
me->name);
875884
return -EINVAL;
876885
}
886+
887+
/* Record the previous j-loop end index */
888+
j_idx = j;
877889
}
878890

879891
if (reloc_handlers[type].accumulate_handler)

0 commit comments

Comments
 (0)