Skip site navigation (1)Skip section navigation (2)
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>