This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Fix multi-arch build with elision
- From: Andi Kleen <andi at firstfloor dot org>
- To: libc-alpha at sourceware dot org
- Cc: markus at trippelsdorf dot de, hjl dot tools at gmail dot com, Andi Kleen <ak at linux dot jf dot intel dot com>
- Date: Tue, 2 Jul 2013 14:57:04 -0700
- Subject: [PATCH] Fix multi-arch build with elision
From: Andi Kleen <ak@linux.intel.com>
This is the simplest fix I could come up with for Markus'
no multiarch problem. Markus can you test please?
Is that an acceptable approach?
The elision code uses the CPUID macros/functions from init-arch.h
to detect whether the CPU supports TSX.
Unfortunately the necessary functions, like __get_cpu_features()
are not available in a non multiarch build.
While it would be possible to fix this, the needed changes
would be rather large. So instead go back to the directly
call CPUID method the early versions of the elision code used.
We simply use the cpuid inlines provided by gcc.
nptl/:
2013-07-02 Andi Kleen <ak@linux.intel.com>
* sysdeps/unix/sysv/linux/x86/Makefile (init-arch): Remove.
* sysdeps/unix/sysv/linux/x86/elision-conf.c (cpu_has_rtm,
CPUID_FEATURE_RTM): Add new definitions.
Remove init-arch.h include and add cpuid.h include.
(elision_init): Use cpu_has_rtm instead of HAS_RTM.
* sysdeps/unix/sysv/linux/x86/elision-conf.h: Remove cpuid.h
include.
---
nptl/sysdeps/unix/sysv/linux/x86/Makefile | 1 -
nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c | 23 +++++++++++++++++++++--
nptl/sysdeps/unix/sysv/linux/x86/elision-conf.h | 1 -
3 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/nptl/sysdeps/unix/sysv/linux/x86/Makefile b/nptl/sysdeps/unix/sysv/linux/x86/Makefile
index 61b7552..01a4004 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86/Makefile
+++ b/nptl/sysdeps/unix/sysv/linux/x86/Makefile
@@ -1,3 +1,2 @@
-libpthread-sysdep_routines += init-arch
libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
elision-trylock
diff --git a/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c b/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c
index 118cfa7..d2857cf 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c
+++ b/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c
@@ -18,9 +18,9 @@
#include "config.h"
#include <pthreadP.h>
-#include <init-arch.h>
#include <elision-conf.h>
#include <unistd.h>
+#include <cpuid.h>
/* Reasonable initial tuning values, may be revised in the future.
This is a conservative initial value. */
@@ -63,6 +63,25 @@ int __elision_available attribute_hidden;
int __pthread_force_elision attribute_hidden;
+#define CPUID_FEATURE_RTM (1U << 11)
+
+/* Determine if CPU has RTM. This does not use the standard macros from
+ init-arch.h, as these are not available in a non multiarch build. */
+
+static int
+cpu_has_rtm (void)
+{
+ if (__get_cpuid_max (0, NULL) >= 7)
+ {
+ unsigned a, b, c, d;
+
+ __cpuid_count (7, 0, a, b, c, d);
+ if (b & CPUID_FEATURE_RTM)
+ return 1;
+ }
+ return 0;
+}
+
/* Initialize elison. */
static void
@@ -70,7 +89,7 @@ elision_init (int argc __attribute__ ((unused)),
char **argv __attribute__ ((unused)),
char **environ)
{
- __elision_available = HAS_RTM;
+ __elision_available = cpu_has_rtm ();
#ifdef ENABLE_LOCK_ELISION
__pthread_force_elision = __libc_enable_secure ? 0 : __elision_available;
__rwlock_rtm_enabled = __libc_enable_secure ? 0 : __elision_available;
diff --git a/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.h b/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.h
index 55b81db..54b4f21 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.h
@@ -19,7 +19,6 @@
#define _ELISION_CONF_H 1
#include <pthread.h>
-#include <cpuid.h>
#include <time.h>
/* Should make sure there is no false sharing on this. */
--
1.8.1.4