Date: Thu, 23 Apr 2015 07:32:29 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r281880 - in stable/10/sys: kern sys Message-ID: <201504230732.t3N7WT4L032327@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Thu Apr 23 07:32:28 2015 New Revision: 281880 URL: https://svnweb.freebsd.org/changeset/base/281880 Log: MFC r281003: Speed up symbol lookup for the amd64 kernel modules. Modified: stable/10/sys/kern/link_elf_obj.c stable/10/sys/sys/elf_common.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/kern/link_elf_obj.c ============================================================================== --- stable/10/sys/kern/link_elf_obj.c Thu Apr 23 02:50:06 2015 (r281879) +++ stable/10/sys/kern/link_elf_obj.c Thu Apr 23 07:32:28 2015 (r281880) @@ -173,6 +173,7 @@ static struct linker_class link_elf_clas }; static int relocate_file(elf_file_t ef); +static void elf_obj_cleanup_globals_cache(elf_file_t); static void link_elf_error(const char *filename, const char *s) @@ -1046,6 +1047,13 @@ relocate_file(elf_file_t ef) } } + /* + * Only clean SHN_FBSD_CACHED for successfull return. If we + * modified symbol table for the object but found an + * unresolved symbol, there is no reason to roll back. + */ + elf_obj_cleanup_globals_cache(ef); + return 0; } @@ -1194,6 +1202,21 @@ link_elf_each_function_nameval(linker_fi return (0); } +static void +elf_obj_cleanup_globals_cache(elf_file_t ef) +{ + Elf_Sym *sym; + Elf_Size i; + + for (i = 0; i < ef->ddbsymcnt; i++) { + sym = ef->ddbsymtab + i; + if (sym->st_shndx == SHN_FBSD_CACHED) { + sym->st_shndx = SHN_UNDEF; + sym->st_value = 0; + } + } +} + /* * Symbol lookup function that can be used when the symbol index is known (ie * in relocations). It uses the symbol index instead of doing a fully fledged @@ -1205,7 +1228,7 @@ static Elf_Addr elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps) { elf_file_t ef = (elf_file_t)lf; - const Elf_Sym *sym; + Elf_Sym *sym; const char *symbol; Elf_Addr ret; @@ -1233,7 +1256,22 @@ elf_obj_lookup(linker_file_t lf, Elf_Siz if (*symbol == 0) return (0); ret = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); - return ret; + + /* + * Cache global lookups during module relocation. The failure + * case is particularly expensive for callers, who must scan + * through the entire globals table doing strcmp(). Cache to + * avoid doing such work repeatedly. + * + * After relocation is complete, undefined globals will be + * restored to SHN_UNDEF in elf_obj_cleanup_globals_cache(), + * above. + */ + if (ret != 0) { + sym->st_shndx = SHN_FBSD_CACHED; + sym->st_value = ret; + } + return (ret); case STB_WEAK: printf("link_elf_obj: Weak symbols not supported\n"); Modified: stable/10/sys/sys/elf_common.h ============================================================================== --- stable/10/sys/sys/elf_common.h Thu Apr 23 02:50:06 2015 (r281879) +++ stable/10/sys/sys/elf_common.h Thu Apr 23 07:32:28 2015 (r281880) @@ -251,6 +251,9 @@ typedef struct { #define SHN_LOPROC 0xff00 /* First processor-specific. */ #define SHN_HIPROC 0xff1f /* Last processor-specific. */ #define SHN_LOOS 0xff20 /* First operating system-specific. */ +#define SHN_FBSD_CACHED SHN_LOOS /* Transient, for sys/kern/link_elf_obj + linker only: Cached global in local + symtab. */ #define SHN_HIOS 0xff3f /* Last operating system-specific. */ #define SHN_ABS 0xfff1 /* Absolute values. */ #define SHN_COMMON 0xfff2 /* Common data. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504230732.t3N7WT4L032327>