a47951
Maintain an explicit order of tunables, so that the tunable_list
a47951
array and the tunable_id_t constant can remain consistent over time.
a47951
a47951
Related to this upstream bug:
a47951
a47951
  Internal tunables ABI depends on awk array iteration order
a47951
  <https://sourceware.org/bugzilla/show_bug.cgi?id=30027>
a47951
a47951
The new dl-tunables.list files are already on the sysdeps search
a47951
path, which is why the existing Makeconfig rule picks them up.
a47951
The files for RHEL 8.7.z were created by applying the gen-tunables.awk
a47951
part of this patch to RHEL 8.7.0 (glibc-2.28-211.el8_7, to be precise).
a47951
The sysdeps/unix/sysv/linux/**/dl-tunables.list files were created
a47951
based on the generated error message during the RHEL 8.7.z build.
a47951
Afterwards, the glibc.rtld.dynamic_sort tunable was added at the
a47951
end of the files, for the RHEL 8.8.0 build.
a47951
a47951
Going forward, new tunables will have to be added manually to the end
a47951
of those files.  Existing tunables should not be deleted.  For
a47951
deletion, the script would have to be extended to be able to create
a47951
gaps in the tunable_list array.
a47951
a47951
diff --git a/scripts/gen-tunables.awk b/scripts/gen-tunables.awk
a47951
index 622199061a140ccd..8ebfb560976ead41 100644
a47951
--- a/scripts/gen-tunables.awk
a47951
+++ b/scripts/gen-tunables.awk
a47951
@@ -12,6 +12,7 @@ BEGIN {
a47951
   tunable=""
a47951
   ns=""
a47951
   top_ns=""
a47951
+  tunable_order_count = 0
a47951
 }
a47951
 
a47951
 # Skip over blank lines and comments.
a47951
@@ -78,6 +79,37 @@ $1 == "}" {
a47951
   next
a47951
 }
a47951
 
a47951
+$1 == "@order" {
a47951
+    if (top_ns != "") {
a47951
+	printf("%s:%d: error: invalid @order directive inside namespace %s\n",
a47951
+               FILENAME, FNR, top_ns) > "/dev/stderr"
a47951
+	exit 1
a47951
+    }
a47951
+    if (NF != 2) {
a47951
+	printf("%s:%d: error: invalid argument count in @order directive\n",
a47951
+               FILENAME, FNR) > "/dev/stderr"
a47951
+        exit 1
a47951
+    }
a47951
+    order_arg = $2
a47951
+    if (split(order_arg, indices, /\./) != 3) {
a47951
+	printf("%s:%d: error: invalid tunable syntax in @order directive\n",
a47951
+               FILENAME, FNR) > "/dev/stderr"
a47951
+        exit 1
a47951
+    }
a47951
+    t = indices[1]
a47951
+    n = indices[2]
a47951
+    m = indices[3]
a47951
+    if ((t, n, m) in tunable_order) {
a47951
+	printf("%s:%d: error: duplicate\"@order %s\"\n" \
a47951
+               FILENAME, FNR, order_arg) > "/dev/stderr"
a47951
+        exit 1
a47951
+    }
a47951
+    ++tunable_order_count
a47951
+    tunable_order[t,n,m] = tunable_order_count
a47951
+    tunable_order_list[tunable_order_count] = t SUBSEP n SUBSEP m
a47951
+    next
a47951
+}
a47951
+
a47951
 # Everything else, which could either be a tunable without any attributes or a
a47951
 # tunable attribute.
