about summary refs log tree commit diff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2016-05-10 05:42:49 -0700
committerH.J. Lu <hjl.tools@gmail.com>2016-05-14 09:19:01 -0700
commit4292da19f08b9d5e804909232489622bee6a60e3 (patch)
treecb1ce5dd222b533113b65d75a039ef8e7d60d358
parent1fa001e37c3c62748b5ab00c30f9f3f0c7209286 (diff)
downloadglibc-hjl/ld.so/master.tar.gz
glibc-hjl/ld.so/master.tar.xz
glibc-hjl/ld.so/master.zip
X86: Add cache info to _dl_x86_cpu_features hjl/ld.so/master
This patch adds cache info to _dl_x86_cpu_features to allow a processor
to override cache info derived from CPUID.

Tested on x86 and x86-64.

	* sysdeps/x86/cacheinfo.c: Skip if not in libc.
	(init_cacheinfo): Use raw_data_size, raw_shared_size and
	shared_non_temporal_threshold from _dl_x86_cpu_features if
	not zero.
	* sysdeps/x86/cpu-features.h (cache_info): New.
	(cpu_features): Add cache.
-rw-r--r--sysdeps/x86/cacheinfo.c17
-rw-r--r--sysdeps/x86/cpu-features.h13
2 files changed, 29 insertions, 1 deletions
diff --git a/sysdeps/x86/cacheinfo.c b/sysdeps/x86/cacheinfo.c
index 8408624ea4..e00e19f91e 100644
--- a/sysdeps/x86/cacheinfo.c
+++ b/sysdeps/x86/cacheinfo.c
@@ -16,6 +16,8 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#if IS_IN (libc)
+
 #include <assert.h>
 #include <stdbool.h>
 #include <stdlib.h>
@@ -656,6 +658,11 @@ init_cacheinfo (void)
 #endif
     }
 
+  const struct cache_info *cache = &GLRO(dl_x86_cpu_features).cache;
+
+  if (cache->raw_data_size != 0)
+    data = cache->raw_data_size;
+
   if (data > 0)
     {
       __x86_raw_data_cache_size_half = data / 2;
@@ -666,6 +673,9 @@ init_cacheinfo (void)
       __x86_data_cache_size = data;
     }
 
+  if (cache->raw_shared_size != 0)
+    shared = cache->raw_shared_size;
+
   if (shared > 0)
     {
       __x86_raw_shared_cache_size_half = shared / 2;
@@ -679,5 +689,10 @@ init_cacheinfo (void)
   /* The large memcpy micro benchmark in glibc shows that 6 times of
      shared cache size is the approximate value above which non-temporal
      store becomes faster.  */
-  __x86_shared_non_temporal_threshold = __x86_shared_cache_size * 6;
+  __x86_shared_non_temporal_threshold
+    = (cache->shared_non_temporal_threshold != 0
+       ? cache->shared_non_temporal_threshold
+       : __x86_shared_cache_size * 6);
 }
+
+#endif
diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/cpu-features.h
index 9529d61ff5..335d96a3e1 100644
--- a/sysdeps/x86/cpu-features.h
+++ b/sysdeps/x86/cpu-features.h
@@ -164,6 +164,18 @@
 
 #else	/* __ASSEMBLER__ */
 
+struct cache_info
+{
+  /* Data cache size for use in memory and string routines, typically
+     L1 size.  */
+  long int raw_data_size;
+  /* Shared cache size for use in memory and string routines, typically
+     L2 or L3 size.  */
+  long int raw_shared_size;
+  /* Threshold to use non temporal store.  */
+  long int shared_non_temporal_threshold;
+};
+
 enum
   {
     COMMON_CPUID_INDEX_1 = 0,
@@ -193,6 +205,7 @@ struct cpu_features
   unsigned int family;
   unsigned int model;
   unsigned int feature[FEATURE_INDEX_MAX];
+  struct cache_info cache;
 };
 
 /* Used from outside of glibc to get access to the CPU features