On 27/04/19(Sat) 21:45, Nathanael Rensen wrote:
> 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.

As for the other diff, could you explain in words what does your change
do?

Comments below :)

> 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 */
> -             }
> -     }

Currently this loop isn't executed when being called from
_dl_cache_grpsym_list().  Is there any risk of adding a duplicate?  Does
it buy us much to remove the lookup?

>       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;
> +             }

Do I understand correctly that you're not recursing if not object is
inserted?  Would it makes sense to have _dl_link_grpsym() return a
value reflecting if it inserted an object or not?

>  
> -     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