[4/4] ld.so: Add --list-tunables to print tunable values

Message ID 20200918160709.949608-5-hjl.tools@gmail.com
State Superseded
Headers
Series [1/4] x86: Initialize CPU info via IFUNC relocation [BZ 26203] |

Commit Message

H.J. Lu Sept. 18, 2020, 4:07 p.m. UTC
  Pass --list-tunables to ld.so to print tunables with min and max values.
---
 NEWS                 |  2 ++
 elf/Makefile         |  8 ++++++++
 elf/dl-tunables.c    | 36 ++++++++++++++++++++++++++++++++++++
 elf/dl-tunables.h    |  2 ++
 elf/rtld.c           | 31 +++++++++++++++++++++++++++++--
 manual/tunables.texi | 37 +++++++++++++++++++++++++++++++++++++
 6 files changed, 114 insertions(+), 2 deletions(-)
  

Comments

Florian Weimer Sept. 21, 2020, 8:25 a.m. UTC | #1
* H. J. Lu:

> Pass --list-tunables to ld.so to print tunables with min and max values.

The code changes look good to me.  Not sure about the NEWS entry and
what conventions we want to use there.

Thanks,
Florian
  

Patch

diff --git a/NEWS b/NEWS
index fc8dd15439..f47516a02f 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,8 @@  Version 2.33
 
 Major new features:
 
+* Pass --list-tunables to ld.so to print tunable values.
+
 * The mallinfo2 function is added to report statistics as per mallinfo,
   but with larger field widths to accurately report values that are
   larger than fit in an integer.
diff --git a/elf/Makefile b/elf/Makefile
index 0b78721848..11e90c9d17 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -44,6 +44,10 @@  dl-routines += dl-tunables
 tunables-type = $(addprefix TUNABLES_FRONTEND_,$(have-tunables))
 CPPFLAGS-dl-tunables.c += -DTUNABLES_FRONTEND=$(tunables-type)
 
+ifeq (yesyes,$(build-shared)$(run-built-tests))
+tests-special += $(objpfx)list-tunables.out
+endif
+
 # Make sure that the compiler does not insert any library calls in tunables
 # code paths.
 ifeq (yes,$(have-loop-to-function))
@@ -1796,3 +1800,7 @@  $(objpfx)tst-tls-ie-dlmopen.out: \
   $(objpfx)tst-tls-ie-mod6.so
 
 $(objpfx)tst-tls-surplus: $(libdl)
+
+$(objpfx)list-tunables.out: $(objpfx)ld.so
+	$(objpfx)ld.so --list-tunables > $@; \
+	$(evaluate-test)
diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
index b44174fe71..53226ef258 100644
--- a/elf/dl-tunables.c
+++ b/elf/dl-tunables.c
@@ -368,6 +368,42 @@  __tunables_init (char **envp)
     }
 }
 
+void
+__tunables_print (void)
+{
+  for (int i = 0; i < sizeof (tunable_list) / sizeof (tunable_t); i++)
+    {
+      tunable_t *cur = &tunable_list[i];
+      _dl_printf ("%s: ", cur->name);
+      switch (cur->type.type_code)
+	{
+	case TUNABLE_TYPE_INT_32:
+	  _dl_printf ("%d (min: %d, max: %d)\n",
+		      (int) cur->val.numval,
+		      (int) cur->type.min,
+		      (int) cur->type.max);
+	  break;
+	case TUNABLE_TYPE_UINT_64:
+	  _dl_printf ("0x%lx (min: 0x%lx, max: 0x%lx)\n",
+		      (long int) cur->val.numval,
+		      (long int) cur->type.min,
+		      (long int) cur->type.max);
+	  break;
+	case TUNABLE_TYPE_SIZE_T:
+	  _dl_printf ("0x%Zx (min: 0x%Zx, max: 0x%Zx)\n",
+		      (size_t) cur->val.numval,
+		      (size_t) cur->type.min,
+		      (size_t) cur->type.max);
+	  break;
+	case TUNABLE_TYPE_STRING:
+	  _dl_printf ("%s\n", cur->val.strval ? cur->val.strval : "");
+	  break;
+	default:
+	  __builtin_unreachable ();
+	}
+    }
+}
+
 /* Set the tunable value.  This is called by the module that the tunable exists
    in. */
 void
diff --git a/elf/dl-tunables.h b/elf/dl-tunables.h
index b1add3184f..a2c728f0dd 100644
--- a/elf/dl-tunables.h
+++ b/elf/dl-tunables.h
@@ -69,9 +69,11 @@  typedef struct _tunable tunable_t;
 # include "dl-tunable-list.h"
 
 extern void __tunables_init (char **);
+extern void __tunables_print (void);
 extern void __tunable_get_val (tunable_id_t, void *, tunable_callback_t);
 extern void __tunable_set_val (tunable_id_t, void *, void *, void *);
 rtld_hidden_proto (__tunables_init)
+rtld_hidden_proto (__tunables_print)
 rtld_hidden_proto (__tunable_get_val)
 rtld_hidden_proto (__tunable_set_val)
 
diff --git a/elf/rtld.c b/elf/rtld.c
index 5b882163fa..f76b9b0265 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -48,6 +48,10 @@ 
 #include <array_length.h>
 #include <libc-early-init.h>
 
