Subject: Re: reducing library searches in ld.elf_so
To: Charles Hannum <abuse@spamalicious.com>
From: Bang Jun-Young <junyoung@mogua.com>
List: tech-userlevel
Date: 09/28/2002 12:16:18
On Sun, Sep 22, 2002 at 07:34:25PM +0000, Charles Hannum wrote:
> 
> While your patch may help a little, I do not think it's sufficient
> even to fully mitigate the problem you're talking about.  The problem
> is that it only affects lookup hits, not misses, and so a certain
> number of missed lookups will occur in many (most?) cases anyway.
> 
> Perhaps better would be to hook into:
> 
>         for (sp = _rtld_paths; sp != NULL; sp = sp->sp_next)
>                 if ((pathname = _rtld_search_library_path(name, namelen,
>                     sp->sp_path, sp->sp_pathlen)) != NULL) 
>                         return (pathname);
> 
> (and the _rtld_default_paths case below it), and to record both
> positive and negative hits here by file name (without the path).  This
> would allow us to do a simple table lookup the next time we see the
> file name.

How about this one? This way we can save lots of open(2) syscalls and
expensive mallocs & strcpys while loading mozilla. Also, it doesn't affect
performance of small binaries, since _rtld_invalid_paths is usually NULL 
with them.

Index: search.c
===================================================================
RCS file: /cvsroot/basesrc/libexec/ld.elf_so/search.c,v
retrieving revision 1.13
diff -u -r1.13 search.c
--- search.c	2002/09/24 12:52:20	1.13
+++ search.c	2002/09/28 03:08:36
@@ -55,6 +55,8 @@
 /*
  * Data declarations.
  */
+Search_Path    *_rtld_invalid_paths;
+
 static Obj_Entry *_rtld_search_library_path __P((const char *, size_t,
     const char *, size_t, int));
 
@@ -68,6 +70,17 @@
 {
 	char *pathname;
 	Obj_Entry *obj;
+	Search_Path *sp;
+
+	for (sp = _rtld_invalid_paths; sp != NULL; sp = sp->sp_next) {
+		/* Compare names first, then dirpaths. */
+		if (!strncmp(name, sp->sp_path + sp->sp_pathlen - namelen,
+		    namelen) && !strncmp(dir, sp->sp_path, sp->sp_pathlen -
+		    dirlen - 1)) {
+			dbg(("  \"%s/%s\" marked invalid", dir, name));
+			return NULL;
+		}
+	}
 
 	pathname = xmalloc(dirlen + 1 + namelen + 1);
 	(void)strncpy(pathname, dir, dirlen);
@@ -76,8 +89,10 @@
 
 	dbg(("  Trying \"%s\"", pathname));
 	obj = _rtld_load_object(pathname, mode);
-	if (obj == NULL)
+	if (obj == NULL) {
+		_rtld_add_paths(&_rtld_invalid_paths, pathname);
 		free(pathname);
+	}
 	return obj;
 }

Jun-Young
 
-- 
Bang Jun-Young <junyoung@mogua.com>