Skip to content
This repository was archived by the owner on Feb 5, 2022. It is now read-only.

Commit 67e58f3

Browse files
committed
Add framework for tunables
The tunables framework allows us to uniformly manage and expose global variables inside glibc as switches to users. tunables/README has instructions for glibc developers to add new tunables. Tunables support can be enabled by passing the --enable-tunables configure flag to the configure script. This patch only adds a framework and does not pose any limitations on how tunable values are read from the user. It also adds environment variables used in malloc behaviour tweaking to the tunables framework as a PoC of the compatibility interface. * manual/install.texi: Add --enable-tunables option. * INSTALL: Regenerate. * README.tunables: New file. * Makeconfig (CPPFLAGS): Define TOP_NAMESPACE. (before-compile): Generate dl-tunable-list.h early. * config.h.in: Add HAVE_TUNABLES. * config.make.in: Add have-tunables. * configure.ac: Add --enable-tunables option. * configure: Regenerate. * csu/init-first.c (__libc_init_first): Move __libc_init_secure earlier... * csu/init-first.c (LIBC_START_MAIN):... to here. Include dl-tunables.h, libc-internal.h. (LIBC_START_MAIN) [!SHARED]: Initialize tunables for static binaries. * elf/Makefile (dl-routines): Add dl-tunables. * elf/Versions (ld): Add __tunable_set_val to GLIBC_PRIVATE namespace. * elf/dl-support (_dl_nondynamic_init): Unset MALLOC_CHECK_ only when !HAVE_TUNABLES. * elf/rtld.c (process_envvars): Likewise. * elf/dl-sysdep.c [HAVE_TUNABLES]: Include dl-tunables.h (_dl_sysdep_start): Call __tunables_init. * elf/dl-tunable-types.h: New file. * elf/dl-tunables.c: New file. * elf/dl-tunables.h: New file. * elf/dl-tunables.list: New file. * malloc/tst-malloc-usable-static.c: New test case. * malloc/Makefile (tests-static): Add it. * malloc/arena.c [HAVE_TUNABLES]: Include dl-tunables.h. Define TUNABLE_NAMESPACE. (DL_TUNABLE_CALLBACK (set_mallopt_check)): New function. (DL_TUNABLE_CALLBACK_FNDECL): New macro. Use it to define callback functions. (ptmalloc_init): Set tunable values. * scripts/gen-tunables.awk: New file. * sysdeps/mach/hurd/dl-sysdep.c: Include dl-tunables.h. (_dl_sysdep_start): Call __tunables_init.
1 parent bbe989e commit 67e58f3

25 files changed

+947
-2
lines changed

ChangeLog

+41
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,44 @@
1+
2016-12-31 Siddhesh Poyarekar <[email protected]>
2+
3+
* manual/install.texi: Add --enable-tunables option.
4+
* INSTALL: Regenerate.
5+
* README.tunables: New file.
6+
* Makeconfig (CPPFLAGS): Define TOP_NAMESPACE.
7+
(before-compile): Generate dl-tunable-list.h early.
8+
* config.h.in: Add HAVE_TUNABLES.
9+
* config.make.in: Add have-tunables.
10+
* configure.ac: Add --enable-tunables option.
11+
* configure: Regenerate.
12+
* csu/init-first.c (__libc_init_first): Move
13+
__libc_init_secure earlier...
14+
* csu/init-first.c (LIBC_START_MAIN):... to here.
15+
Include dl-tunables.h, libc-internal.h.
16+
(LIBC_START_MAIN) [!SHARED]: Initialize tunables for static
17+
binaries.
18+
* elf/Makefile (dl-routines): Add dl-tunables.
19+
* elf/Versions (ld): Add __tunable_set_val to GLIBC_PRIVATE
20+
namespace.
21+
* elf/dl-support (_dl_nondynamic_init): Unset MALLOC_CHECK_
22+
only when !HAVE_TUNABLES.
23+
* elf/rtld.c (process_envvars): Likewise.
24+
* elf/dl-sysdep.c [HAVE_TUNABLES]: Include dl-tunables.h
25+
(_dl_sysdep_start): Call __tunables_init.
26+
* elf/dl-tunable-types.h: New file.
27+
* elf/dl-tunables.c: New file.
28+
* elf/dl-tunables.h: New file.
29+
* elf/dl-tunables.list: New file.
30+
* malloc/tst-malloc-usable-static.c: New test case.
31+
* malloc/Makefile (tests-static): Add it.
32+
* malloc/arena.c [HAVE_TUNABLES]: Include dl-tunables.h.
33+
Define TUNABLE_NAMESPACE.
34+
(DL_TUNABLE_CALLBACK (set_mallopt_check)): New function.
35+
(DL_TUNABLE_CALLBACK_FNDECL): New macro. Use it to define
36+
callback functions.
37+
(ptmalloc_init): Set tunable values.
38+
* scripts/gen-tunables.awk: New file.
39+
* sysdeps/mach/hurd/dl-sysdep.c: Include dl-tunables.h.
40+
(_dl_sysdep_start): Call __tunables_init.
41+
142
2016-12-31 Florian Weimer <[email protected]>
243