+#if HAVE_TUNABLES
+# include <dl-tunables.h>
+#endif
+
 #include <assert.h>
 
 /* Only enables rtld profiling for architectures which provides non generic
@@ -168,7 +172,7 @@  static void audit_list_add_dynamic_tag (struct audit_list *,
 static const char *audit_list_next (struct audit_list *);
 
 /* This is a list of all the modes the dynamic loader can be in.  */
-enum mode { normal, list, verify, trace };
+enum mode { normal, list, verify, trace, list_tunables };
 
 /* Process all environments variables the dynamic linker must recognize.
    Since all of them start with `LD_' we are a bit smarter while finding
@@ -1263,9 +1267,27 @@  dl_main (const ElfW(Phdr) *phdr,
 	    _dl_argc -= 2;
 	    _dl_argv += 2;
 	  }
+#if HAVE_TUNABLES
+	else if (! strcmp (_dl_argv[1], "--list-tunables"))
+	  {
+	    mode = list_tunables;
+
+	    ++_dl_skip_args;
+	    --_dl_argc;
+	    ++_dl_argv;
+	  }
+#endif
 	else
 	  break;
 
+#if HAVE_TUNABLES
+      if (__builtin_expect (mode, normal) == list_tunables)
+	{
+	  __tunables_print ();
+	  _exit (0);
+	}
+#endif
+
       /* If we have no further argument the program was called incorrectly.
 	 Grant the user some education.  */
       if (_dl_argc < 2)
@@ -1292,7 +1314,12 @@  of this helper program; chances are you did not intend to run this program.\n\
   --inhibit-rpath LIST  ignore RUNPATH and RPATH information in object names\n\
 			in LIST\n\
   --audit LIST          use objects named in LIST as auditors\n\
-  --preload LIST        preload objects named in LIST\n");
+  --preload LIST        preload objects named in LIST\n"
+#if HAVE_TUNABLES
+"\
+  --list-tunables       list all tunables with minimum and maximum values\n"
+#endif
+	  );
 
       ++_dl_skip_args;
       --_dl_argc;
diff --git a/manual/tunables.texi b/manual/tunables.texi
index 23ef0d40e7..38c8578229 100644
--- a/manual/tunables.texi
+++ b/manual/tunables.texi
@@ -28,6 +28,43 @@  Finally, the set of tunables available may vary between distributions as
 the tunables feature allows distributions to add their own tunables under
 their own namespace.
 
+Passing @option{--list-tunables} to the dynamic loader to print all
+tunables with minimum and maximum values:
+
+@example
+$ /lib64/ld-linux-x86-64.so.2 --list-tunables
+glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10)
+glibc.elision.skip_lock_after_retries: 3 (min: -2147483648, max: 2147483647)
+glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0xffffffffffffffff)
+glibc.malloc.perturb: 0 (min: 0, max: 255)
+glibc.cpu.x86_shared_cache_size: 0x100000 (min: 0x0, max: 0xffffffffffffffff)
+glibc.elision.tries: 3 (min: -2147483648, max: 2147483647)
+glibc.elision.enable: 0 (min: 0, max: 1)
+glibc.cpu.x86_rep_movsb_threshold: 0x800 (min: 0x100, max: 0xffffffffffffffff)
+glibc.malloc.mxfast: 0x0 (min: 0x0, max: 0xffffffffffffffff)
+glibc.elision.skip_lock_busy: 3 (min: -2147483648, max: 2147483647)
+glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0xffffffffffffffff)
+glibc.cpu.x86_rep_stosb_threshold: 0x800 (min: 0x1, max: 0xffffffffffffffff)
+glibc.cpu.x86_non_temporal_threshold: 0x600000 (min: 0x0, max: 0xffffffffffffffff)
+glibc.cpu.x86_shstk: 
+glibc.cpu.hwcap_mask: 0x6 (min: 0x0, max: 0xffffffffffffffff)
+glibc.malloc.mmap_max: 0 (min: -2147483648, max: 2147483647)
+glibc.elision.skip_trylock_internal_abort: 3 (min: -2147483648, max: 2147483647)
+glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0xffffffffffffffff)
+glibc.cpu.x86_ibt: 
+glibc.cpu.hwcaps: 
+glibc.elision.skip_lock_internal_abort: 3 (min: -2147483648, max: 2147483647)
+glibc.malloc.arena_max: 0x0 (min: 0x1, max: 0xffffffffffffffff)
+glibc.malloc.mmap_threshold: 0x0 (min: 0x0, max: 0xffffffffffffffff)
+glibc.cpu.x86_data_cache_size: 0x8000 (min: 0x0, max: 0xffffffffffffffff)
+glibc.malloc.tcache_count: 0x0 (min: 0x0, max: 0xffffffffffffffff)
+glibc.malloc.arena_test: 0x0 (min: 0x1, max: 0xffffffffffffffff)
+glibc.pthread.mutex_spin_count: 100 (min: 0, max: 32767)
+glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0xffffffffffffffff)
+glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0xffffffffffffffff)
+glibc.malloc.check: 0 (min: 0, max: 3)
+@end example
+
 @menu
 * Tunable names::  The structure of a tunable name
 * Memory Allocation Tunables::  Tunables in the memory allocation subsystem