The diff below speeds up ld.so library loading where the dependency tree
is broad and deep, such as samba's smbd which links over 100 libraries.

See for example https://marc.info/?l=openbsd-misc&m=155007285712913&w=2 

The timings below are for ldd /usr/local/sbin/smbd:

Timing without diff: 2m02.50s real     2m02.48s user     0m00.02s system
Timing with diff   : 0m00.03s real     0m00.02s user     0m00.01s system

Note that these timings are for a build of a recent samba master tree
(linked with kerberos) which is probably slower than the OpenBSD port.

While this diff speeds up loading (e.g. ldd) a second diff (part 2) is
also helpful to speed up library initialisation.

Nathanael


Index: libexec/ld.so/dlfcn.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/dlfcn.c,v
retrieving revision 1.102
diff -u -p -p -u -r1.102 dlfcn.c
--- libexec/ld.so/dlfcn.c       22 Oct 2018 01:59:08 -0000      1.102
+++ libexec/ld.so/dlfcn.c       27 Apr 2019 13:24:02 -0000
@@ -93,7 +93,7 @@ dlopen(const char *libname, int flags)
                /* if opened but grpsym_list has not been created */
                if (OBJECT_DLREF_CNT(object) == 1) {
                        /* add first object manually */
-                       _dl_link_grpsym(object, 1);
+                       _dl_link_grpsym(object);
                        _dl_cache_grpsym_list(object);
                }
                goto loaded;
Index: libexec/ld.so/library_subr.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/library_subr.c,v
retrieving revision 1.48
diff -u -p -p -u -r1.48 library_subr.c
--- libexec/ld.so/library_subr.c        28 Aug 2017 14:06:22 -0000      1.48
+++ libexec/ld.so/library_subr.c        27 Apr 2019 13:24:02 -0000
@@ -527,19 +527,13 @@ _dl_link_child(elf_object_t *dep, elf_ob
 static unsigned int _dl_grpsym_gen = 0;
 
 void
-_dl_link_grpsym(elf_object_t *object, int checklist)
+_dl_link_grpsym(elf_object_t *object)
 {
        struct dep_node *n;
 
-       if (checklist) {
-               TAILQ_FOREACH(n, &_dl_loading_object->grpsym_list, next_sib)
-                       if (n->data == object)
-                               return; /* found, dont bother adding */
-       } else {
-               if (object->grpsym_gen == _dl_grpsym_gen) {
+       TAILQ_FOREACH(n, &_dl_loading_object->grpsym_list, next_sib)
+               if (n->data == object)
                        return; /* found, dont bother adding */
-               }
-       }
        object->grpsym_gen = _dl_grpsym_gen;
 
        n = _dl_malloc(sizeof *n);
@@ -572,6 +566,7 @@ _dl_cache_grpsym_list_setup(elf_object_t
 void
 _dl_cache_grpsym_list(elf_object_t *object)
 {
+       int recurse = 0;
        struct dep_node *n;
 
        /*
@@ -581,8 +576,12 @@ _dl_cache_grpsym_list(elf_object_t *obje
         */
 
        TAILQ_FOREACH(n, &object->child_list, next_sib)
-               _dl_link_grpsym(n->data, 0);
+               if (n->data->grpsym_gen != _dl_grpsym_gen) {
+                       _dl_link_grpsym(n->data);
+                       recurse = 1;
+               }
 
-       TAILQ_FOREACH(n, &object->child_list, next_sib)
-               _dl_cache_grpsym_list(n->data);
+       if (recurse)
+               TAILQ_FOREACH(n, &object->child_list, next_sib)
+                       _dl_cache_grpsym_list(n->data);
 }
Index: libexec/ld.so/loader.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/loader.c,v
retrieving revision 1.177
diff -u -p -p -u -r1.177 loader.c
--- libexec/ld.so/loader.c      3 Dec 2018 05:29:56 -0000       1.177
+++ libexec/ld.so/loader.c      27 Apr 2019 13:24:02 -0000
@@ -360,7 +360,7 @@ _dl_load_dep_libs(elf_object_t *object, 
        }
 
        /* add first object manually */
-       _dl_link_grpsym(object, 1);
+       _dl_link_grpsym(object);
        _dl_cache_grpsym_list_setup(object);
 
        return(0);
@@ -543,7 +543,7 @@ _dl_boot(const char **argv, char **envp,
        _dl_add_object(dyn_obj);
 
        dyn_obj->refcount++;
-       _dl_link_grpsym(dyn_obj, 1);
+       _dl_link_grpsym(dyn_obj);
 
        dyn_obj->status |= STAT_RELOC_DONE;
        _dl_set_sod(dyn_obj->load_name, &dyn_obj->sod);
Index: libexec/ld.so/resolve.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/resolve.h,v
retrieving revision 1.90
@@ -271,7 +272,7 @@ int _dl_load_dep_libs(elf_object_t *obje
 int _dl_rtld(elf_object_t *object);
 void _dl_call_init(elf_object_t *object);
 void _dl_link_child(elf_object_t *dep, elf_object_t *p);
-void _dl_link_grpsym(elf_object_t *object, int checklist);
+void _dl_link_grpsym(elf_object_t *object);
 void _dl_cache_grpsym_list(elf_object_t *object);
 void _dl_cache_grpsym_list_setup(elf_object_t *object);
 void _dl_link_grpref(elf_object_t *load_group, elf_object_t *load_object);

Reply via email to