344
* resolv/resolv.h (RES_BLAST): Deprecate.

INSTALL

+5
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ will be used, and CFLAGS sets optimization options for the compiler.
169169
By default for x86_64, the GNU C Library is built with the vector
170170
math library. Use this option to disable the vector math library.
171171

172+
'--enable-tunables'
173+
Tunables support allows additional library parameters to be
174+
customized at runtime. This is an experimental feature and affects
175+
startup time and is thus disabled by default.
176+
172177
'--build=BUILD-SYSTEM'
173178
'--host=HOST-SYSTEM'
174179
These options are for cross-compiling. If you specify both options

Makeconfig

+16
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,11 @@ CPPFLAGS = $(config-extra-cppflags) $(CPPUNDEFS) $(CPPFLAGS-config) \
934934
$(foreach lib,$(libof-$(basename $(@F))) \
935935
$(libof-$(<F)) $(libof-$(@F)),$(CPPFLAGS-$(lib))) \
936936
$(CPPFLAGS-$(<F)) $(CPPFLAGS-$(@F)) $(CPPFLAGS-$(basename $(@F)))
937+
938+
ifeq (yes,$(have-tunables))
939+
CPPFLAGS += -DTOP_NAMESPACE=glibc
940+
endif
941+
937942
override CFLAGS = -std=gnu11 -fgnu89-inline $(config-extra-cflags) \
938943
$(filter-out %frame-pointer,$(+cflags)) $(+gccwarn-c) \
939944
$(sysdep-CFLAGS) $(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) \
@@ -1108,6 +1113,17 @@ $(common-objpfx)libc-modules.stmp: $(..)scripts/gen-libc-modules.awk \
11081113

11091114
endif
11101115

1116+
# Build the tunables list header early since it could be used by any module in
1117+
# glibc.
1118+
ifeq (yes,$(have-tunables))
1119+
before-compile += $(common-objpfx)dl-tunable-list.h
1120+
1121+
$(common-objpfx)dl-tunable-list.h: $(..)scripts/gen-tunables.awk \
1122+
$(..)elf/dl-tunables.list
1123+
$(AWK) -f $^ > [email protected]
1124+
1125+
endif
1126+
11111127
common-generated += libc-modules.h libc-modules.stmp
11121128

11131129
# The name under which the run-time dynamic linker is installed.

