about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@sourceware.org>2017-06-30 22:58:39 +0530
committerSiddhesh Poyarekar <siddhesh@sourceware.org>2017-06-30 22:58:39 +0530
commit28cfa3a48e59f9c6b9bc25a003a4ede435841382 (patch)
treeec2c7a24f4fd2a0d8b4e2ead2dabc36b6b3c3cf9 /sysdeps
parentab85da15301c552e3ea4577a6432aa028bee9295 (diff)
downloadglibc-28cfa3a48e59f9c6b9bc25a003a4ede435841382.tar.gz
glibc-28cfa3a48e59f9c6b9bc25a003a4ede435841382.tar.xz
glibc-28cfa3a48e59f9c6b9bc25a003a4ede435841382.zip
tunables, aarch64: New tunable to override cpu
Add a new tunable (glibc.tune.cpu) to override CPU identification on
aarch64.  This is useful in two cases: one where it is desirable to
pretend to be another CPU for purposes of testing or because routines
written for that CPU are beneficial for specific workloads and second
where the underlying kernel does not support emulation of MRS to get
the MIDR of the CPU.

	* elf/dl-tunables.h (tunable_is_name): Move from...
	* elf/dl-tunables.c (is_name): ... here.
	(parse_tunables, __tunables_init): Adjust.
	* manual/tunables.texi: Document glibc.tune.cpu.
	* sysdeps/aarch64/dl-tunables.list: New file.
	* sysdeps/unix/sysv/linux/aarch64/cpu-features.c (struct
	cpu_list): New type.
	(cpu_list): New list of CPU names and their MIDR.
	(get_midr_from_mcpu): New function.
	(init_cpu_features): Override MIDR if necessary.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/aarch64/dl-tunables.list25
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/cpu-features.c47
2 files changed, 66 insertions, 6 deletions
diff --git a/sysdeps/aarch64/dl-tunables.list b/sysdeps/aarch64/dl-tunables.list
new file mode 100644
index 0000000000..b1da2bfdfe
--- /dev/null
+++ b/sysdeps/aarch64/dl-tunables.list
@@ -0,0 +1,25 @@
+# aarch64 specific tunables.
+# Copyright (C) 2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+glibc {
+  tune {
+    cpu {
+      type: STRING
+    }
+  }
+}
diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
index ef6eecd17e..47c7d97185 100644
--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
@@ -20,18 +20,53 @@
 #include <sys/auxv.h>
 #include <elf/dl-hwcaps.h>
 
+#if HAVE_TUNABLES
+struct cpu_list
+{
+  const char *name;
+  uint64_t midr;
+};
+
+static struct cpu_list cpu_list[] = {
+      {"thunderxt88",	0x430F0A10},
+      {"generic", 	0x0}
+};
+
+static uint64_t
+get_midr_from_mcpu (const char *mcpu)
+{
+  for (int i = 0; i < sizeof (cpu_list) / sizeof (struct cpu_list); i++)
+    if (tunable_is_name (mcpu, cpu_list[i].name) == 0)
+      return cpu_list[i].midr;
+
+  return UINT64_MAX;
+}
+#endif
+
 static inline void
 init_cpu_features (struct cpu_features *cpu_features)
 {
   uint64_t hwcap_mask = GET_HWCAP_MASK();
   uint64_t hwcap = GLRO (dl_hwcap) & hwcap_mask;
 
-  if (hwcap & HWCAP_CPUID)
+  register uint64_t midr = UINT64_MAX;
+
+#if HAVE_TUNABLES
+  /* Get the tunable override.  */
+  const char *mcpu = TUNABLE_GET (glibc, tune, mcpu, const char *, NULL);
+  if (mcpu != NULL)
+    midr = get_midr_from_mcpu (mcpu);
+#endif
+
+  /* If there was no useful tunable override, query the MIDR if the kernel
+     allows it.  */
+  if (midr == UINT64_MAX)
     {
-      register uint64_t id = 0;
-      asm volatile ("mrs %0, midr_el1" : "=r"(id));
-      cpu_features->midr_el1 = id;
+      if (hwcap & HWCAP_CPUID)
+	asm volatile ("mrs %0, midr_el1" : "=r"(midr));
+      else
+	midr = 0;
     }
-  else
-    cpu_features->midr_el1 = 0;
+
+  cpu_features->midr_el1 = midr;
 }