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. */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to