This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]