README.tunables

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
TUNABLE FRAMEWORK
2+
=================
3+
4+
Tunables is a feature in the GNU C Library that allows application authors and
5+
distribution maintainers to alter the runtime library behaviour to match their
6+
workload.
7+
8+
The tunable framework allows modules within glibc to register variables that
9+
may be tweaked through an environment variable. It aims to enforce a strict
10+
namespace rule to bring consistency to naming of these tunable environment
11+
variables across the project. This document is a guide for glibc developers to
12+
add tunables to the framework.
13+
14+
ADDING A NEW TUNABLE
15+
--------------------
16+
17+
The TOP_NAMESPACE macro is defined by default as 'glibc'. If distributions
18+
intend to add their own tunables, they should do so in a different top
19+
namespace by overriding the TOP_NAMESPACE macro for that tunable. Downstream
20+
implementations are discouraged from using the 'glibc' top namespace for
21+
tunables they don't already have consensus to push upstream.
22+
23+
There are two steps to adding a tunable:
24+
25+
1. Add a tunable ID:
26+
27+
Modules that wish to use the tunables interface must define the
28+
TUNABLE_NAMESPACE macro. Following this, for each tunable you want to
29+
add, make an entry in elf/dl-tunables.list. The format of the file is as
30+
follows:
31+
32+
TOP_NAMESPACE {
33+
NAMESPACE1 {
34+
TUNABLE1 {
35+
# tunable attributes, one per line
36+
}
37+
# A tunable with default attributes, i.e. string variable.
38+
TUNABLE2
39+
TUNABLE3 {
40+
# its attributes
41+
}
42+
}
43+
NAMESPACE2 {
44+
...
45+
}
46+
}
47+
48+
The list of allowed attributes are:
49+
50+
- type: Data type. Defaults to STRING. Allowed types are:
51+
INT_32, SIZE_T and STRING.
52+
53+
- minval: Optional minimum acceptable value. For a string type
54+
this is the minimum length of the value.
55+
56+
- maxval: Optional maximum acceptable value. For a string type
57+
this is the maximum length of the value.
58+
59+
- env_alias: An alias environment variable
60+
61+
- is_secure: Specify whether the tunable should be read for setuid
62+
binaries. True allows the tunable to be read for
63+
setuid binaries while false disables it. Note that
64+
even if this is set as true and the value is read, it
65+
may not be used if it does not validate against the
66+
acceptable values or is not considered safe by the
67+
module.
68+
69+
2. Call either the TUNABLE_SET_VALUE and pass into it the tunable name and a
70+
pointer to the variable that should be set with the tunable value.
71+
If additional work needs to be done after setting the value, use the
72+
TUNABLE_SET_VALUE_WITH_CALLBACK instead and additionally pass a pointer to
73+
the function that should be called if the tunable value has been set.
74+
75+
FUTURE WORK
76+
-----------
77+
78+
The framework currently only allows a one-time initialization of variables
79+
through environment variables and in some cases, modification of variables via
80+
an API call. A future goals for this project include:
81+
82+
- Setting system-wide and user-wide defaults for tunables through some
83+
mechanism like a configuration file.
84+
85+
- Allow tweaking of some tunables at runtime

config.h.in

+3
Original file line numberDiff line numberDiff line change
@@ -256,4 +256,7 @@
256256
/* PowerPC32 uses fctidz for floating point to long long conversions. */
257257
#define HAVE_PPC_FCTIDZ 0
258258

259+
/* Build glibc with tunables support. */
260+
#define HAVE_TUNABLES 0
261+
259262
#endif

config.make.in

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ use-nscd = @use_nscd@
9696
build-hardcoded-path-in-tests= @hardcoded_path_in_tests@
9797
build-pt-chown = @build_pt_chown@
9898
enable-lock-elision = @enable_lock_elision@
99+
have-tunables = @have_tunables@
99100

100101
# Build tools.
101102
CC = @CC@

configure

+16
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ libc_cv_ssp
666666
base_machine
667667
add_on_subdirs
668668
add_ons
669+
have_tunables
669670
build_pt_chown
670671
build_nscd
671672
link_obsolete_rpc
@@ -782,6 +783,7 @@ enable_systemtap
782783
enable_build_nscd
783784
enable_nscd
784785
enable_pt_chown
786+
enable_tunables
785787
enable_mathvec
786788
with_cpu
787789
'
@@ -1452,6 +1454,7 @@ Optional Features:
14521454
--disable-build-nscd disable building and installing the nscd daemon
14531455
--disable-nscd library functions will not contact the nscd daemon
14541456
--enable-pt_chown Enable building and installing pt_chown
1457+
--enable-tunables Enable tunables support
14551458
--enable-mathvec Enable building and installing mathvec [default
14561459
depends on architecture]
14571460
@@ -3698,6 +3701,19 @@ if test "$build_pt_chown" = yes; then
36983701

36993702
fi
37003703

3704+
# Check whether --enable-tunables was given.
3705+
if test "${enable_tunables+set}" = set; then :
3706+
enableval=$enable_tunables; have_tunables=$enableval
3707+
else
3708+
have_tunables=no
3709+
fi
3710+
3711+
3712+
if test "$have_tunables" = yes; then
3713+
$as_echo "#define HAVE_TUNABLES 1" >>confdefs.h
3714+
3715+
fi
3716+
37013717
# The abi-tags file uses a fairly simplistic model for name recognition that
37023718
# can't distinguish i486-pc-linux-gnu fully from i486-pc-gnu. So we mutate a
37033719
# $host_os of `gnu*' here to be `gnu-gnu*' just so that it can tell.

configure.ac

+10
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,16 @@ if test "$build_pt_chown" = yes; then
421421
AC_DEFINE(HAVE_PT_CHOWN)
422422
fi
423423