a47951
 {
a47951
@@ -137,6 +169,31 @@ END {
a47951
     exit 1
a47951
   }
a47951
 
a47951
+  missing_order = 0
a47951
+  for (tnm in types) {
a47951
+      if (!(tnm in tunable_order)) {
a47951
+	  if (!missing_order) {
a47951
+	      print "error: Missing @order directives:" > "/dev/stderr"
a47951
+	      missing_order = 1
a47951
+	  }
a47951
+	  split(tnm, indices, SUBSEP)
a47951
+	  printf("@order %s.%s.%s\n", indices[1], indices[2], indices[3]) \
a47951
+	      > "/dev/stderr"
a47951
+      }
a47951
+  }
a47951
+  for (i = 1; i <= tunable_order_count; ++i) {
a47951
+    tnm = tunable_order_list[i]
a47951
+    if (!(tnm in types)) {
a47951
+	split(tnm, indices, SUBSEP)
a47951
+	printf("error: tunable in \"@order %s.%s.%s\" not known\n", \
a47951
+	       indices[1], indices[2], indices[3]) > "/dev/stderr"
a47951
+	missing_order = 1
a47951
+    }
a47951
+  }
a47951
+  if (missing_order) {
a47951
+      exit 1
a47951
+  }
a47951
+
a47951
   print "/* AUTOGENERATED by gen-tunables.awk.  */"
a47951
   print "#ifndef _TUNABLES_H_"
a47951
   print "# error \"Do not include this file directly.\""
a47951
@@ -147,7 +204,8 @@ END {
a47951
   # Now, the enum names
a47951
   print "\ntypedef enum"
a47951
   print "{"
a47951
-  for (tnm in types) {
a47951
+  for (i = 1; i <= tunable_order_count; ++i) {
a47951
+    tnm = tunable_order_list[i]
a47951
     split (tnm, indices, SUBSEP);
a47951
     t = indices[1];
a47951
     n = indices[2];
a47951
@@ -159,7 +217,8 @@ END {
a47951
   # Finally, the tunable list.
a47951
   print "\n#ifdef TUNABLES_INTERNAL"
a47951
   print "static tunable_t tunable_list[] attribute_relro = {"
a47951
-  for (tnm in types) {
a47951
+  for (i = 1; i <= tunable_order_count; ++i) {
a47951
+    tnm = tunable_order_list[i]
a47951
     split (tnm, indices, SUBSEP);
a47951
     t = indices[1];
a47951
     n = indices[2];
a47951
diff --git a/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list b/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list
a47951
new file mode 100644
a47951
index 0000000000000000..5c3c5292025607a1
a47951
--- /dev/null
a47951
+++ b/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list
a47951
@@ -0,0 +1,26 @@
a47951
+# Order of tunables in RHEL 8.7.0.
a47951
+@order glibc.rtld.nns
a47951
+@order glibc.elision.skip_lock_after_retries
a47951
+@order glibc.malloc.trim_threshold
a47951
+@order glibc.malloc.perturb
a47951
+@order glibc.cpu.name
a47951
+@order glibc.elision.tries
a47951
+@order glibc.elision.enable
a47951
+@order glibc.malloc.mxfast
a47951
+@order glibc.elision.skip_lock_busy
a47951
+@order glibc.malloc.top_pad
a47951
+@order glibc.cpu.hwcap_mask
a47951
+@order glibc.malloc.mmap_max
a47951
+@order glibc.elision.skip_trylock_internal_abort
a47951
+@order glibc.malloc.tcache_unsorted_limit
a47951
+@order glibc.elision.skip_lock_internal_abort
a47951
+@order glibc.malloc.arena_max
a47951
+@order glibc.malloc.mmap_threshold
a47951
+@order glibc.malloc.tcache_count
a47951
+@order glibc.malloc.arena_test
a47951
+@order glibc.rtld.optional_static_tls
a47951
+@order glibc.malloc.tcache_max
a47951
+@order glibc.malloc.check
a47951
+
a47951
+# Tunables added in RHEL 8.8.0
a47951
+@order glibc.rtld.dynamic_sort
a47951
diff --git a/sysdeps/unix/sysv/linux/i386/dl-tunables.list b/sysdeps/unix/sysv/linux/i386/dl-tunables.list
a47951
new file mode 100644
a47951
index 0000000000000000..b9cad4af62d9f2e5
a47951
--- /dev/null
a47951
+++ b/sysdeps/unix/sysv/linux/i386/dl-tunables.list
a47951
@@ -0,0 +1,33 @@
a47951
+# Order of tunables in RHEL 8.7.0.
a47951
+@order glibc.rtld.nns
a47951
+@order glibc.elision.skip_lock_after_retries
a47951
+@order glibc.malloc.trim_threshold
a47951
+@order glibc.malloc.perturb
a47951
+@order glibc.cpu.x86_shared_cache_size
a47951
+@order glibc.elision.tries
a47951
+@order glibc.elision.enable
a47951
+@order glibc.cpu.x86_rep_movsb_threshold
a47951
+@order glibc.malloc.mxfast
a47951
+@order glibc.elision.skip_lock_busy
a47951
+@order glibc.malloc.top_pad
a47951
+@order glibc.cpu.x86_rep_stosb_threshold
a47951
+@order glibc.cpu.x86_non_temporal_threshold
a47951
+@order glibc.cpu.x86_shstk
a47951
+@order glibc.cpu.hwcap_mask
a47951
+@order glibc.malloc.mmap_max
a47951
+@order glibc.elision.skip_trylock_internal_abort
a47951
+@order glibc.malloc.tcache_unsorted_limit
a47951
+@order glibc.cpu.x86_ibt
a47951
+@order glibc.cpu.hwcaps
a47951
+@order glibc.elision.skip_lock_internal_abort
a47951
+@order glibc.malloc.arena_max
a47951
+@order glibc.malloc.mmap_threshold
a47951
+@order glibc.cpu.x86_data_cache_size
a47951
+@order glibc.malloc.tcache_count
a47951
+@order glibc.malloc.arena_test
a47951
+@order glibc.rtld.optional_static_tls
a47951
+@order glibc.malloc.tcache_max
a47951
+@order glibc.malloc.check
a47951
+
a47951
+# Tunables added in RHEL 8.8.0
a47951
+@order glibc.rtld.dynamic_sort
a47951
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list
a47951
new file mode 100644
a47951
index 0000000000000000..ee1e6fca95e1f2da
a47951
--- /dev/null
a47951
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list
a47951
@@ -0,0 +1,26 @@
a47951
+# Order of tunables in RHEL 8.7.0.
a47951
+@order glibc.rtld.nns
a47951
+@order glibc.elision.skip_lock_after_retries
a47951
+@order glibc.malloc.trim_threshold
a47951
+@order glibc.malloc.perturb
a47951
+@order glibc.elision.tries
a47951
+@order glibc.elision.enable
a47951
+@order glibc.malloc.mxfast
a47951
+@order glibc.elision.skip_lock_busy
a47951
+@order glibc.malloc.top_pad
a47951
+@order glibc.cpu.hwcap_mask
a47951
+@order glibc.malloc.mmap_max
a47951
+@order glibc.elision.skip_trylock_internal_abort
a47951
+@order glibc.malloc.tcache_unsorted_limit
a47951
+@order glibc.elision.skip_lock_internal_abort
a47951
+@order glibc.malloc.arena_max
a47951
+@order glibc.malloc.mmap_threshold
a47951
+@order glibc.cpu.cached_memopt
a47951
+@order glibc.malloc.tcache_count
a47951
+@order glibc.malloc.arena_test
a47951
+@order glibc.rtld.optional_static_tls
a47951
+@order glibc.malloc.tcache_max
a47951
+@order glibc.malloc.check
a47951
+
a47951
+# Tunables added in RHEL 8.8.0
a47951
+@order glibc.rtld.dynamic_sort
a47951
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list b/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list
a47951
new file mode 100644
a47951
index 0000000000000000..099e28d8f8e67944
a47951
--- /dev/null
a47951
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list
a47951
@@ -0,0 +1,25 @@
a47951
+# Order of tunables in RHEL 8.7.0.
a47951
+@order glibc.rtld.nns
a47951
+@order glibc.elision.skip_lock_after_retries
a47951
+@order glibc.malloc.trim_threshold
a47951
+@order glibc.malloc.perturb
a47951
+@order glibc.elision.tries
a47951
+@order glibc.elision.enable
a47951
+@order glibc.malloc.mxfast
a47951
+@order glibc.elision.skip_lock_busy
a47951
+@order glibc.malloc.top_pad
a47951
+@order glibc.cpu.hwcap_mask
a47951
+@order glibc.malloc.mmap_max
a47951
+@order glibc.elision.skip_trylock_internal_abort
a47951
+@order glibc.malloc.tcache_unsorted_limit
a47951
+@order glibc.elision.skip_lock_internal_abort
a47951
+@order glibc.malloc.arena_max
a47951
+@order glibc.malloc.mmap_threshold
a47951
+@order glibc.malloc.tcache_count
a47951
+@order glibc.malloc.arena_test
a47951
+@order glibc.rtld.optional_static_tls
a47951
+@order glibc.malloc.tcache_max
a47951
+@order glibc.malloc.check
a47951
+
a47951
+# Tunables added in RHEL 8.8.0
a47951
+@order glibc.rtld.dynamic_sort
a47951
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list b/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list
a47951
new file mode 100644
a47951
index 0000000000000000..b9cad4af62d9f2e5
a47951
--- /dev/null
a47951
+++ b/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list
a47951
@@ -0,0 +1,33 @@
a47951
+# Order of tunables in RHEL 8.7.0.
a47951
+@order glibc.rtld.nns
a47951
+@order glibc.elision.skip_lock_after_retries
a47951
+@order glibc.malloc.trim_threshold
a47951
+@order glibc.malloc.perturb
a47951
+@order glibc.cpu.x86_shared_cache_size
a47951
+@order glibc.elision.tries
a47951
+@order glibc.elision.enable
a47951
+@order glibc.cpu.x86_rep_movsb_threshold
a47951
+@order glibc.malloc.mxfast
a47951
+@order glibc.elision.skip_lock_busy
a47951
+@order glibc.malloc.top_pad
a47951
+@order glibc.cpu.x86_rep_stosb_threshold
a47951
+@order glibc.cpu.x86_non_temporal_threshold
a47951
+@order glibc.cpu.x86_shstk
a47951
+@order glibc.cpu.hwcap_mask
a47951
+@order glibc.malloc.mmap_max
a47951
+@order glibc.elision.skip_trylock_internal_abort
a47951
+@order glibc.malloc.tcache_unsorted_limit
a47951
+@order glibc.cpu.x86_ibt
a47951
+@order glibc.cpu.hwcaps
a47951
+@order glibc.elision.skip_lock_internal_abort
a47951
+@order glibc.malloc.arena_max
a47951
+@order glibc.malloc.mmap_threshold
a47951
+@order glibc.cpu.x86_data_cache_size
a47951
+@order glibc.malloc.tcache_count
a47951
+@order glibc.malloc.arena_test
a47951
+@order glibc.rtld.optional_static_tls
a47951
+@order glibc.malloc.tcache_max
a47951
+@order glibc.malloc.check
a47951
+
a47951
+# Tunables added in RHEL 8.8.0
a47951
+@order glibc.rtld.dynamic_sort