424+
AC_ARG_ENABLE([tunables],
425+
[AS_HELP_STRING([--enable-tunables],
426+
[Enable tunables support])],
427+
[have_tunables=$enableval],
428+
[have_tunables=no])
429+
AC_SUBST(have_tunables)
430+
if test "$have_tunables" = yes; then
431+
AC_DEFINE(HAVE_TUNABLES)
432+
fi
433+
424434
# The abi-tags file uses a fairly simplistic model for name recognition that
425435
# can't distinguish i486-pc-linux-gnu fully from i486-pc-gnu. So we mutate a
426436
# $host_os of `gnu*' here to be `gnu-gnu*' just so that it can tell.

csu/init-first.c

-2
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@ _init (int argc, char **argv, char **envp)
7272
__environ = envp;
7373

7474
#ifndef SHARED
75-
__libc_init_secure ();
76-
7775
/* First the initialization which normally would be done by the
7876
dynamic linker. */
7977
_dl_non_dynamic_init ();

csu/libc-start.c

+8
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#include <unistd.h>
2222
#include <ldsodefs.h>
2323
#include <exit-thread.h>
24+
#include <libc-internal.h>
25+
26+
#include <elf/dl-tunables.h>
2427

2528
extern void __libc_init_first (int argc, char **argv, char **envp);
2629

@@ -174,6 +177,11 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
174177
}
175178
}
176179

180+
/* Initialize very early so that tunables can use it. */
181+
__libc_init_secure ();
182+
183+
__tunables_init (__environ);
184+
177185
/* Perform IREL{,A} relocations. */
178186
apply_irel ();
179187

elf/Makefile

+5
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ dl-routines = $(addprefix dl-,load lookup object reloc deps hwcaps \
3535
ifeq (yes,$(use-ldconfig))
3636
dl-routines += dl-cache
3737
endif
38+
39+
ifeq (yes,$(have-tunables))
40+
dl-routines += dl-tunables
41+
endif
42+
3843
all-dl-routines = $(dl-routines) $(sysdep-dl-routines)
3944
# But they are absent from the shared libc, because that code is in ld.so.
4045
elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \

elf/Versions

+3
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,8 @@ ld {
7070

7171
# Internal error handling support. Interposed by libc.so.
7272
_dl_signal_error; _dl_catch_error;
73+
74+
# Set value of a tunable.
75+
__tunable_set_val;
7376
}
7477
}

elf/dl-support.c

+2
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,10 @@ _dl_non_dynamic_init (void)
354354
cp = (const char *) __rawmemchr (cp, '\0') + 1;
355355
}
356356

357+
#if !HAVE_TUNABLES
357358
if (__access ("/etc/suid-debug", F_OK) != 0)
358359
__unsetenv ("MALLOC_CHECK_");
360+
#endif
359361
}
360362

361363
#ifdef DL_PLATFORM_INIT

elf/dl-sysdep.c

+4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
#include <hp-timing.h>
4545
#include <tls.h>
4646

47+
#include <dl-tunables.h>
48+
4749
extern char **_environ attribute_hidden;
4850
extern char _end[] attribute_hidden;
4951

@@ -219,6 +221,8 @@ _dl_sysdep_start (void **start_argptr,
219221
}
220222
#endif
221223

224+
__tunables_init (_environ);
225+
222226
#ifdef DL_SYSDEP_INIT
223227
DL_SYSDEP_INIT;
224228
#endif

elf/dl-tunable-types.h

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* Tunable type information.
2+
3+
Copyright (C) 2016 Free Software Foundation, Inc.
4+
This file is part of the GNU C Library.
5+
6+
The GNU C Library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2.1 of the License, or (at your option) any later version.
10+
11+
The GNU C Library is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public
17+
License along with the GNU C Library; if not, see
18+
<http://www.gnu.org/licenses/>. */
19+
20+
#ifndef _TUNABLE_TYPES_H_
21+
# define _TUNABLE_TYPES_H_
22+
#include <stddef.h>
23+
24+
typedef void (*tunable_callback_t) (void *);
25+
26+
typedef enum
27+
{
28+
TUNABLE_TYPE_INT_32,
29+
TUNABLE_TYPE_SIZE_T,
30+
TUNABLE_TYPE_STRING
31+
} tunable_type_code_t;
32+
33+
typedef struct
34+
{
35+
tunable_type_code_t type_code;
36+
int64_t min;
37+
int64_t max;
38+
} tunable_type_t;
39+
40+
typedef union
41+
{
42+
int64_t numval;
43+
const char *strval;
44+
} tunable_val_t;
45+
46+
#endif

0 commit comments

Comments
 (0)